所以我有这样的事情:
class MyParser extends JavaTokenParsers {
var m = new HashMap[String,String]
def store = ("var" ~> ident "=") ~ ident ^^ {
case k ~ v => m += k -> v
}
def stored_val = ident ^^ {
case k => m(k)
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是我真正想做的是让解析器stored_val失败,以便其他解析器有机会匹配输入.但现在发生的是当地图无法找到值时会抛出.
我尝试像这样实现stored_val:
def stored_val = ident => {
case k => if (m.contains(k)) m(k) else failure("identifier not found")
}
Run Code Online (Sandbox Code Playgroud)
但问题是失败返回Parser [Nothing],它与String不同.
小智 8
您可以使用^?接受部分函数的组合子(Scaladoc):
def stored_val: Parser[String] = ident ^? {
case k if m.contains(k) => m(k)
}
Run Code Online (Sandbox Code Playgroud)
如果您想检查正则表达式之外的字符内容,您可能需要查看StandardTokenParser. 尤其,
def elem (kind: String, p: (Elem) \xe2\x87\x92 Boolean) : Parser[Elem]\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n如果输入以true元素开头,则匹配满足给定谓词的输入元素的解析器\n 会
\nelem(kind, p)成功。e\'p(e)
编辑:\n有关标准令牌解析器的示例,请查看 Jim McBeath 关于Scala 解析器组合器的文章。我对第一个示例进行了快速修改以进行演示elem。这是一个简单的解析器,只需要奇数的和:
import scala.util.parsing.combinator.syntactical._\nimport scala.util.parsing.combinator._\n\ntrait Expression\ncase class EConstant(value: Int) extends Expression\ncase class EAdd(lhs: Expression, rhs: Expression) extends Expression\n\nobject ExpressionParser extends StandardTokenParsers {\n lexical.delimiters ++= List("+")\n\n def oddValue = elem("odd", { x => x.toString.toInt % 2 == 1 }) ^^ {\n x => EConstant(x.toString.toInt) }\n def value = numericLit ^^ { x => EConstant(x.toInt) }\n\n def sum = oddValue ~ "+" ~ oddValue ^^ { case left ~ "+" ~ right =>\n EAdd(left, right) }\n\n def expr = ( sum | value )\n\n def parse(s:String) = {\n val tokens = new lexical.Scanner(s)\n phrase(expr)(tokens)\n }\n\n def apply(s:String): Expression = parse(s) match {\n case Success(tree, _) => tree\n case e: NoSuccess =>\n throw new IllegalArgumentException("Bad syntax: "+s)\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n将以上内容保存为ExpressionParser.scala并加载到 REPL 中,如下所示:
scala> :l ExpressionParser.scala \nLoading ExpressionParser.scala...\nimport scala.util.parsing.combinator.syntactical._\nimport scala.util.parsing.combinator._\ndefined trait Expression\ndefined class EConstant\ndefined class EAdd\ndefined module ExpressionParser\n\nscala> ExpressionParser("2 + 2")\njava.lang.IllegalArgumentException: Bad syntax: 2 + 2\n at ExpressionParser$.apply(<console>:42)\n at .<init>(<console>:24)\n at .<clinit>(<console>)\n at RequestResult$.<init>(<console>:9)\n at RequestResult$.<clinit>(<console>)\n at RequestResult$scala_repl_result(<console>)\n at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)\n at java.lang.reflect.Method.invoke(Method.java:597)\n at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$17.apply(Interpreter.scala:988)\n at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$17.apply(Interpreter.scala:988)\n at scala.util.con...\nscala> ExpressionParser("1 + 1")\nres3: Expression = EAdd(EConstant(1),EConstant(1))\nRun Code Online (Sandbox Code Playgroud)\n