2011-01-06 6 views
5

Es scheint, dass Scala Parser Kombinator nicht zurückverfolgen. Ich habe eine Grammatik (siehe unten), das folgende „Anw“ nicht analysieren kann richtig:Backtracking in Scala-Parser-Kombinatoren?

copy in to out . 

so einfach sein sollte mit Rückzieher zu analysieren:

stmt: (to out(copy in)) 

oder bin ich etwas fehlt?

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

Bekam es zu arbeiten, jetzt bekomme ich einen Stapelüberlauf. Aktualisierter Parser. – Anonymous

Antwort

4

Sie wollen PackratParsers in 2.8 verwenden. Ich denke, der Packrat-Parser ist der einzige Backtracking-Parser.

Edit: ab Mitte des Jahres 2015 sollten Sie stattdessen verwenden. Es ist nicht nur viel schneller, sondern auch einfacher zu benutzen (besonders beim Aufbau von Datenstrukturen aus dem Parsing).

+0

Es scheint nicht zu reparieren; Ich bekomme immer noch SO (von einer linksrekursiven Grammatik), und ich habe gehört, dass Packrat-Parsing das beheben könnte. Wenn ich Werte vor Aufrufen analysiere, wird es nicht analysiert (kein Backtracking?). Vielleicht habe ich Packat-Parsing nicht aktiviert, aber ich habe darauf geachtet, die PackratParser zu mischen und PakratParser von allen Funktionen zurückzugeben. Kennst du etwas über PackratParser? – Anonymous

+1

Oh, okay, jetzt habe ich es gefunden. An alle, die packrat-Parser benötigen: Denken Sie daran, "def" durch "lazy val" zu ersetzen, "Parser [T]" durch "PackratParser [T]" zu ersetzen und die Parser-Klasse/Objekt-Mischung aus PackratParsers zu machen. – Anonymous

+0

@Anonymous Bitte seien Sie bei Ihrer letzten Anweisung klarer: "Machen Sie die Parser-Klasse/Objekt-Mischung aus PackratParsers". Ist das einfach "mit PackratParsers" für die Klasse? – javadba

3

Ihr Problem ist kein Backtracking. Der Standard | Operator in scala.util.parsing.combinator wird Backtracking ausführen. Ihr Problem ist Links-Rekursion (exprcallargssmplargsexpr). Packat-Parsing kann dabei helfen.

Verwandte Themen