YACC/BISON, minimize o valor agrupando o OPS de matemática
Pergunta
Estou olhando para a fonte do calc aqui http://epaperpress.com/lexandyacc/
Eu vejo essas linhas em 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); }
Existe uma maneira de agrupar -os? Então, posso escrever algo como o abaixo?
| expr mathOp expr { $$ = opr(mathOp, 2, $1, $3); }
| expr cmpOp expr { $$ = opr(cmpOp, 2, $1, $3); }
Nota: Estou usando o bisonte.
Solução
O problema de agrupá -los assim é que você perde as precedências sobre as regras - você tem apenas uma regra que tem precedência diferente, dependendo de qual é o Mathop, que o bisonte/yacc não pode lidar. Dito isto, você pode agrupar as operações do mesmo nível de precedência juntas
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: '*' { $$ = '*'; }
| '/' { $$ = '/'; }
;
Outras dicas
Você pode fazer isso de 2 maneiras:
- No Stage Lex, define o reconhecimento dos operadores e forneça símbolo de terminal (na sua sintaxe Mathop) com o valor do operador '+', '-' ...
Usando o Mathop como não terminal, você pode retornar algum valor associado:
MATHOP: '+' {$$ = '+'; } | '-' {$$ = '-'; } ...
Em seguida, o uso será (preste atenção a US $ 2):
| expr mathOp expr { $$ = opr($2, 2, $1, $3); }
Pode ser que você gostaria de definir Mathop mais complicado e do que o tipo %