从ANTLR语法生成AST

3

针对问题和由@BartKiers建议的语法(谢谢!),我添加了options块以指定输出内容

options{
language=Java;
output=AST;
ASTLabelType=CommonTree;
}

然而,我无法弄清如何访问输出,即AST。我需要遍历树并处理输入中指定的每个操作。


使用你的示例这里,我正在尝试实现返回值的规则。然而,我遇到了以下错误:

relational    returns [String val]                   
        :  STRINGVALUE ((operator)^ term)?
            {val = $STRINGVALUE.text + $operator.text + $term.text; }
                                    ;

term returns [String rhsOperand]                    
        :  QUOTEDSTRINGVALUE  {rhsOperand = $QUOTEDSTRINGVALUE.text;}
                                    |  NUMBERVALUE               {rhsOperand = $NUMBERVALUE.text; }
                                    | '(' condition ')'
                                     ;

编译错误。
Checking Grammar RuleGrammarParser.g...
\output\RuleGrammarParser.java:495: cannot find symbol
symbol  : variable val
location: class RuleGrammarParser
            val = (STRINGVALUE7!=null?STRINGVALUE7.getText():null) + (operator8!=null?input.toString(operator8.start,operator8.stop):null) + (term9!=null?input.toString(term9.start,term9.stop):null); 
            ^
\output\RuleGrammarParser.java:612: cannot find symbol
symbol  : variable rhsOperand
location: class RuleGrammarParser
                    rhsOperand = (QUOTEDSTRINGVALUE10!=null?QUOTEDSTRINGVALUE10.getText():null);
                    ^
\output\RuleGrammarParser.java:632: cannot find symbol
symbol  : variable rhsOperand
location: class RuleGrammarParser
                    rhsOperand = (NUMBERVALUE11!=null?NUMBERVALUE11.getText():null); 
                    ^
3 errors

请问您能帮我理解为什么这个代码编译失败吗?


添加了Pastebin:http://pastebin.com/u1Bv3L0A

1个回答

4
通过在选项部分添加 output=AST,您不会创建 AST,而是平面的、一维的标记列表。要将某些标记标记为根 (或子级),您需要进行一些工作。
查看这个答案,它解释了如何创建一个适当的 AST,并获得解析器生成的树的访问权(在我提到的答案的main方法中的CommonTree tree)。
请注意,您可以安全地删除 language=Java;:默认目标语言为 Java(但保留它也没有问题)。

太棒了!为@BartKiers欢呼三声!!(而且还押韵了:)) - name_masked
你能帮我解决上面的问题吗?我已经更新了问题。 - name_masked
巴特,找到解决方法了。也许你需要更新你的示例,将规则中定义的所有变量都包含 $ - name_masked
@darkie15,是的,在ANTLR 3的早期版本中,你可以安全地省略$符号,但在ANTLR 3.4(也许3.3也是)中,它现在是必需的。请注意,在我提供的教程中使用的是ANTLR 3.2,它与教程中发布的所有代码都兼容,所以我不打算做太多改动:我可能会意外地破坏一些东西。当然很高兴听到你解决了问题。 - Bart Kiers
我又卡住了:(。我在我的帖子中附上了pastebin链接。基本上,一旦解析器验证了输入,我正在尝试将条件作为返回值获取。因此,对于像condition1这样的输入,其中condition1可能是NAME = "BATMAN",我会得到返回值,但是对于多个条件,例如NAME = "BATMAN" AND SSN = 0000,返回值仅为第一个条件而不是第二个条件。你能帮我吗? - name_masked
@darkie15,不太确定你在问什么。最好你创建一个新的问题,在那里发布代码和合理的解释,不要使用外部链接(如pastebin)。 - Bart Kiers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接