2012-05-07 9 views
13
unterstützt

Die Dokumentation für Parsec.Expr.buildExpressionParser sagt:Parsec.Expr wiederholt Prefix/Postfix Betreiber nicht

Präfix und Postfix-Operatoren mit demselben Rang nur einmal auftreten können (dh --2, wenn nicht erlaubt - Präfix negieren).

und in der Tat, das mich beißt, da die Sprache, die ich (man denke an einem C-Ausdruck wie **a[1][2]) ermöglicht beliebige Wiederholung der Präfix und Postfix-Operatoren zu analysieren versuche. So

, warum Parsec diese Einschränkung machen, und wie kann ich es umgehen?

Ich denke, ich kann meine Prefix/Postfix-Parser nach unten in den term Parser verschieben, da sie die höchste Priorität haben.

dh

**a + 1 

als

analysiert wird
(*(*(a)))+(1) 

aber was hätte ich tun, wenn ich es analysieren wollte als

*(*((a)+(1))) 

wenn buildExpressionParser tat, was ich will, ich hätte einfach die Reihenfolge der Operatoren in der Tabelle neu ordnen können.

Hinweishere für eine bessere Lösung

Antwort

13

Siehe gelöst ich es selbst von chainl1 mit:

prefix p = Prefix . chainl1 p $ return  (.) 
postfix p = Postfix . chainl1 p $ return (flip (.)) 

Diese combinators verwenden chainl1 mit einem op Parser, der immer erfolgreich ist, und einfach die Funktionen komponiert zurück durch die term Parser in von links nach rechts oder von rechts nach links um. Diese können in der buildExprParser Tabelle verwendet werden; wo Sie dies getan hätte:

exprTable = [ [ Postfix subscr 
       , Postfix dot 
       ] 
      , [ Prefix pos 
       , Prefix neg 
       ] 
      ] 

jetzt Sie dies tun:

auf diese Weise kann buildExprParser noch einstellen Operator Vorrang verwendet werden, aber jetzt sieht nur einen einzigen Prefix oder Postfix Operator bei jeder Priorität. Allerdings haben die Betreiber die Möglichkeit, so viele Kopien von mir selbst schlürfen, wie sie kann, und eine Funktion zurück, die es so aussehen, als voll ist, wenn es nur ein einziger Betreiber war.

+0

Ich fand Ihre Antwort sehr nützlich, aber ich lief in ein anderes Problem, detaillierte [hier] (http://stackoverflow.com/questions/11174775), und ich würde es begrüßen, wenn Sie einen Blick auf die nehmen könnte wenn du keine Chance hast, hast du eine Lösung. –

+0

Danke für die nützliche Antwort. Ich habe ein paar Schwierigkeiten mit einer Verallgemeinerung dieses Problems. Wenn Sie Vorschläge haben, würden sie sehr willkommen sein (siehe http://stackoverflow.com/questions/33214163/parsec-expr-repeated-prefix-with-different-priority/33217888#33217888) – BartBog