Возврат в комбинаторы скала парсер? - PullRequest
5 голосов
/ 06 января 2011

Похоже, что комбинаторы парсера scala не возвращаются. У меня есть грамматика (см. Внизу), которая не может правильно проанализировать следующее «stmt»:

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}

Ответы [ 2 ]

4 голосов
/ 06 января 2011

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

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

3 голосов
/ 09 августа 2011

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

...