我们正在为看起来像SQL的DSL构建解析器。就像在SQL中一样,它有多个块,即select,where,order by,group by等。我们使查询的某些部分像where,order by等可选。当我们这样做时,解析器会忽略所有输入错误。
DSL Code Snippet
case class Query(select: Select, where: Where)
case class Select(cols: Seq[String])
case class Where(conditions: Seq[String])
object QueryLanguage extends StandardTokenParsers {
lazy val sql: Parser[Query] = select_block ~ (where_block?) ^^ {case slct ~ whr => Query(slct, whr.getOrElse(null))}
lazy val select_block: Parser[Select] = "SELECT" ~> rep1sep(ident, ",") ^^ { case cols => Select(cols) }
lazy val where_block: Parser[Where] = "WHERE" ~> rep1sep(ident, "and") ^^ { case conds => Where(conds) }
}
报告选择块中的任何语法错误,但不报告其他块。这对于想要在查询中有where块但却无法在其定义中报告错误的人来说是令人沮丧的。
例如,如下所示的SQL只是忽略了WHERE子句而没有报告错误(注释和关键字拼写错误)
select A, B
WHERE a=1 andd b=2
如果我要修改输入中的拼写或在DSL中强制执行caluse,那么SQL会正确解析
lazy val sql: Parser[Query] = select ~ where ~ (orderby?)
是否有其他方法可以处理此问题或覆盖此默认行为?