我正在开发自己的语言应用程序,该应用程序很大程度上基于《语言实现模式》书中的 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)来构建符号表。除了输入每个功能/ block /等等。为了开始新的范围,我还处理自顶向下规则中的变量和常量的定义(同样,基于《语言实现模式》一书),如下所示:
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 定义”。
我尝试了很多方法来调试/解决这个问题:
- 使变量声明的可选初始化表达式变为非可选,因此除了关键字之外,它在语法上与 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 则不匹配。
最佳答案
在解析器中,您匹配文字 'var'
,但在树解析器中,您正在查找 ^(VAR ...
。您的词法分析器是否包含完全遵循规则吗?
VAR : 'var';
对于树解析器中的 constDeclaration
(你说它有效),你使用的文字语法与解析器中使用的相同:^('const' ...
关于antlr - 我的 ANTLR3 树语法从不匹配与匹配的模式非常相似的特定模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15499946/