在Scala解析器组合器中进行回溯?
-
26-09-2019 - |
题
似乎Scala的解析器组合者没有回溯。我有一个语法(请参见底部),无法正确解析以下“ STMT”:
copy in to out .
回溯很容易解析:
stmt: (to out(copy in))
还是我想念什么?
解析器:
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}
解决方案
你想使用 PackratParsers
在2.8中。我认为Packrat解析器是唯一的回溯解析器。
编辑:截至2015年中,您应该使用 Fastparse 反而。它不仅更快,而且更易于使用(尤其是在解析构建数据结构时)。
其他提示
您的问题不是回溯。标准 |
操作员进 scala.util.parsing.combinator
会回溯。您的问题是左记录(expr
→ call
→ args
→ smplargs
→ expr
)。 Packrat解析确实可能有助于解决这个问题。
不隶属于 StackOverflow