Falls Sie auf diese Frage kam und dachte, dass Sie endlich diesen Moment erreicht hatte, wenn Sie genau das finden, was Sie suchen, dann enttäuscht waren, ist hier eine deutlichere Antwort:
Sie können nicht verwenden% prec aus dem Grund Thelema erwähnt. Daher müssen Sie die Assoziativität beim Erstellen eines rekursiven Regelsatzes definieren.
Hier ist ein parser.mly
vereinfachte-around Arbeit
%token <int> Num
%token <string> Id
%token TRUE FALSE
%token LET REC EQ IN FUN ARROW IF THEN ELSE
%token PLUS MINUS MUL DIV LT LE NE AND OR
%token EOF
%start exp
%type <Simple.expr> exp
%%
/* Associativity increases from exp to exp8
* Each precedence level trickles down to higher level expressions if the pattern is not matched
*/
/* Parses the LET, LET REC, FUN, and IF expressions */
exp:
LET Id EQ exp IN exp { Let($2,$4,$6) }
| LET REC Id EQ exp IN exp { Letrec($3,$5,$7) }
| FUN Id ARROW exp { Fun($2,$4) }
| IF exp THEN exp ELSE exp { If($2,$4,$6) }
| exp2 { $1 }
/* Parses OR expressions */
exp2:
exp2 OR exp3 { Bin($1,Or,$3) }
| exp3 { $1 }
/* Parses AND expressions */
exp3:
exp3 AND exp4 { Bin($1,And,$3) }
| exp4 { $1 }
/* Parses EQ, NE, LT, and LE expressions */
exp4:
exp4 EQ exp5 { Bin($1,Eq,$3) }
| exp4 NE exp5 { Bin($1,Ne,$3) }
| exp4 LT exp5 { Bin($1,Lt,$3) }
| exp4 LE exp5 { Bin($1,Le,$3) }
| exp5 { $1 }
/* Parses PLUS and MINUS expressions */
exp5:
exp5 PLUS exp6 { Bin($1,Plus,$3) }
| exp5 MINUS exp6 { Bin($1,Minus,$3) }
| exp6 { $1 }
/* Parses MUL and DIV expressions */
exp6:
exp6 MUL exp7 { Bin($1,Mul,$3)}
| exp6 DIV exp7 { Bin($1,Div,$3)}
| exp7 { $1 }
/* Parses Function Application expressions */
exp7:
exp7 exp8 { Apply($1,$2) }
| exp8 { $1 }
/* Parses numbers (Num), strings (Id), booleans (True | False), and expressions in parentheses */
exp8:
Num { Const($1) }
| Id { Var($1) }
| TRUE { True }
| FALSE { False }
| LPAREN exp RPAREN { $2 }
Die rekursive ist wirklich der Fall für den Fang, die wir in Bezug auf diese Frage betroffen sind, ist es jedoch leicht zu sehen, wie es zu definieren, angewendet werden kann, Assoziativität für den Rest der Ausdrücke.
Der Kern dieses Ansatzes besteht darin, das fragliche Muster mit den im Anfangsfall (exp) definierten Mustern in Übereinstimmung zu bringen und einen Aufruf an den nächstfolgenden Fall (exp2) als Catch-All-Muster zu belassen Ihr Muster passt zu keinem davor; Fortsetzung mit diesem Ansatz, bis das Muster schließlich übereinstimmt. Dies bedeutet, dass das Muster mit der höchsten Priorität im weitesten Fall existiert - in diesem Beispiel exp8.
In diesem Beispiel ist der Fall für Apply (Funktionsanwendung) in exp7. Dies liegt daran, dass Apply in diesem Beispiel die höchste Assoziativität eines Musters aufweist. Der Grund dafür, dass es keine Priorität gegenüber den Fällen in exp8 hat, liegt darin, dass die Auswertung auf weitere Aufrufe von Ausdrucksfällen und nicht auf Aufrufe von Werten angewendet wird. Wenn exp8 nicht existieren würde, hätten wir einen unendlichen Blick auf unsere Hände.
In der hypothetischen simple.ml ist die Funktion Application als Ausdruck der folgenden Eigenschaft definiert: Apply of expr * expr.Und da Apply links-rekursiv ist, bewerten wir den rechten Ausdruck (exp8) und rekursiv auf der linken Seite (exp7).
Danke. Funktioniert jetzt :) – Amadan
Was war die Lösung, die du benutzt hast? – Thelema