1

我的最终目标是将结构化文件解析为内存对象树,然后我可以对其进行操作。我使用的文件格式相当复杂,包含大约 200 个关键字/标签,这似乎是学习解析器/词法分析器框架的好理由。

不幸的是,有太多的概念(以及数百个教程和指南),以至于到目前为止的学习过程感觉就像试图从消防水管中喝水。所以我正在采取一些非常微不足道的婴儿步骤,从这个例子开始。

我修改了语法以创建以下测试 Nano.g4:

grammar Nano;

r  : root ;
root : START ROOT ID END ROOT;
START : 'StartBlock' ;
END : 'EndBlock' ;
ROOT : 'RootItem' ;
ID : [a-z]+ ;             // match lower-case identifiers
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines

接下来,我创建了一个简单的输入文件 nano.txt:

StartBlock RootItem
   foo
EndBlock RootItem

然后我使用以下命令加载代码:

del *.class
del *.java
java org.antlr.v4.Tool Nano.g4
javac nano*.java
java org.antlr.v4.runtime.misc.TestRig Nano r -gui < nano.txt

这给了我这个结果:

ANTLR 输出

上面的树是我对词法分析器和解析器的期望的第一个概念性挂断。就使输入文件合法而言,“StartBlock RootItem”和“EndBlock RootItem”标记是必需的,但从概念上讲,在我证明文件格式正确后,我不需要它们。从那时起,我唯一关心的是有一个包含“foo”的 RootItem,如下所示:

在此处输入图像描述

同样,我对解析器/词法分析器概念非常陌生。 我应该(或者,甚至可以)编写语法以使输出树与上图匹配吗?或者我应该在遍历 AST 并仅提取相关数据字段的后续步骤中处理这个问题?

4

1 回答 1

4

ANTLR 4 生成解析树,而不是 AST。这是与 ANTLR 3 行为的一个重要区别,被选择用于帮助长期维护语法。特别是,可能会出现用户确实想要访问令牌的情况,例如,作为 IDE 中语义突出显示组件的一部分。在这种情况下,我们没有强制用户编写特定于应用程序的修改语法,而是选择始终将所有标记包含在解析树中。

于 2013-09-12T22:51:21.867 回答