乐者为王

Do one thing, and do it well.

ANTLR 4权威参考读书笔记(11)

为制作语言应用,我们必须为每个输入短语或子短语执行一些适当的代码,那样做最简单的方法是操作由语法分析器自动创建的语法分析树。

早些时候我们已经学习了词法分析器处理字符和把记号传递给语法分析器,然后语法分析器分析语法和创建语法分析树的相关知识。对应的ANTLR类分别是CharStream、Lexer、Token、Parser和ParseTree。连接词法分析器和语法分析器的管道被称为TokenStream。下图说明了这些类型的对象如何连接到内存中其它的对象。

basic-data-structure

这些ANTLR数据结构共享尽可能多的数据以便节省内存的需要。上图显示在语法分析树中的叶子(记号)节点含有在记号流中记号的点。记号记录开始和结束字符在CharStream中的索引,而不是复制子串。这里没有与空格字符有关的记号,因为我们假设我们的词法分析器扔掉了空格。

下图显示的是ParseTree的子类RuleNode和TerminalNode以及它们所对应的子树根节点和叶子节点。RuleNode包含有方法如getChild()和getParent()等,但RuleNode并不专属于特定语法所有。为了能更好地访问在特定节点中的元素,ANTLR为每个规则生成一个RuleNode的子类。下图显示了赋值语句例子的子树根节点的特定类,它们是StatContext、AssignContext和ExprContext:

parse-tree-node

它们记录了通过规则对短语识别的每件事情,所以被称为上下文对象。每个上下文对象都知道被识别短语的开始和结束记号以及提供对所有短语的元素的访问。例如,AssignContext提供方法ID()和expr()去访问标志符节点和表达式子树。

给出了具体类型的描述后,我们可以手工编写代码去执行树的深度优先遍历。当我们发现和完成节点时我们可以执行任何我们想要的动作。典型的动作是诸如计算结果,更新数据结构,或者生成输出。相比每次为每个应用编写同样的树遍历样板代码,使用ANTLR自动生成的树遍历机制更方便、更容易。

Comments