4

ここで計算ソースを見ていますhttp://epaperpress.com/lexandyacc/

calc.y にこれらの行が表示されます

| expr '+' expr         { $$ = opr('+', 2, $1, $3); }
| expr '-' expr         { $$ = opr('-', 2, $1, $3); }
| expr '*' expr         { $$ = opr('*', 2, $1, $3); }
| expr '/' expr         { $$ = opr('/', 2, $1, $3); }
| expr '<' expr         { $$ = opr('<', 2, $1, $3); }
| expr '>' expr         { $$ = opr('>', 2, $1, $3); }

それらをグループ化する方法はありますか?代わりに以下のようなものを書くことができますか?

| expr mathOp expr         { $$ = opr(mathOp, 2, $1, $3); }
| expr cmpOp  expr         { $$ = opr(cmpOp, 2, $1, $3); }

注: バイソンを使用しています。

4

2 に答える 2

6

それらをそのようにグループ化することの問題は、ルールの優先順位を失うことです.bison / yaccが処理できないマホップに応じて、優先順位が異なる1つのルールしかありません。とはいえ、同じ優先度レベルの op をグループ化することはできます

expr: expr mulOp expr { $$ = opr($2, 2, $1, $3); } %prec '*'
    | expr addOp expr { $$ = opr($2, 2, $1, $3); } %prec '+'
    | expr relOp expr { $$ = opr($2, 2, $1, $3); } %prec '<'
             :

mulOp: '*' { $$ = '*'; }
     | '/' { $$ = '/'; }
;
于 2009-09-22T03:08:12.367 に答える
1

あなたは2つの方法でそれを行うことができます:

  • lex 段階で、演算子の認識を定義し、演算子 '+'、'-' の値を使用して終端記号 (シンタックス mathOp) を提供します。
  • mathOp を非終端記号として使用すると、関連付けられた値を返すことができます。

    mathOp : '+' { $$ = '+'; } | '-' { $$ = '-'; } ...

次に、使用法は次のようになります ($2 に注意してください):

| expr mathOp expr         { $$ = opr($2, 2, $1, $3); }

より複雑な mathOp を定義して %type を使用したい場合があります

于 2009-09-11T13:55:26.143 に答える