Frage

Ich mache Übungen Cay Horstmanns combinator Parser, frage ich mich über den besten Weg zwischen Strings zu unterscheiden, die Zahlen und Strings darstellen, die Variablen in einem Spiel Aussage darstellen:

def factor: Parser[ExprTree] = (wholeNumber | "(" ~ expr ~ ")" | ident) ^^ {
    case a: wholeNumber  => Number(a.toInt)
    case a: String => Variable(a)
}

Die zweite Zeile gibt „Fall a: wholeNumber“ nicht legal ist. Ich dachte über einen regulären Ausdruck, haben aber keinen Weg, um es an die Arbeit mit „Fall“.

gefunden
War es hilfreich?

Lösung

Ich würde es gespalten ein wenig und die Fallanalyse in die | schieben. Dies ist einer der Vorteile von Kombinatoren und wirklich LL (*) Analyse im Allgemeinen:

def factor: Parser[ExprTree] = ( wholeNumber ^^ { Number(_.toInt) }
                               | "(" ~> expr <~ ")" 
                               | ident ^^ { Variable(_) } )

Ich entschuldige mich, wenn Sie nicht vertraut mit der Unterstrich-Syntax sind. Im Grunde bedeutet es einfach „ersetzen die n th Parameter an die einschließende Funktion Wert“. So { Variable(_) } entspricht { x => Variable(x) }.

Ein weiteres Bit von Syntax Magie hier ist die ~> und <~ Betreiber anstelle von ~. Diese Operatoren bedeuten, dass die Analyse dieses Begriffs sollte die Syntax sind sowohl der Pars, aber das Ergebnis sollte ausschließlich durch das Ergebnis der expr bestimmt werden. Somit ist die "(" ~> expr <~ ")" paßt genau das Gleiche wie "(" ~ expr ~ ")", aber nicht die zusätzliche Fallanalyse erfordert den inneren Ergebniswert von expr abgerufen werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top