2011-01-06 11 views
5

Sembra che i combinatori di parser di scala non tornino indietro. Ho una grammatica (vedi in basso) che non può analizzare il seguente "stmt" correttamente:Backtracking in scala parser combinatori?

copy in to out . 

che dovrebbe essere facile da analizzare con backtracking:

stmt: (to out(copy in)) 

o mi sto perdendo qualcosa?

Parser:

type ExprP = Parser[Expr] 
type ValueP = Parser[ValExpr] 
type CallP = Parser[Call] 
type ArgsP = Parser[Seq[Expr]] 

val ident  = "[a-zA-Z\\+\\-\\*/%><\\\\\\=]+".r 
val sqstart = "\\["       .r 
val sqend  = "\\]"       .r 
val del  = ","       .r 
val end  = "\\."       .r 

def stmt: ExprP  = expr <~ end 
def expr: ExprP  = ucall | call | value 
def value: ValueP = ident ^^ {str => IdentExpr(str)} 
def call: CallP  = (args ~ ident ~ expr) ^^ {case args ~ method ~ upon => Call(args, method, upon)} 
def ucall: CallP  = (ident ~ expr) ^^ {case method ~ upon => Call(Seq(), method, upon)} 
def args: ArgsP  = advargs | smplargs 
def smplargs: ArgsP = expr ^^ {e => Seq(e)} 
def advargs: ArgsP = (sqstart ~> repsep(expr, del) <~ sqend) ^^ {seq => seq} 
+0

Ottenuto vicino al lavoro, ora ottengo uno stack overflow. Parser aggiornato. – Anonymous

risposta

4

Si desidera utilizzare PackratParsers in 2.8. Penso che il parser Packrat è l'unico parser backtracking.

Modifica: a partire dalla metà dell'anno 2015, invece, è necessario utilizzare fastparse. Non è solo molto più veloce, ma anche più facile da usare (specialmente quando si costruiscono strutture dati dall'analisi).

+0

Non sembra aggiustarlo; Ho ancora SO (da una grammatica ricorsiva a sinistra), e ho sentito che l'analisi di packrat dovrebbe essere in grado di risolverlo. Se faccio in modo che analizzi i valori prima delle chiamate, non verrà analizzato (nessun backtracking?). Forse non ho attivato l'analisi del packrat, ma mi sono assicurato di mescolare PackratParsers e restituire PakratParser da tutte le funzioni. Sai qualcosa su PackratParsers? – Anonymous

+1

Oh, ok, ora l'ho trovato. A tutti voi che avete bisogno di parser packrat: ricordatevi di sostituire "def" con "lazy val", sostituire "Parser [T]" con "PackratParser [T]" e creare il mix-class parser/object da PackratParsers. – Anonymous

+0

@Anonimo Per favore, sii più chiaro sulla tua ultima istruzione: "crea la combinazione parsers-class/object da PackratParsers". È semplicemente "con PackratParsers" per la classe? – javadba

3

Il tuo problema non è il backtracking. L'operatore standard | in scala.util.parsing.combinator eseguirà il backtracking. Il tuo problema è ricorsione sinistra (expr → → argssmplargsexpr). L'analisi di Packrat può davvero aiutare in questo.

Problemi correlati