Yacc / Bison, минимизируйте количество, сгруппировав математические операции

StackOverflow https://stackoverflow.com/questions/1410875

  •  05-07-2019
  •  | 
  •  

Вопрос

Я смотрю на исходный код calc здесь 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); }

ПРИМЕЧАНИЕ:Я использую bison.

Это было полезно?

Решение

Проблема с их группировкой заключается в том, что вы теряете приоритеты в правилах - у вас есть только одно правило, которое имеет различный приоритет, в зависимости от того, какой это mathop, который bison / 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: '*' { $ = '*'; }
     | '/' { $ = '/'; }
;

Другие советы

Вы можете сделать это двумя способами:

  • На этапе lex определите распознавание операторов и укажите терминальный символ (в вашем синтаксисе mathOp) со значением оператора '+', '-' ...
  • Используя mathOp как нетерминальный, вы можете вернуть некоторое связанное значение:

    Мэтоп :'+' { $$ = '+';} | '-' { $$ = '-';} ...

Тогда использование будет выглядеть следующим образом (обратите внимание на 2 доллара):

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

возможно, вы хотели бы определить более сложный mathOp, а затем использовать %type

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top