質問
ここで計算ソースを見ています 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); }
注:バイソンを使用しています。
解決
そのようなグループ化の問題は、ルールの優先順位が失われることです。つまり、どのmathopで、どの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: '*' { $ = '*'; }
| '/' { $ = '/'; }
;
他のヒント
次の2つの方法で実行できます。
- lexステージで演算子の認識を定義し、終端記号(構文mathOp内)に演算子 '+'、 '-'の値を提供します...
-
mathOpを非終端として使用すると、関連する値を返すことができます:
mathOp: '+' {$$ = '+'; } | '-' {$$ = '-'; } ...
使用方法は次のようになります($ 2に注意してください):
| expr mathOp expr { $ = opr($2, 2, $1, $3); }
より複雑なmathOpを定義してから%typeを使用したい場合
所属していません StackOverflow