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 ;.

È stato utile?

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 <=>.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top