Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有递归结构的Scala解析器组合器_Scala - Fatal编程技术网

具有递归结构的Scala解析器组合器

具有递归结构的Scala解析器组合器,scala,Scala,我是Scala的初学者,现在学习Scala解析器组合器,编写“MiniLogicParser”,一个命题逻辑公式的迷你解析器。我成功地对其进行了部分解析,但无法转换为case类。我试过下面的代码 import java.io._ import scala.util.parsing.combinator._ sealed trait Bool[+A] case object True extends Bool[Nothing] case class Var[A](label: A) extend

我是Scala的初学者,现在学习Scala解析器组合器,编写“MiniLogicParser”,一个命题逻辑公式的迷你解析器。我成功地对其进行了部分解析,但无法转换为case类。我试过下面的代码

import java.io._
import scala.util.parsing.combinator._

sealed trait Bool[+A]
case object True extends Bool[Nothing]
case class Var[A](label: A) extends Bool[A]
case class Not[A](child: Bool[A]) extends Bool[A]
case class And[A](children: List[Bool[A]]) extends Bool[A]

object LogicParser extends RegexParsers {
  override def skipWhitespace = true

  def formula = ( TRUE | not | and | textdata )
  def TRUE  = "TRUE"
  def not : Parser[_] = NEG ~ formula  ^^ {case ( "!"  ~ formula) => Not(formula)}
  def and : Parser[_] = LPARENTHESIS ~ formula ~ opt(CONJUNCT ~ formula) ~ RPARENTHESIS
  def NEG = "!"
  def CONJUNCT = "&&"
  def LPARENTHESIS = '('
  def RPARENTHESIS = ')'
  def textdata = "[a-zA-Z0-9]+".r

  def apply(input: String): Either[String, Any] = parseAll(formula, input) match {
      case Success(logicData, next)        => Right(logicData)
      case NoSuccess(errorMessage, next) => Left(s"$errorMessage on line ${next.pos.line} on column ${next.pos.column}")
    }
}
但是,编译失败,出现以下错误消息

[error] ... MiniLogicParser.scala:15 type mismatch;  
[error]  found : Any 
[error]  required: Bool[?]  
[error]  def not : Parser[_] = NEG ~ formula  ^^ {case ( "!"  ~ formula) => Not(formula)}

我能部分理解错误信息;i、 例如,这意味着对于第15行,我试图将解析结果转换为case类,类型不匹配正在发生。但是,我不知道如何修复此错误。

非-节点的子节点类型为
Bool
。但是,在第15行中,
公式
,您要传递给
Not
apply
方法的值的类型为
Any
。通过在冒号后面添加类型信息,可以限制提取器(即
case
-语句)仅匹配
公式
类型为
Bool
的值:

case ( "!"  ~ (formula: Bool[_]))
因此,
not
方法如下所示:

def not : Parser[_] = NEG ~ formula  ^^ {case ( "!"  ~ (formula: Bool[_])) => Not(formula)}
但是,现在,例如,
“!TRUE”
不再匹配,因为
“TRUE”
还不是
Bool
类型。可以通过扩展解析器将字符串转换为
Bool
,例如

def TRUE  = "TRUE" ^^ (_ => True)

我对你的解析器做了一些修改

import scala.util.parsing.combinator._
sealed trait Bool[+A]
case object True extends Bool[Nothing]
case class Var[A](label: A) extends Bool[A]
case class Not[A](child: Bool[A]) extends Bool[A]
case class And[A](l: Bool[A], r: Bool[A]) extends Bool[A]


object LogicParser extends RegexParsers with App {
  override def skipWhitespace = true

  def NEG = "!"
  def CONJUNCT = "&&"
  def LP = '('
  def RP = ')'

  def TRUE = literal("TRUE") ^^ { case _ => True }
  def textdata = "[a-zA-Z0-9]+".r ^^ { case x => Var(x) }

  def formula: Parser[Bool[_]] = textdata | and | not | TRUE
  def not = NEG ~ formula ^^ { case n ~ f => Not(f) }
  def and = LP ~> formula ~ CONJUNCT ~ formula <~ RP ^^ { case f1 ~ c ~ f2 => And(f1, f2) }

  def apply(input: String): Either[String, Any] = parseAll(formula, input) match {
    case Success(logicData, next) => Right(logicData)
    case NoSuccess(errorMessage, next) => Left(s"$errorMessage on line ${next.pos.line} on column ${next.pos.column}")
  }

  println(apply("TRUE"))            // Right(Var(TRUE))
  println(apply("(A && B)"))        // Right(And(Var(A),Var(B)))
  println(apply("((A && B) && C)")) // Right(And(And(Var(A),Var(B)),Var(C)))
  println(apply("!(A && !B)"))      // Right(Not(And(Var(A),Not(Var(B)))))
}
导入scala.util.parsing.combinator_
密封特性布尔[+A]
case对象True扩展Bool[无]
案例类变量[A](标签:A)扩展布尔[A]
case类Not[A](child:Bool[A])扩展Bool[A]
case类和[A](l:Bool[A],r:Bool[A])扩展了Bool[A]
对象逻辑分析器使用App扩展RegexParsers{
覆盖def skipWhitespace=真
def NEG=“!”
def CONJUNCT=“&&”
def LP='('
def RP=')'
def TRUE=literal(“TRUE”)^{case}
def textdata=“[a-zA-Z0-9]+”.r^^{case x=>Var(x)}
def公式:解析器[Bool[|]]=textdata |和| not | TRUE
def not=NEG~公式^{案例n~f=>not(f)}
def and=LP~>公式~conconconcent~公式和(f1,f2)}
def apply(输入:字符串):要么[String,Any]=parseAll(公式,输入)匹配{
案例成功(logicData,下一个)=>Right(logicData)
case NoSuccess(errorMessage,next)=>Left(s“${next.pos.column}列的${next.pos.line}行上的$errorMessage”)
}
println(apply(“TRUE”)//Right(Var(TRUE))
println(apply(“(A&&B)”)//右(和(Var(A),Var(B)))
println(apply(((A&&B)&&C)//右(和(和(Var(A)、Var(B))、Var(C)))
println(apply(“!(A&&!B)”)//右(Not(And(Var(A)),Not(Var(Bщ)!)
}