我正在开发自己的语言应用程序,该应用程序很大程度上基于 Language Implementation Patterns 书中的 Cymbol 语法。我一直在使用 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 打印输出验证),我也从未在控制台上看到“在变量声明中”打印,而显示“常量定义”。
我已经尝试了很多东西来调试/解决这个问题:
- 使变量声明的可选初始化表达式不是可选的,使其在语法上与 const 声明除了关键字相同。
- 将关键字“var”更改为其他内容(在本例中为“splunge”)。
- 更改了匹配参数以使用特定的通配符(例如 ^(VAR vn=.vt=.vv=.))
- 尝试将 varDeclaration 放在自下而上的规则中。
如您所见,我变得非常绝望,因为我不知道为什么一个规则和模式匹配而另一个不匹配。变量和常量声明之间唯一的其他区别是常量声明可以发生在代码块内和顶层(对于全局常量),而变量只能在代码块内声明。我不明白这与为什么代码块中的 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 不匹配。