Scala Parser Combinators用于递归bnf?
发布时间:2020-12-16 18:54:43 所属栏目:安全 来源:网络整理
导读:我试图匹配这种语法: pgm ::= exprsexprs ::= expr [; exprs]expr ::= ID | expr . [0-9]+ 我的scala packrat解析器组合器看起来像这样: import scala.util.parsing.combinator.PackratParsersimport scala.util.parsing.combinator.syntactical._object D
我试图匹配这种语法:
pgm ::= exprs exprs ::= expr [; exprs] expr ::= ID | expr . [0-9]+ 我的scala packrat解析器组合器看起来像这样: 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); } } 但这不起作用.要么“匹配贪婪”并告诉我: [1.2] failure: end of input expected x.1.2.3;y.4.1.1;z;n.1.10.30 或者如果我改变了|到|||我得到一个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) ... 我理解为什么我会得到错误;我该怎么做才能解析上面的语法?对我来说似乎并不深奥 编辑: IE浏览器.将Parser [Any]更改为PackratParser [Any]并使用lazy val而不是def 我把上面的内容改写为: 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); } } 解决方法
问题是(至少部分地)你实际上并没有使用Packrat解析器.请参阅Scala的
PackratParsers特征文档
我不太了解Scala 2.8的解析器组合器来完全解决这个问题,但是通过以下修改,我能够将它解析为分号,这比你已经完成的改进了. object Dotter extends StandardTokenParsers with PackratParsers { lexical.delimiters ++= List(".",";") lazy val pgm:PackratParser[Any] = repsep(expr,";") lazy val expr:PackratParser[Any]= ident ||| (expr~"."~numericLit) def parse(input: String) = phrase(expr)(lex(input)) match { case Success(result,_) => println("Success!"); Some(result) case n @ _ => println(n);println("bla"); None } def lex(input:String) = new PackratReader(new lexical.Scanner(input)) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |