Yacc / Bison, minimiser le montant en regroupant les opérations mathématiques

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

  •  05-07-2019
  •  | 
  •  

Question

Je regarde la source de calcul ici http://epaperpress.com/lexandyacc/

Je vois ces lignes dans 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-t-il un moyen de les regrouper? donc je peux écrire quelque chose comme le ci-dessous à la place?

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

REMARQUE: j'utilise du bison.

Était-ce utile?

La solution

Le problème avec les regrouper ainsi est que vous perdez les précédents sur les règles - vous n’avez qu’une règle qui a des précédents différents en fonction de son magasin, que bison / yacc ne peut pas gérer. Cela dit, vous pouvez grouper des opérations du même niveau de priorité

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: '*' { $ = '*'; }
     | '/' { $ = '/'; }
;

Autres conseils

Vous pouvez le faire de deux manières:

  • Au stade de la lex, définissez la reconnaissance des opérateurs et fournissez le symbole du terminal (dans votre syntaxe mathOp) avec la valeur de l'opérateur '+', '-' ...
  • En utilisant mathOp comme terminal, vous pouvez renvoyer une valeur associée:

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

Ensuite, l'utilisation ressemblera (attention à 2 $):

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

peut-être voudriez-vous définir mathOp plus compliqué, puis utilisez% type

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top