Note that there are some explanatory texts on larger screens.

plurals
  1. POScala Parser Combinators tricks for recursive bnf?
    primarykey
    data
    text
    <p>Im trying to match this syntax:</p> <pre><code>pgm ::= exprs exprs ::= expr [; exprs] expr ::= ID | expr . [0-9]+ </code></pre> <p>My scala packrat parser combinator looks like this:</p> <pre><code>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, _) =&gt; println("Success!"); Some(result) case n @ _ =&gt; 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); } } </code></pre> <p>But this doesnt work. Either it "matches greedy" and tells me:</p> <pre><code>[1.2] failure: end of input expected x.1.2.3;y.4.1.1;z;n.1.10.30 </code></pre> <p>or if I change the <code>|</code> to a <code>|||</code> I get a stackoverflow:</p> <pre><code>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) ... </code></pre> <p>I kindoff understand why I get the errors; what can I do to parse a syntax like the above? It doesnt seem that esoteric to me</p> <p>EDIT: Based on the paper referenced in <a href="http://scala-programming-language.1934581.n4.nabble.com/Packrat-parser-guidance-td1956908.html" rel="noreferrer">http://scala-programming-language.1934581.n4.nabble.com/Packrat-parser-guidance-td1956908.html</a> I found out that my program didnt actually use the new packrat parser.</p> <p>Ie. change <code>Parser[Any]</code> to <code>PackratParser[Any]</code> and use <code>lazy val</code> instead of <code>def</code></p> <p>I rewrote the above to this:</p> <pre><code>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, _) =&gt; println("Success!"); Some(result) case n @ _ =&gt; 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); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload