0

ANTLRでの左再帰の削除で質問と回答があったように、左再帰を削除できました

E-> E + T | T
T-> T * F | F
F-> INT | (E)

左再帰を削除すると、次のようになります

E-> TE '
E'-> null | + TE '
T-> FT '
T'-> null | * FT '

それでは、修正された文法でツリーを構築する方法は?入力1+2で、ツリーが欲しい

^('+' ^(INT 1)^(INT 2))
。または類似。

文法T;

オプション{
    output = AST;
    language = Python;
    ASTLabelType = CommonTree;
}

開始:e-> e
   ;
e:t ep-> ???
   ;
ep:
   | '+' t ep-> ???
   ;
t:f tp-> ???
  ;
tp:
  | '*' f tp-> ???
  ;
f:INT
  | '(' e')'-> e
  ;

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

1 に答える 1

2

少し意見があります。LR文法からLL文法に移行できる場合もありますが、これまでのように、結果は慣用的ではなく、LL文法に精通している人に文法を定義する奇妙な方法のように見える場合があります。

たとえば、上記からの次の抜粋を検討してください。

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

上記は、最初のセットに含まれる、または、それ自体の開始が正しい再帰として* 続く後続を受け入れます。したがって、ルート化する式の開始が表示されることはありません。これにより、必要なツリーを構築する必要があるよりもはるかに困難になります。fINT(*

ANTLRでそのASTを簡単に作成できるようにするには、オペランドと演算子の両方が必要です。

add:
   INT '+'^ INT;

カレットは木の根を^作り、 2つはその子になります。+INT

リンクされているBartKの例は、LL文法で実行されることを期待する良い例です...そして、異なる優先順位の演算子をサポートするように拡張されます

于 2010-06-11T21:02:59.363 に答える