2011-01-06 25 views
5

Wygląda na to, że kombinatory parsera scala nie cofają się. Mam gramatyki (patrz na dole), które nie mogą analizować następujące „stmt” poprawnie:Powrót do tyłu w kombinatorach parsera scala?

copy in to out . 

które powinny być łatwe do analizowania z backtracking:

stmt: (to out(copy in)) 

albo ja czegoś brakuje?

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

Gotowy do pracy, teraz mam przepełnienie stosu. Zaktualizowany analizator składni. – Anonymous

Odpowiedz

4

Chcesz użyć PackratParsers w 2,8. Myślę, że parser packrat jest jedynym parserem wstecznym.

Edytuj: od połowy roku 2015 należy zamiast tego użyć numeru fastparse. Jest nie tylko znacznie szybszy, ale także łatwiejszy w użyciu (szczególnie przy budowaniu struktur danych z parsowania).

+0

Nie wydaje się, aby to naprawić; Nadal dostaję SO (z gramatyki lewej rekursywnej) i słyszałem, że parsowanie pakietów powinno być w stanie to naprawić. Jeśli sprawię, że przeanalizuję wartości przed wywołaniami, to nie będzie parsować (bez cofania?). Być może nie aktywowałem parsowania pakietów, ale upewniłem się, że miksowałem w PackratParsers i zwróciłem PakratParser ze wszystkich funkcji. Czy wiesz coś o PackratParsers? – Anonymous

+1

No dobra, teraz go znalazłem. Wszystkim, którzy potrzebują packrat-parserów: pamiętajcie o zastąpieniu "def" przez "lazy val", zastąpcie "Parser [T]" słowem "PackratParser [T]" i dokonajcie miksowania klasy/obiektu parserów z PackratParsers. – Anonymous

+0

@Anonymous Prosimy o bardziej szczegółowe informacje na temat ostatniej instrukcji: "wykonaj składankę klasy/obiektu z PackratParsers". Czy to po prostu "z PackratParsers" dla klasy? – javadba

3

Twój problem nie powraca. Standardowy operator | w scala.util.parsing.combinator wykona operację cofania. Twoim problemem jest lewa rekursja (exprcallargs → → expr). Przetwarzanie Packrat może w tym pomóc.