开发者

Backtracking in scala parser combinators?

开发者 https://www.devze.com 2023-02-03 08:42 出处:网络
It seems like scala\'s parser combinators don\'t backtrack. I have a grammar (see bottom) which can\'t parse the following \"stmt\" correctly:

It seems like scala's parser combinators don't backtrack. I have a grammar (see bottom) which can't parse the following "stmt" correctly:

copy in to out .

That should be easy to parse with backtracking:

stmt: (to out(copy in))

or am I missing something?

Parser:

type ExprP = Parser[Expr]
type ValueP = Parser[ValExpr]
type CallP = Parser[Call]
type ArgsP = Parser[Seq[E开发者_开发百科xpr]]

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}


You want to use PackratParsers in 2.8. I think the packrat parser is the only backtracking parser.

Edit: as of mid-year 2015, you should use fastparse instead. It's not only much faster, but also easier to use (especially when building data structures from parsing).


Your problem is not backtracking. The standard | operator in scala.util.parsing.combinator will do backtracking. Your problem is left-recursion (exprcallargssmplargsexpr). Packrat parsing may indeed help with that.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号