我正在尝试使用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)
我认为最后一句话与“表达式”中的(操作数〜运算符〜术语)模式相匹配。有人可以解释我为什么我的模式是错误的,也许可以显示写一个匹配最后一个打印语句?
答案 0 :(得分:3)
首先,您没有正确处理Failure
的结果。如果你是,你会在最后一个例子中看到它返回[1.3] failure: end of input expected
A AND (B OR C)
^
并带有消息
expression
这里的问题是你的解析器在|
内的顺序错误。
当创建解析器的分离(uisng operand
)时,你总是必须从“最贪婪”的解析器开始。换句话说,这里发生的是parseAll
本身正在成功解析“A”并解析结束。但是,def expression: Parser[String] = ((operand ~ operator ~ term) | term | operand)^^
看到解析已成功但仍有输入,因此它返回上述错误。
如果颠倒3个解析器的顺序,它看起来像:
public float getValue(int id, float num1, float num2){
float result = 0.0;
switch (id) {
case R.id.btnAdd:
oper = "+";
result = num2 + num2;
break;
case R.id.btnSub:
oper = "-";
result = num1 - num2;
break;
case R.id.btnMult:
oper = "*";
result = num1 * num2;
break;
case R.id.btnDiv:
oper = "/";
result = num1 / num2;
break;
default:
break;
}
return result;
}
现在它们已正确订购,所有3个示例都有效。