Pregunta

Estoy viendo la fuente de cálculo aquí http://epaperpress.com/lexandyacc/

Veo estas líneas en 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); }

¿Hay alguna manera de agruparlos? así que puedo escribir algo como el siguiente en su lugar?

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

NOTA: Estoy usando bisonte.

¿Fue útil?

Solución

El problema con agruparlos de esta manera es que se pierden las precedencias en las reglas; solo tiene una regla que tiene una precedencia diferente dependiendo de qué mathop es, que bison / yacc no puede manejar. Dicho esto, PUEDES agrupar operaciones del mismo nivel de precedencia 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: '*' { $ = '*'; }
     | '/' { $ = '/'; }
;

Otros consejos

Puedes hacerlo de 2 maneras:

  • En la etapa lex, defina el reconocimiento de los operadores y proporcione un símbolo de terminal (en su sintaxis mathOp) con el valor del operador '+', '-' ...
  • Usando mathOp como no terminal, puede devolver algún valor asociado:

    mathOp: '+' {$$ = '+'; } | '-' {$$ = '-'; } ...

Entonces el uso se verá como (preste atención a $ 2):

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

puede ser que te gustaría definir mathOp más complicado y luego usar% type

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top