2011-01-06 8 views
5

Кажется, что комбайны Scars's parser не возвращаются. У меня есть грамматики (см снизу), которые не могут разобрать следующее «STMT» правильно:Backtracking в компиляторах scala parser?

copy in to out . 

Это должно быть легко разобрать с откатами:

stmt: (to out(copy in)) 

или я что-то отсутствует?

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

Получил это близко к работе, теперь я получаю переполнение стека. Обновлен парсер. – Anonymous

ответ

4

Вы хотите использовать PackratParsers в 2.8. Я думаю, что парсер parrat является единственным парсером обратного отслеживания.

Редактировать: начиная с середины 2015 года вместо этого вы должны использовать fastparse. Это не только намного быстрее, но и проще в использовании (особенно при построении структур данных при разборе).

+0

Кажется, это не исправлено; Я все еще получаю SO (от леворекурсивной грамматики), и я слышал, что метод parrat-parsing должен быть в состоянии исправить это. Если я сделаю это синтаксисом значений перед вызовами, то он не будет анализировать (нет возврата)? Может быть, я не активировал разбор паркета, но я обязательно поместил в PackratParsers и вернул PakratParser из всех функций. Вы знаете что-то о PackratParsers? – Anonymous

+1

О, ладно, теперь я нашел его. Для всех вас, кто нуждается в packrat-parsers: не забудьте заменить «def» на «lazy val», замените «Parser [T]» на «PackratParser [T]» и сделайте смешивание парсеров-класс/объект из PackratParsers. – Anonymous

+0

@Anonymous Пожалуйста, поясните свою последнюю инструкцию: «сделайте смешивание парсеров/объектов из PackratParsers». Это просто «с PackratParsers» для класса? – javadba

3

Ваша проблема не в обратном направлении. Стандартный оператор | в scala.util.parsing.combinator выполнит откат. Ваша проблема - левая рекурсия (exprcallargssmplargsexpr). Анализ Packrat действительно может помочь в этом.