如何让这个简单的正则表达式解析器捕捉布尔表达式?
How to get this simple regex-parser to catch a Boolean expression?
我试图用 Scala 理解解析器组合器,并编写了以下内容:
import scala.util.parsing.combinator._
class SimpleParser extends RegexParsers {
def operand: Parser[String] = "[A-Za-z]+".r ^^ {_.toString}
def operator: Parser[String] = "OR|AND".r ^^ {_.toString}
def term: Parser[String] = (("(" ~> (operand ~ operator ~ operand) <~ ")")) ^^ {
case o1 ~ operator ~ o2 => o1 + " " + operator + " " + o2
case _ => " "
}
def expression: Parser[String] = (operand | term | (operand ~ operator ~ term))^^ {
case str:String => str
case operand ~ operator ~ term => operand + " " + operator + " " + term
}
}
object ParserTest extends SimpleParser{
def main(args: Array[String]): Unit = {
println(parseAll(expression, "A").get)
println(parseAll(expression, "(A OR C)").get)
println(parseAll(expression, "A AND (A OR C)").get)
}
}
前两幅作品找到,而最后一幅导致:
Exception in thread "main" java.lang.RuntimeException: No result when parsing failed at scala.sys.package$.error(package.scala:27)
at scala.util.parsing.combinator.Parsers$NoSuccess.get(Parsers.scala:181)
at scala.util.parsing.combinator.Parsers$NoSuccess.get(Parsers.scala:167)
at ParserTest$.main(ParserTest.scala:31)
at ParserTest.main(ParserTest.scala)
我认为最后一句话会匹配 "expression" 中的(操作数 ~ 运算符 ~ 术语)模式。有人可以向我解释为什么我的模式是错误的,并且可以显示 write 模式以匹配最后的 print 语句吗?
首先,您没有正确处理 parseAll
的结果。如果你是,你会看到在最后一个例子中,它返回了一个 Failure
和消息
[1.3] failure: end of input expected
A AND (B OR C)
^
这里的问题是你的解析器在 expression
中的顺序错误。
创建解析器的析取 (uisng |
) 时,您始终必须从 "greediest" 解析器开始。换句话说,这里发生的是 operand
本身成功解析了 "A" 并且解析结束。但是parseAll
看到解析成功了但是还有输入,所以returns出现上面的错误。
如果你颠倒 3 个解析器的顺序,那么它看起来像:
def expression: Parser[String] = ((operand ~ operator ~ term) | term | operand)^^
它们现在已正确排序,所有 3 个示例都有效。
我试图用 Scala 理解解析器组合器,并编写了以下内容:
import scala.util.parsing.combinator._
class SimpleParser extends RegexParsers {
def operand: Parser[String] = "[A-Za-z]+".r ^^ {_.toString}
def operator: Parser[String] = "OR|AND".r ^^ {_.toString}
def term: Parser[String] = (("(" ~> (operand ~ operator ~ operand) <~ ")")) ^^ {
case o1 ~ operator ~ o2 => o1 + " " + operator + " " + o2
case _ => " "
}
def expression: Parser[String] = (operand | term | (operand ~ operator ~ term))^^ {
case str:String => str
case operand ~ operator ~ term => operand + " " + operator + " " + term
}
}
object ParserTest extends SimpleParser{
def main(args: Array[String]): Unit = {
println(parseAll(expression, "A").get)
println(parseAll(expression, "(A OR C)").get)
println(parseAll(expression, "A AND (A OR C)").get)
}
}
前两幅作品找到,而最后一幅导致:
Exception in thread "main" java.lang.RuntimeException: No result when parsing failed at scala.sys.package$.error(package.scala:27)
at scala.util.parsing.combinator.Parsers$NoSuccess.get(Parsers.scala:181)
at scala.util.parsing.combinator.Parsers$NoSuccess.get(Parsers.scala:167)
at ParserTest$.main(ParserTest.scala:31)
at ParserTest.main(ParserTest.scala)
我认为最后一句话会匹配 "expression" 中的(操作数 ~ 运算符 ~ 术语)模式。有人可以向我解释为什么我的模式是错误的,并且可以显示 write 模式以匹配最后的 print 语句吗?
首先,您没有正确处理 parseAll
的结果。如果你是,你会看到在最后一个例子中,它返回了一个 Failure
和消息
[1.3] failure: end of input expected
A AND (B OR C)
^
这里的问题是你的解析器在 expression
中的顺序错误。
创建解析器的析取 (uisng |
) 时,您始终必须从 "greediest" 解析器开始。换句话说,这里发生的是 operand
本身成功解析了 "A" 并且解析结束。但是parseAll
看到解析成功了但是还有输入,所以returns出现上面的错误。
如果你颠倒 3 个解析器的顺序,那么它看起来像:
def expression: Parser[String] = ((operand ~ operator ~ term) | term | operand)^^
它们现在已正确排序,所有 3 个示例都有效。