验证是否使用了每个全局变量
verify if each global variable is used
我想在我的 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 () {}
{
......
}
我的问题是如何验证语句中是否使用了全局变量?。提前谢谢你。
解决此类问题的常用方法是创建一个符号 table 来记录有关程序中每个命名实体的信息。命名实体包括变量、函数、类型等。您可以(并且应该)在任何关于编译器的好书中阅读有关符号 table 的内容。
符号table为程序中的每个点提供了从名称到实体信息的映射。
符号table通常在早期通过时构建。这可能是解析过程,也可能是在解析之后遍历 AST 的过程。构建后,符号 table 可用于查找有关名称所指实体的信息。也就是说,当语言处理器看到一个名字时,它会在符号 table 中查找有关该名字的信息。
如果语言是 "definition before use" 语言——C 是一个例子——,那么符号 table 可以在内置的同一遍中用于查找;因此,可以一次性解析、构建符号 table,并使用符号 table 进行查找。其他语言(例如 Java)允许在实体定义之前(在程序文本中)使用实体。在这种情况下,符号 table 仅在构建后用于在通行证中查找。
在您的情况下——即使您没有编写编译器——您也需要一个符号 table。每当定义一个全局变量时,在符号 table 中添加一个条目。每当使用一个变量时,查找符号 table 中的变量并记下它被使用的事实。您还需要在符号 table 中记录局部变量,如下例 (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.
}
我想在我的 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 () {}
{
......
}
我的问题是如何验证语句中是否使用了全局变量?。提前谢谢你。
解决此类问题的常用方法是创建一个符号 table 来记录有关程序中每个命名实体的信息。命名实体包括变量、函数、类型等。您可以(并且应该)在任何关于编译器的好书中阅读有关符号 table 的内容。
符号table为程序中的每个点提供了从名称到实体信息的映射。
符号table通常在早期通过时构建。这可能是解析过程,也可能是在解析之后遍历 AST 的过程。构建后,符号 table 可用于查找有关名称所指实体的信息。也就是说,当语言处理器看到一个名字时,它会在符号 table 中查找有关该名字的信息。
如果语言是 "definition before use" 语言——C 是一个例子——,那么符号 table 可以在内置的同一遍中用于查找;因此,可以一次性解析、构建符号 table,并使用符号 table 进行查找。其他语言(例如 Java)允许在实体定义之前(在程序文本中)使用实体。在这种情况下,符号 table 仅在构建后用于在通行证中查找。
在您的情况下——即使您没有编写编译器——您也需要一个符号 table。每当定义一个全局变量时,在符号 table 中添加一个条目。每当使用一个变量时,查找符号 table 中的变量并记下它被使用的事实。您还需要在符号 table 中记录局部变量,如下例 (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.
}