解析 – Scala解析器组合器,解析器由于优先级而失败
发布时间:2020-12-16 08:46:46 所属栏目:安全 来源:网络整理
导读:我正在尝试为编程语言Icon编写一个解释器.这个过程中的一个步骤是为Icon编写一个解析器,我用以下方式完成了: import java.io.FileReaderimport scala.util.parsing.combinator.syntactical._import scala.util.parsing.combinator.RegexParsersimport scala
我正在尝试为编程语言Icon编写一个解释器.这个过程中的一个步骤是为Icon编写一个解析器,我用以下方式完成了:
import java.io.FileReader import scala.util.parsing.combinator.syntactical._ import scala.util.parsing.combinator.RegexParsers import scala.util.parsing.combinator.PackratParsers import scala.util.parsing.combinator.JavaTokenParsers abstract class expr case class CstInt(val value : Int) extends expr case class FromTo(val from : expr,val to : expr) extends expr case class Write(val value : expr) extends expr case class And(val e1 : expr,val e2 : expr) extends expr case class Or(val e1 : expr,val e2 : expr) extends expr object ExprParser extends JavaTokenParsers with PackratParsers{ lazy val exp : PackratParser[expr] = andexp | exp2 lazy val exp2 : PackratParser[expr] = fromTo | exp3 lazy val exp3 :PackratParser[expr] = orexp | exp4 lazy val exp4 : PackratParser[expr] = integer | exp5 lazy val exp5 : PackratParser[expr] = write lazy val integer : PackratParser[expr] = wholeNumber ^^ { s => CstInt(s.toInt)} lazy val write : PackratParser[Write] = "write" ~> "(" ~> exp <~ ")" ^^ { e => Write(e)} lazy val fromTo : PackratParser[FromTo] = ("(" ~> integer) ~ ("to" ~> integer <~ ")") ^^ { case from ~ to => FromTo(from,to)} lazy val andexp : PackratParser[And] = exp ~ ("&" ~> exp) ^^ { case e1 ~ e2 => And(e1,e2)} lazy val orexp : PackratParser[Or] = exp ~ ("|" ~> exp) ^^ { case e1 ~ e2 => Or(e1,e2)} def parseInput(input: String) : expr = parseAll (exp,input) match { case Success(tree,_) => tree case e: NoSuccess => throw new IllegalArgumentException(e.toString()) } } object Interpret { def main(args : Array[String]) : Unit = { println(ExprParser.parseInput(args(0))) } } 但是,当我尝试解析以下表达式时,我遇到了一些问题: write((1 to 4) | 4) 我收到此错误: java.lang.IllegalArgumentException: [9.17] failure: `)' expected but ` ' found 而解析 write((1 to 4) & 4) 工作得很好.如果我将orexp解析器移动到fromto解析器上方的exp组,则第一个表达式可以正常工作.但是,这不符合Icon给出的规则,并不能解决潜在的问题. 有没有人对解决方案有任何想法?根据Scala文档,混合packrat解析器和常规解析器应该没问题. 解决方法
好吧,我已经阅读了Scala中的包装解析器上的
paper,我担心这个语法不能正常工作.问题是,从内部写入exp,然后写入本身失败(并且没有其他选择,外部exp失败).它永远不会回头说“好吧,让我们看看是否有另一个exp也是有效的”.
但是,看看this text,我没有看到括号作为其语法的一部分.如果只是重写它以从该级别中删除那些括号,它将起作用: object ExprParser extends JavaTokenParsers with PackratParsers{ lazy val exp : PackratParser[expr] = andexp | exp2 lazy val exp2 : PackratParser[expr] = fromTo | exp3 lazy val exp3 :PackratParser[expr] = orexp | exp4 lazy val exp4 : PackratParser[expr] = integer | exp5 lazy val exp5 : PackratParser[expr] = write | exp6 lazy val exp6 : PackratParser[expr] = "(" ~> exp <~ ")" lazy val integer : PackratParser[expr] = wholeNumber ^^ { s => CstInt(s.toInt)} lazy val write : PackratParser[Write] = "write" ~> "(" ~> exp <~ ")" ^^ { e => Write(e)} lazy val fromTo : PackratParser[FromTo] = integer ~ ("to" ~> integer) ^^ { case from ~ to => FromTo(from,to)} lazy val andexp : PackratParser[And] = exp ~ ("&" ~> exp) ^^ { case e1 ~ e2 => And(e1,e2)} lazy val orexp : PackratParser[Or] = exp3 ~ ("|" ~> exp) ^^ { case e1 ~ e2 => Or(e1,e2)} } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |