Ich habe zwei Schnipsel von Happy-Code hier, eine, die normale Vorrangregeln verwendet, und eine, die kontextabhängige Vorrangregeln verwendet (beide beschrieben here).Happy Context-abhängigen Operator Precedence
Normal:
%left '+'
%left '*'
%%
Exp :: { Exp }
: Exp '+' Exp { Plus $1 $3 }
| Exp '*' Exp { Times $1 $3 }
| var { Var $1 }
Kontextabhängige:
%left PLUS
%left TIMES
%%
Exp :: { Exp }
: Exp '+' Exp %prec PLUS { Plus $1 $3 }
| Exp '*' Exp %prec TIMES { Times $1 $3 }
| var { Var $1 }
Angesichts der Eingang:
a * b + c * d
Die normale Version gibt:
Plus (Times (Var "a") (Var "b")) (Times (Var "c") (Var "d"))
während die kontextabhängige Version gibt:
Times (Var "a") (Plus (Var "b") (Times (Var "c") (Var "c")))
Sollten diese die gleiche Leistung nicht beide geben? Was mache ich hier falsch, dass sie verschiedene Parse-Bäume erzeugen?
Verzeihen Sie mir, wenn das eine dumme Frage ist, da ich nie zuvor glücklich verwendet habe. Bedeutet das, dass "% links" + "; % left '*' '* deklariert * Präzedenzfälle für' '+' 'und' '*' ', aber'% links PLUS; % links TIMES' * deklariert keine Vorraussetzungen für 'PLUS' und' TIMES'? –
@DanielWagner: Was war unklar, was ich geschrieben habe? '% links '+'; % left '*' deklariert die Präzedenz für ''+' 'und'' * ''und'% left PLUS; % left TIMES' erklärt die Präzedenz für 'PLUS' und' TIMES'. Aber der Vergleich der Präzedenzfälle ist immer zwischen einer Produktion und einem Terminal und '% links PLUS; % left TIMES 'does * not * deklariert Vorrang für" + "und" * ". Warum sollte es?Und wenn ''+'' und ''*' 'keine Vorkommnisse deklariert haben, gibt es nichts, womit man die Präzedenz von' PLUS' und 'TIMES' vergleichen könnte. – rici
Danke, das macht es klar! Ich habe nicht verstanden, dass es versuchen würde, den Vorrang von "+" mit "PLUS" im zweiten Beispiel zu vergleichen und nicht zu folgen (weil nur "PLUS" dort eine erklärte Priorität hat). –