Retour en arrière dans combinateurs analyseur scala?
-
26-09-2019 - |
Question
Il semble que les combinateurs analyseur de scala ne BackTrack. J'ai une grammaire (voir en bas) qui ne peut pas analyser les éléments suivants « stmt » correctement:
copy in to out .
Cela devrait être facile à analyser avec retours en arrière:
stmt: (to out(copy in))
ou suis-je manque quelque chose?
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}
La solution
Vous voulez utiliser PackratParsers
2.8. Je pense que l'analyseur packrat est le seul analyseur de retours en arrière.
Edit: au milieu de l'année 2015, vous devez utiliser fastparse à la place. Il est non seulement beaucoup plus rapide, mais aussi plus facile à utiliser (en particulier lors de la construction des structures de données de l'analyse syntaxique).
Autres conseils
Votre problème n'est pas marche arrière. L'opérateur standard |
dans scala.util.parsing.combinator
va ne faire marche arrière. Votre problème est-gauche récursion (expr
→ call
→ args
→ smplargs
→ expr
). l'analyse syntaxique PackRat peut en effet aider.