我有一个问题,我已经坚持了一段时间,如果可能的话,我会感激一些帮助。
我在ANTLR 树语法中有一些规则:
block
: compoundstatement
| ^(VAR declarations) compoundstatement
;
declarations
: (^(t=type idlist))+
;
idlist
: IDENTIFIER+
;
type
: REAL
| i=INTEGER
;
我编写了一个Java类VarTable,我将把所有变量插入到源文件开头的声明中。该表还将保存其变量类型(即实数或整数)。我还可以使用此变量表来检查未声明的变量或重复的声明等。
所以基本上我希望能够将变量类型从'declarations'规则发送到'idlist'规则,然后循环遍历idlist规则中的每个标识符,将它们逐个添加到我的变量表中。 / p>
我得到的主要问题是,当我尝试访问'text'属性时,如果'声明'规则中的$ t变量(这是引用该类型的一个),我会得到一个NullPointerException。 / p>
然而,如果我尝试在'type'规则中访问$ i变量的'text'属性,那就没问题了。
我查看了Java文件中生成NullPointerException的位置,但对我来说仍然没有意义。
因为规则是
,所以可能存在多种类型的问题(^(typeidlist))+
...
当我达到idlist规则时,我遇到了同样的问题,因为我不确定如何编写一个允许我遍历所有IDENTIFIER Tokens的动作。
感谢任何帮助或评论。
干杯
答案 0 :(得分:4)
您不能像在树语法中尝试的那样引用生产规则中的属性,只能在解析器(或组合)语法中引用它们(它们是不同的对象!)。请注意,INTEGER
不是生产规则,只是一个“简单”令牌(终端)。这就是可以调用其.text
属性的原因。
因此,如果您希望在树语法中保留type
规则的文本并将其打印在declarations
规则中,您可以执行以下操作:
tree grammar T;
...
declarations
: (^(t=type idlist {System.out.println($t.returnValue);}))+
;
...
type returns [String returnValue]
: i=INTEGER {returnValue = "[" + $i.text + "]";}
;
...
但是如果你真的想在没有指定返回对象的情况下这样做,你可以这样做:
declarations
: (^(t=type idlist {System.out.println($t.start.getText());}))+
;
请注意,type
会返回TreeRuleReturnScope
的实例,该实例具有名为start
的属性,该属性又是CommonTree
个实例。然后,您可以在getText()
个实例上调用CommonTree
。