Search code examples
compiler-constructionjavacc

verify if each global variable is used


I want to implement the rule coding in my parser generated by javaCC :

is the global variable is used in the statement?

the Rule Production javacc is :

   TOKEN :
    {
      < ID : ([ "a"-"z"])* >
    }
            void myProgram() #programm: {}
            {

            initialisation()
            MyMethod ()
             {return jjtThis;}

            } 


     void MyMethod () #MyMethod  : {}
             {
             <begin> <id> "(" (Argument ())* ")" {}
             (Statement ()) *

              <end>
             }    


             void Argument() : {}
             {
             <String>  <id>
             <int>  <id>
             }

             void statement ()  : {}
             {
             DeclarationVariable()
             ......

             }

                void initialisation() : {}
            {

             DeclarationVariable()


            }

          void  DeclarationVariable() : {}
    {
    StringDeclarationVariable()

    }


    void StringDeclarationVariable() :{} 
    {
    <STRING> <id> ["=" StringStructure()]
    }


    void StringStructure() : {}
    {

    CallMyMethod ()
    VarariableString ()

    }
   void VarariableString () : {}
{<ID>
} 
    void  CallMyMethod  () : {}
        {
        <id> "(" (
             ExpressionTreeStructure ()
             (
               "," ExpressionTreeStructure ()
             ) *
           ) *
        ")"
        }

      void  ExpressionTreeStructure  () {}
        {
        ......
        }

my question how I can verified is the global variable is used in the statement?. Thank you in advance.


Solution

  • The usual approach to this sort of problem is to create a symbol table that records information about each named entity in your program. Named entities include things like variables, functions, types, etc. You can (and should) read about symbol tables in any good book on compilers.

    The symbol table provides, for each point in the program, a mapping from names to information about entities.

    The symbol table is usually build during an early pass. This could be the parsing pass or it could be a pass that walks the AST subsequent to parsing. Once built the symbol table can be used to lookup information about the entities that names refers to. I.e., when the language processor sees a name, it looks in the symbol table to find out information about that name.

    If the language is a "definition before use" language --C is an example--, then the symbol table may be used for lookup in the same pass as it is built in; thus it is possible to parse, build the symbol table, and use the symbol table for lookup all in one pass. Other languages (e.g. Java) allow entities to be used prior (in the program text) to where they are defined. In such a case, the symbol table is only used for lookup in passes after it has been built.

    In your case --even though you are not writing a compiler-- you will want to have a symbol table. Whenever a global variable is defined, add an entry to the symbol table. Whenever a variable is used, lookup the variable in the symbol table and make a note of the fact that it is used. You will also need to record local variables in your symbol table as the following example (C) illustrates.

    int x ;           // Add x as a global variable to the symbol table.
    int y ;           // Add y as a global variable to the symbol table.
    
    void f() {
        int x ;      // Add x as a local variable to the symbol table.
        x = 1 ;      // Look up x. Find the local entry. Note that it is used.
        y = 1 ;      // Look up y. Fund the global entry. Note that it is used.
    }