【发布时间】:2018-01-11 12:54:14
【问题描述】:
我一直在尝试使用 scala-parser-combinator 库构建 SQL 解析器,我已将其大大简化为下面的代码。
class Expression
case class FalseExpr() extends Expression
case class TrueExpr() extends Expression
case class AndExpression(expr1: Expression, expr2: Expression) extends Expression
object SimpleSqlParser {
def parse(sql: String): Try[Expression] = new SimpleSqlParser().parse(sql)
}
class SimpleSqlParser extends RegexParsers {
def parse(sql: String): Try[_ <: Expression] = parseAll(expression, sql) match {
case Success(matched,_) => scala.util.Success(matched)
case Failure(msg,remaining) => scala.util.Failure(new Exception("Parser failed: "+msg + "remaining: "+ remaining.source.toString.drop(remaining.offset)))
case Error(msg,_) => scala.util.Failure(new Exception(msg))
}
private def expression: Parser[_ <: Expression] =
andExpr | falseExpr | trueExpr
private def falseExpr: Parser[FalseExpr] =
"false" ^^ (_ => FalseExpr())
private def trueExpr: Parser[TrueExpr] = "true" ^^ (_ => TrueExpr())
private def andExpr: Parser[Expression] =
expression ~ "and" ~ expression ^^ { case e1 ~ and ~ e2 => AndExpression(e1,e2)}
}
没有'and'解析,它工作正常。但我希望能够解析诸如“真与(假或真)”之类的东西,例如。当我将“和”部分添加到表达式的定义中时,我得到一个 StackOverflowError,堆栈在“和”和“表达式”的定义之间交替。
我理解为什么会发生这种情况 - 表达式的定义以 and 开头,反之亦然。但这似乎是对这个问题建模的最自然的方法。实际上,表达式也可以是 LIKE、EQUALS 等。为了解决递归定义的问题,是否有另一种方法可以对这类事物进行建模。
【问题讨论】:
标签: scala parser-combinators left-recursion