0

正如在删除 ANTLR 中的左递归中询问和回答的那样,我可以删除左递归

E -> E + T|T
T -> T * F|F
F -> 整数 | (五)

左递归删除后,我得到以下一个

E -> TE'
E'-> 空 | + TE'
T -> 英尺'
T'-> 空 | *英尺'

那么,如何用修改后的语法进行树构造呢?输入1+2,我想要一棵树

^('+' ^(INT 1) ^(INT 2))
. 或类似的。

语法 T;

选项 {
    输出=AST;
    语言=Python;
    ASTLabelType=CommonTree;
}

开始:e -> e
   ;
e : t ep -> ???
   ;
EP:
   | '+' t ep -> ???
   ;
t : f tp -> ???
  ;
TP:
  | '*' f tp -> ???
  ;
f : 整数
  | '(' e ')' -> e
  ;

INT : '0'..'9'+ ;
WS: (' '|'\n'|'\r')+ {$channel=HIDDEN;} ;
4

1 回答 1

2

一点意见:尽管有时可以从 LR 语法转到 LL 语法,但正如您所做的那样,结果并不像惯用的那样,对于熟悉 LL 语法的人来说,定义语法似乎是一种奇怪的方式。

例如,考虑上面的以下摘录:

tp : 
  | '*' f tp -> ???

上面接受 a* 后跟a ,f其第一个集合将包含INTor (,其自身的开始作为其右递归。因此,您永远不会看到您想要根植于的表达式的开头*,这将使构建您想要的树变得比需要的困难得多。

为了便于在 ANTLR 中创建 AST,您需要同时拥有操作数和运算符。

add:
   INT '+'^ INT;

插入符号^使+树的根和两个INTs 成为它的孩子。

Bart K链接到的示例是一个很好的示例,说明了我希望如何使用 LL 语法完成它......并且它可以扩展以支持不同优先级的运算符。

于 2010-06-11T21:02:59.363 回答