验证是否使用了每个全局变量

时间:2015-07-16 10:39:35

标签: compiler-construction javacc

我想在javaCC生成的解析器中实现规则编码:

是语句中使用的全局变量吗?

规则生产javacc是:

   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  () {}
        {
        ......
        }

我的问题我如何验证是否在语句中使用了全局变量?提前谢谢。

1 个答案:

答案 0 :(得分:1)

解决此类问题的常用方法是创建一个符号表,用于记录程序中每个命名实体的信息。命名实体包括变量,函数,类型等等。您可以(并且应该)在编译器的任何好书中阅读符号表。

符号表为程序中的每个点提供从名称到有关实体的信息的映射。

符号表通常在早期传递期间构建。这可以是解析过程,也可以是在解析之后遍历AST的过程。构建后,符号表可用于查找有关名称引用的实体的信息。即,当语言处理器看到一个名称时,它会在符号表中查找有关该名称的信息。

如果语言是“使用前的定义”语言--C是一个例子 - 那么符号表可以用于在内置的同一通道中查找;因此,可以解析,构建符号表,并使用符号表在一次传递中进行查找。其他语言(例如Java)允许在(在程序文本中)之前使用实体来定义它们。在这种情况下,符号表仅用于在构建后的通道中查找。

在你的情况下 - 即使你没有编写编译器 - 你也会想要一个符号表。无论何时定义全局变量,都要在符号表中添加一个条目。每当使用变量时,在符号表中查找变量并记下它被使用的事实。您还需要在符号表中记录局部变量,如以下示例(C)所示。

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.
}