我有一个问题困扰了我一段时间,如果可能的话,我将不胜感激。
我在 ANTLR 树 语法中有一些规则:
block
: compoundstatement
| ^(VAR declarations) compoundstatement
;
declarations
: (^(t=type idlist))+
;
idlist
: IDENTIFIER+
;
type
: REAL
| i=INTEGER
;
我已经编写了一个 Java 类 VarTable,我将在源文件开头声明的所有变量插入其中。该表还将保存它们的变量类型(即实数或整数)。我还可以使用这个变量表来检查未声明的变量或重复声明等。
所以基本上我希望能够将变量类型从“声明”规则向下发送到“idlist”规则,然后遍历 idlist 规则中的每个标识符,将它们一一添加到我的变量表中。
我遇到的主要问题是,当我尝试访问“文本”属性时,如果“声明”规则中的 $t 变量(这是一个引用类型的变量),我会得到一个 NullPointerException。
然而,如果我尝试访问“类型”规则中 $i 变量的“文本”属性,则没有问题。
我已经查看了 Java 文件中生成 NullPointerException 的位置,但它对我来说仍然毫无意义。
因为规则是可以有多种类型的事实是否有问题
(^(typeidlist))+
??
当我深入到 idlist 规则时,我遇到了同样的问题,因为我不确定如何编写一个允许我循环遍历找到的所有 IDENTIFIER token 的操作。
感谢任何帮助或评论。
干杯
最佳答案
您不能像在树语法中尝试的那样从生产规则中引用属性,只能在解析器(或组合)语法中引用属性(它们是不同的对象!)。请注意,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
的属性,而 start
又是一个 CommonTree
实例。然后,您可以对该 CommonTree
实例调用 getText()
。
关于antlr - 带有 ANTLR 文本属性的 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5665219/