如何将令牌流转换为解析树

时间:2009-01-19 04:47:09

标签: parsing token lexical-analysis parse-tree

我有一个lexer构建,从输入中流出标记,但我不知道如何构建过程中的下一步 - 解析树。有没有人有任何关于如何实现这一目标的好资源或例子?

4 个答案:

答案 0 :(得分:4)

我真的会推荐http://www.antlr.org/,当然还有经典的Dragon Compilers一书。

对于像JavaScript这样的简单语言,手动滚动递归下降解析器并不困难,但使用yacc或antlr等工具几乎总是更容易。

我想回到你问题的基础,你真的想研究BNF-esque语法语法并为你的目标选择一种语法。如果你有这个,那么解析树应该会掉线,作为该语法的“实例”表现形式。

另外,不要试图将解析树的创建转换为最终解决方案(如生成代码或什么不是)。它似乎可行且更有效;但是总会有一段时间,你真的希望你有那个解析树“就像”那样。

答案 1 :(得分:2)

您应该为您的平台调查解析器生成器工具。解析器生成器允许您为您的语言指定无上下文语法。该语言由许多规则组成,这些规则将一系列符号“减少”为新符号。您通常还可以为不同的规则指定优先级和关联性,以消除语言中的歧义。例如,一个非常简单的计算器语言可能如下所示:

%left PLUS, MINUS           # low precedence, evaluated left-to-right
%left TIMES, DIV            # high precedence, left-to-right

expr ::= INT
| expr PLUS expr
| expr MINUS expr
| expr TIMES expr
| expr DIV expr
| LEFT_PAREN expr RIGHT_PAREN

通常,您可以将一些代码与每个规则相关联,以根据该规则中的其他符号构造新值(在本例中为表达式)。解析器生成器将接受语法并使用您的语言生成将令牌流转换为解析树的代码。

大多数解析器生成器都是特定于语言的。 ANTLR是众所周知的,支持C,C ++,Objective C,Java和Python。我听说它很难使用。我已经将bison用于C / C ++,CUP用于Java,ocamlyacc用于OCaml,它们都非常好用。如果您已经在使用词法分析器生成器,那么您应该寻找与其特别兼容的解析器生成器。

答案 2 :(得分:0)

我认为一种常见的方法是使用Finite State Machine。例如,如果您读取操作数,则会进入下一个期望运算符的状态,并且通常使用运算符作为操作数的根节点,依此类推。

答案 3 :(得分:0)

如上所述,Marcos Marin如果您想自己动手,那么在BNF中使用您的语言规则来解析您的令牌列表的状态机将会起作用。只有,正如Paul Hollingsworth在上面的评论中所说,更简单的方法是使用具有简单FiFo内存堆栈的Pushdown-Automaton。 每个令牌类都有一个语法中的下一个预期令牌,它也在你的状态机中表示。堆栈用于记住"前面的标记类是什么,以减少所需的状态(可以在没有堆栈的情况下完成,但是你需要为语法树中的每个类和子类拆分一个新的状态)。 接受状态(在自然语言和大多数编程语言中)也是起始状态,在特定情况下可能是其他状态。

如果你想使用一个工具(更快,更广泛),

Antlr将是我的建议。祝你好运!