Nested Expression
ネスト式の扱いは、(トップダウンパーサではなく)ボトムアップパーサが適している。
・ネスト式は「再帰的性質」と「優先度」の扱いでトリッキーな面を有している。
・どのように対処するかは、トップダウンパーサとボトムアップパーサとで大きく異なる。
・ネスト式の扱いは、(トップダウンパーサではなく)ボトムアップパーサが適している。
ボトムアップパーサーの例
expr ::= NUMBER:n {: RESULT = new Double(n); :} | expr:a PLUS expr:b {: RESULT = a + b; :} | expr:a MINUS expr:b {: RESULT = a - b; :} | expr:a TIMES expr:b {: RESULT = a * b; :} | expr:a DIVIDE expr:b {: RESULT = a / b; :} | expr:a POWER expr:b {: RESULT = Math.pow(a,b); :} | expr:a ROOT expr:b {: RESULT = Math.pow(a,(1.0/b)); :} | MINUS expr:e {: RESULT = - e; :} %prec UMINUS | LPAREN expr:e RPAREN {: RESULT = e; :} ; precedence left PLUS, MINUS; precedence left TIMES, DIVIDE; precedence right POWER, ROOT; precedence left UMINUS;
単純な再帰グラマー規則と優先度宣言の組合せにより、ボトムアップパーサーでは入れ子式を取り扱うのは非常に容易になっている。(定義がそのまま表れている。)
トップダウンパーサ 左再帰を導入(左再帰って何?) すると→単純な再帰文法を使用できない すると→入れ子式が複雑になる すると→文法はかなり不明確 だから、多くの人はボトムアップパーサを使う
トップダウンパーサの例
expression : mult_exp ( ('+' | '-') mult_exp )* ; mult_exp : power_exp ( ('*' | '/') power_exp )* ;
ここで、左結合演算子のパターンが見られる。規則の本体は次の規則への参照から始まり、演算子とその右辺の繰り返しグループがそれに続く。常に、今対応している規則ではなく、次の規則を述べることになる。
べき乗と平方根演算子は、右結合演算子のパターンを示す。
power_exp : unary_exp ( ('**' | '//') power_exp )? ;
さらに、このボロボロの文法から生じる別の結果は、パーサーツリー結果も複雑になることである。1 + 2のパーサーツリーは、この様になることが予想されるだろう。
+ 1 2
しかし、代わりに、この様になる。
+ mult_exp power_exp unary_exp factor_exp 1 mult_exp power_exp unary_exp factor_exp 2
・RESULT変数を言語に組み込んでほしい。特に手続型言語は必須。
・+ではなくPLUSのようにトークンの名前をつけた理由として、「この本の実例で通常、選択するAntlrとは異なり、リテラル・トークンをグラマーファイルに入れることができないため」の意味が分かりません、、。前の方を読んでいないから?
・ボトムアップの文法から、トップダウンの文法を生成できないのかなぁw ・「トップダウンパーサーの愛好者は、ボロボロになるのは入れ子式の場合のみで、ボトムアップパーサーの他の問題と比較して、つり合ったトレードオフであると主張している。」とあるが、ボトムアップパーサにはこれよりひどいどんな問題があるというのだろう、。