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

像这样对它们进行分组的问题是你失去了规则的优先级——你只有一个规则具有不同的优先级,具体取决于它是哪个数学运算,哪个野牛/yacc 无法处理。也就是说,您可以将相同优先级的操作组合在一起

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

你可以通过两种方式做到这一点:

  • 在 lex 阶段定义运算符的识别并提供带有运算符 '+'、'-' 的值的终端符号(在你的语法 mathOp 中)......
  • 使用 mathOp 作为非终结符,您可以返回一些关联值:

    数学运算:'+' { $$ = '+'; } | '-' { $$ = '-'; } ...

然后使用情况将如下所示(注意 $2):

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

可能你想定义更复杂的 mathOp 然后使用 %type

于 2009-09-11T13:55:26.143 回答