关于LL1非递归解析器中的AST构造

时间:2014-03-01 20:32:21

标签: java parsing abstract-syntax-tree

我已经使用显式堆栈以非递归方式实现了LL1解析器。

以下算法来自Dragon Book:

set zp to point to the first symbol of w;
set X to the top stack symbol;
while ( X != $ ) { /* stack is not empty */
    if ( X is a ) 
       pop the stack and advance zp;
    else if ( X is a terminal )
       error();
    else if ( M[X, a] is an error entry )
       error();
    else if ( M[X,a] = X -+ Y1Y2 Yk ) {
       output the production X -+ YlY2 - . Yk;
       pop the stack;
       push Yk, Yk-1,. . . , Yl onto the stack, with Yl on top;

    set X to the top stack symbol;
}

这本书说:

  

解析器由一个程序控制,该程序考虑X,即符号   堆栈顶部和a,当前输入符号。如果X是   非终结者,解析器通过参考条目选择X生成   解析表IM的M [X,a]。 (可以执行附加代码   这里,例如,用于在解析树中构造节点的代码。)   否则,它检查终端X和当前之间的匹配   输入符号a。

但是我需要更多关于如何在这种方法下构造表达式树节点的信息。我有一个UnaryOperator,BinaryOperator等的节点层次结构,但不知道在哪里实例化。

然而我还没有找到任何这方面的简单例子(例如算术语言)。

1 个答案:

答案 0 :(得分:0)

我一直在搜索相同的信息 - 如何使用LL(1)表驱动的非递归解析创建一个解析树 - 并且发现很少。

刚才我发现了这些讲义https://parasol.tamu.edu/~rwerger/Courses/434/lec7.pdf,其中提出对于每个终端或非终端,相应的解析树节点也被推入堆栈。不过,它确实看起来很浪费。以下是伪代码中提出的算法:

TOS ← 0
Stack[tos++] ← eof
Stack[tos++] ← *root node*
Stack[tos++] ← *Start Symbol*
token ← next_token()
X ← Stack[tos]
repeat
  if X is a terminal or eof then
    if X = token then
      pop X
      token ← next_token()
      *pop and fill in node*
    else error()
  else /* X is a non-terminal */
    if M[X,token] = X → Y1Y2...Yk then
      pop X
      *pop node for X
      build node for each child and
      make it a child of node for X*
      push nk,Yk,nk-1,Yk-1...n1,Y1
    else error()
until X = eof