質問

ここで計算ソースを見ています 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を使用したい場合

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top