我正在开发自己的语言应用程序,该应用程序在很大程度上基于语言实现模式书中的符号语法。我一直在使用ANTLRworks开发语法,然后使用Eclipse在Java中实现完整的应用程序。作为我的语法的一部分,我有这两条规则:
varDeclaration
: 'var' ID 'is' dataType (':=' expr )? ';'
-> ^('var' ^(NAME ID) ^(VARTYPE dataType) ^(VALUE expr)?)
;
constantDeclaration
: 'const' ID 'is' dataType ':=' expr ';'
-> ^('const' ^(NAME ID) ^(VARTYPE dataType) ^(VALUE expr))
;
在运行解析器并打印生成的AST之后,这两者的输出似乎都是正确的。
然后运行符号定义树匹配器(filter-true)来构建符号表。除了输入每个函数/块等。为了开始新的作用域,我还处理了自顶向下规则中变量和常量的定义(同样,基于语言实现模式书),如下所示:
topdown
: varDeclaration
| constDeclaration
| ...
;
varDeclaration
: ^('var' ^(NAME ID) .*) //^(VAR ^(NAME ID) .*) Rewrote this for clarity of example
{
System.out.println("In a variable declaration");
}
;
constDeclaration
: ^('const' ^(NAME ID) .*)
{
System.out.println("Const definition");
}
;
我的问题是只有constDeclaration匹配。即使我在输入中有varDeclaration(通过AST打印输出验证),我也从未看到"in a variable declaration"打印到我的控制台,而"Const definition"显示。
我已经尝试了很多事情来调试/解决这个问题:
- 使变量声明的可选初始化表达式不是可选的,因此它在语法上与const声明相同,除了关键字。
- 将关键字'var'更改为其他内容(在本例中为'splunge')。
- 将匹配参数更改为使用特定的通配符(例如:^ (VAR vn =。vt =。=))
- 尝试将varDeclaration放到自底向上规则中
正如你所看到的,我变得非常绝望,因为我不知道为什么一个规则和模式匹配而另一个不匹配。变量声明和常量声明之间唯一的另一个区别是,常量声明可以发生在代码块和顶层(对于全局const),而变量只能在代码块中声明。我不明白为什么代码块中的const可以匹配,而var不能匹配。
下面的代码是一个错误匹配的例子:
function foo(int a) returns (int) {
const PI is real := 3.14159; // Recognized
var r is real; // Not recognized
var s is int := 4; // Not recognized
const TESTCONST is int := 3; // Recognized
// Other code (if statements, for loops) recognized.
}
这几天我一直在想办法解决这个问题,但是我已经束手无策了。我错过了什么?附加信息(2013年3月20日新增)
为了进一步说明,输入声明如const y is real := 2.4; // Recognized
var temp is int := 0 ; // Not recognized
在AST中产生以下内容:
(const (NAME y) (VARTYPE (SCALAR (NAME (TYPEID real)))) (VALUE (EXPR 2.4)))
(var (NAME temp) (VARTYPE (SCALAR (NAME (TYPEID int)))) (VALUE (EXPR 0)))
const AST与上述树语法匹配,var AST则不匹配。
在解析器中,您匹配文字'var'
,但在树解析器中,您正在寻找^(VAR ...
。您的词法分析器是否完全包含以下规则?
VAR : 'var';
对于树解析器中的constDeclaration
(您说有效),您使用的是与解析器中使用的相同的文字语法:^('const' ...