Im trying to match this syntax:
pgm ::= exprs exprs ::= expr [; exprs] expr ::= ID | expr . [0-9]+
My scala packrat parser combinator is as follows:
import scala.util.parsing.combinator.PackratParsers import scala.util.parsing.combinator.syntactical._ object Dotter extends StandardTokenParsers with PackratParsers { lexical.delimiters ++= List(".",";") def pgm = repsep(expr,";") def expr :Parser[Any]= ident | expr~"."~num def num = numericLit def parse(input: String) = phrase(pgm)(new PackratReader(new lexical.Scanner(input))) match { case Success(result, _) => println("Success!"); Some(result) case n @ _ => println(n);println("bla"); None } def main(args: Array[String]) { val prg = "x.1.2.3;" + "y.4.1.1;" + "z;" + "n.1.10.30" parse(prg); } }
But that does not work. Or he "corresponds to the greedy," and tells me:
[1.2] failure: end of input expected x.1.2.3;y.4.1.1;z;n.1.10.30
or if I change | on a ||| I get stackoverflow:
Exception in thread "main" java.lang.StackOverflowError at java.lang.Character.isLetter(Unknown Source) at java.lang.Character.isLetter(Unknown Source) at scala.util.parsing.combinator.lexical.Lexical$$anonfun$letter$1.apply(Lexical.scala:32) at scala.util.parsing.combinator.lexical.Lexical$$anonfun$letter$1.apply(Lexical.scala:32) ...
I already understood why I get errors; What can I do to parse the syntax as above? It seems this is not esoteric for me
EDIT: Based on the article provided at http://scala-programming-language.1934581.n4.nabble.com/Packrat-parser-guidance-td1956908.html I found out that my program did not actually use the new parrat parser.
Those. change Parser[Any] to PackratParser[Any] and use lazy val instead of def
I rewrote the above:
import scala.util.parsing.combinator.PackratParsers import scala.util.parsing.combinator.syntactical._ object Dotter extends StandardTokenParsers with PackratParsers { lexical.delimiters ++= List(".",";") lazy val pgm : PackratParser[Any] = repsep(expr,";") lazy val expr :PackratParser[Any]= expr~"."~num | ident lazy val num = numericLit def parse(input: String) = phrase(pgm)(new PackratReader(new lexical.Scanner(input))) match { case Success(result, _) => println("Success!"); Some(result) case n @ _ => println(n);println("bla"); None } def main(args: Array[String]) { val prg = "x.1.2.3 ;" + "y.4.1.1;" + "z;" + "n.1.10.30" parse(prg); } }
scala parser-combinators ebnf
svrist
source share