5

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}
4

2 に答える 2

4

あなたの問題は後戻りではありません。の標準|演算子scala.util.parsing.combinatorはバックトラックを実行します。あなたの問題は左再帰です(expr→→→→ )。Packratの解析は確かにそれを助けるかもしれません。callargssmplargsexpr

于 2011-08-09T03:28:22.133 に答える
4

PackratParsers2.8で使いたい。backtracking パーサーは packrat パーサーだけだと思います。

編集: 2015 年半ば以降、代わりにfastparseを使用する必要があります。はるかに高速であるだけでなく、使いやすい (特に解析からデータ構造を構築する場合)。

于 2011-01-06T20:42:28.780 に答える