Parser combinatori Scala: distinguere tra stringhe numeriche e stringhe variabili
-
05-07-2019 - |
Domanda
Sto facendo esercizi di parser combinatore di Cay Horstmann, mi chiedo il modo migliore per distinguere tra stringhe che rappresentano numeri e stringhe che rappresentano variabili in una dichiarazione di corrispondenza:
def factor: Parser[ExprTree] = (wholeNumber | "(" ~ expr ~ ")" | ident) ^^ {
case a: wholeNumber => Number(a.toInt)
case a: String => Variable(a)
}
La seconda riga lì, " case a: wholeNumber " non è legale. Ho pensato a un regexp, ma non ho trovato il modo di farlo funzionare con & Quot; case & Quot ;.
Soluzione
Lo dividerei un po 'e spingerei l'analisi del caso in |
. Questo è uno dei vantaggi dei combinatori e dell'analisi LL (*) in generale:
def factor: Parser[ExprTree] = ( wholeNumber ^^ { Number(_.toInt) }
| "(" ~> expr <~ ")"
| ident ^^ { Variable(_) } )
Mi scuso se non hai familiarità con la sintassi del trattino basso. Fondamentalmente significa solo & Quot; sostituisci il n th parametro con il valore della funzione che racchiude & Quot ;. Pertanto { Variable(_) }
equivale a { x => Variable(x) }
.
Un altro po 'di magia di sintassi qui sono gli operatori ~>
e <~
al posto di ~
. Questi operatori indicano che l'analisi di quel termine dovrebbe includere la sintassi di entrambe le parentesi, ma il risultato dovrebbe essere determinato esclusivamente dal risultato di expr
. Pertanto, "(" ~> expr <~ ")"
corrisponde esattamente alla stessa cosa di "(" ~ expr ~ ")"
, ma non richiede l'analisi di maiuscole / minuscole per recuperare il valore del risultato interno da <=>.