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