加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何使scala解析器失败

发布时间:2020-12-16 08:58:56 所属栏目:安全 来源:网络整理
导读:所以我有这样的事情: 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) }} 我的问题是,我真正想做的是
所以我有这样的事情:

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)
    }
}

我的问题是,我真正想做的是让解析器stored_val失败,以便其他解析器有机会匹配输入.但现在发生的是,当地图无法找到值时,它会抛出.

我尝试像这样实现stored_val:

def stored_val = ident => {
    case k => if (m.contains(k)) m(k) else failure("identifier not found")
}

但问题是失败返回Parser [Nothing],它与String不同.

解决方法

如果要查看正则表达式以外的字符内容,可能需要查看 StandardTokenParser.特别是

def elem (kind: String,p: (Elem) ? Boolean) : Parser[Elem]

A parser matching input elements that satisfy a given predicate
elem(kind,p) succeeds if the input starts with an element e' for which p(e) is true.

编辑:
有关标准令牌解析器的示例,请查看Jim McBeath关于Scala Parser Combinators的文章.我对第一个示例进行了快速修改以演示elem.这是一个简单的解析器,只需要奇数的总和:

import scala.util.parsing.combinator.syntactical._
import scala.util.parsing.combinator._

trait Expression
case class EConstant(value: Int) extends Expression
case class EAdd(lhs: Expression,rhs: Expression) extends Expression

object ExpressionParser extends StandardTokenParsers {
  lexical.delimiters ++= List("+")

  def oddValue = elem("odd",{ x => x.toString.toInt % 2 == 1 }) ^^ {
    x => EConstant(x.toString.toInt) }
  def value = numericLit ^^ { x => EConstant(x.toInt) }

  def sum = oddValue ~ "+" ~ oddValue ^^ { case left ~ "+" ~ right =>
          EAdd(left,right) }

  def expr = ( sum | value )

  def parse(s:String) = {
    val tokens = new lexical.Scanner(s)
    phrase(expr)(tokens)
  }

  def apply(s:String): Expression = parse(s) match {
    case Success(tree,_) => tree
    case e: NoSuccess =>
      throw new IllegalArgumentException("Bad syntax: "+s)
  }
}

将上面保存为ExpressionParser.scala并将其加载到REPL中,如下所示:

scala> :l ExpressionParser.scala     
Loading ExpressionParser.scala...
import scala.util.parsing.combinator.syntactical._
import scala.util.parsing.combinator._
defined trait Expression
defined class EConstant
defined class EAdd
defined module ExpressionParser

scala> ExpressionParser("2 + 2")
java.lang.IllegalArgumentException: Bad syntax: 2 + 2
    at ExpressionParser$.apply(<console>:42)
    at .<init>(<console>:24)
    at .<clinit>(<console>)
    at RequestResult$.<init>(<console>:9)
    at RequestResult$.<clinit>(<console>)
    at RequestResult$scala_repl_result(<console>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$17.apply(Interpreter.scala:988)
    at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$17.apply(Interpreter.scala:988)
    at scala.util.con...
scala> ExpressionParser("1 + 1")
res3: Expression = EAdd(EConstant(1),EConstant(1))

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读