Ich versuche Parsec zu lernen, indem ich einen kleinen regulären Ausdrucksparser implementiere. In BNF sieht meine Grammatik ungefähr so aus:
%Vor%Ich habe versucht, dies in Haskell als zu implementieren:
%Vor% Es gibt jedoch einige unendliche Schleifen (z. B. Ausdruck - & gt; Stern - & gt; Ausdruck, ohne irgendwelche Tokens zu verbrauchen), was den Parser für immer schleifen lässt. Ich bin mir aber nicht sicher, wie ich das beheben soll, denn die Besonderheit von star
ist, dass es am Ende sein obligatorisches Token verbraucht.
Irgendwelche Gedanken?
Sie sollten Parsec.Expr.buildExprParser
; es ist ideal für diesen Zweck. Sie beschreiben einfach Ihre Operatoren, ihre Präzedenz und Assoziativität und wie man ein Atom analysiert, und der Kombinator erstellt den Parser für Sie!
Sie möchten wahrscheinlich auch die Möglichkeit hinzufügen, Begriffe mit Parens zu gruppieren, damit Sie *
auf mehr als nur ein einzelnes Literal anwenden können.
Hier ist mein Versuch (Ich habe |
, +
und ?
für ein gutes Mass hinzugefügt):
Ihre Grammatik ist links-rekursiv, was mit try
nicht gut funktioniert, da Parsec immer wieder zurückgeht. Dafür gibt es ein paar Möglichkeiten. Wahrscheinlich ist das einfachste das *
optional in einer anderen Regel:
Natürlich werden Sie am Ende sowieso Dinge in einen Datentyp einschließen, und es gibt viele Möglichkeiten, dies zu tun. Hier ist einer, aus dem Kopf:
%Vor%Vielleicht wird ein erfahrener Haskeller mit einer besseren Lösung kommen.
Tags und Links haskell parsing grammar context-free-grammar parsec