Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.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_Parsing_Fastparse - Fatal编程技术网

Scala 分析结果时返回类型错误

Scala 分析结果时返回类型错误,scala,parsing,fastparse,Scala,Parsing,Fastparse,我正在解析python代码的解析结果以获得结果 项目结构: PythonParseProject build.sbt src main scala pyparse Ast.scala Lexical.scala Expressions.scala Statements.scala Main.scala 我使用fastparse库 buil

我正在解析python代码的解析结果以获得结果

项目结构:

PythonParseProject
  build.sbt
  src
    main
      scala
        pyparse
            Ast.scala
            Lexical.scala
            Expressions.scala
            Statements.scala 
        Main.scala
我使用fastparse库

build.sbt:

name := "PythonParser"

version := "0.1"

scalaVersion := "2.13.1"

libraryDependencies += "com.lihaoyi" %% "fastparse" % "2.1.3"
Main.scala:

import pyparse._

object Main extends App {

  import fastparse._

  var CODE =
    """
      |a = 5
      |b = "7"
      |def my_func(a):
      |    r = a * 2
      |    return r
      |if a > b:
      |    print(a)
      |else:
      |    print(b)
      |print(my_func(a))
      |print(my_func(a), a)
      |print(a)
      |print("qwewqeqwe")
      |print(123 + 3)
      |""".stripMargin
  CODE = CODE.replaceAll("\r", "")

  import fastparse.NoWhitespace._
  def parseIt[_: P] = Statements.file_input(P.current) ~ End
  val parsed = parse(CODE, parseIt(_))
  val stringResult = parsed match {
    case f: Parsed.Failure => throw new Exception(f.trace().longTerminalsMsg)
    case s: Parsed.Success[Seq[parsed]] => {
      val result = s.value

      import pyparse.Ast._

      var globalVars = Map("None" -> "None", "for" -> 0)

      class StringOrInt[T]
      object StringOrInt {
        implicit object IntWitness extends StringOrInt[Int]
        implicit object StringWitness extends StringOrInt[String]
      }

      def BinOp(left: expr, op: operator, right: expr) = {
        val l = left match {
          case expr.Num(n) => n
          case expr.Str(s) => s
          case expr.BinOp(left, op, right) => BinOp(left, op, right)
          case _ => println("BinOp. left match: что это: " + left + "?"); 0
        }
        val r = right match {
          case expr.Num(n) => n
          case expr.Str(s) => s
          case expr.BinOp(left, op, right) => BinOp(left, op, right)
          case _ => println("BinOp. right match: что это: " + right + "?")
        }
        val result = op match {
        /*
        Error: type mismatch;
          found   : Any
          required: String
            case operator.Add => l + r
         */
          case operator.Add => l + r
          case _ => println("BinOp. op match: что это: " + op + "?")
        }
        result
      }

      def Print(dest: Option[expr], values: Seq[expr], nl: bool): Unit = {
        values(0) match {
//          case expr.Num(n) => println(n)
//          case expr.Str(s) => println(s)
//          case expr.Name(id, ctx) => println(globalVars(id.name)) // а если не globalVars? Передавать сюда localVars?
//          case expr.Tuple(elts, ctx) => Nil
          case expr.BinOp(left, op, right) => println(BinOp(left, op, right))
          case _ => println("Print. values(0): что это: " + values(0) + "?")
        }
      }

      for (x <- result) {
        var res: Any = x match {
          case stmt.Print(dest, values, nl) => Print(dest, values, nl)
          case _ => 0
        }
      }

    }
  }

}
如何修复它

声明了一个混合类型“StringOrInt[T]”,但这没有帮助。

我的问题的解决方案

def BinOpInt(left: Int, op: operator, right: Int): Int = {
  op match {
    case operator.Add => left + right
    case operator.Sub => left - right
    case operator.Mult => left * right
    case operator.Div => left / right
    case operator.Mod => left % right
    case operator.Pow => math.pow(left, right).toInt
  }
}

def BinOpString(left: String, op: operator, right: String): String = {
  op match {
    case operator.Add => left + right
  }
}

def BinOpStringInt(left: String, op: operator, right: Int): String = {
  op match {
    case operator.Mult => left * right
  }
}

def BinOp(left: expr, op: operator, right: expr): Any = {
  val l = left match {
    case expr.Num(n) => n.toString.toInt
    case expr.Str(s) => s
    case expr.BinOp(left, op, right) => BinOp(left, op, right)
  }
  val r = right match {
    case expr.Num(n) => n.toString.toInt
    case expr.Str(s) => s
    case expr.BinOp(left, op, right) => BinOp(left, op, right)
  }

  l match {
    case n_left: Int =>
      r match {
        case n_right: Int => BinOpInt(n_left, op, n_right)
        case s_right: String => BinOpStringInt(s_right, op, n_left)  // first String!
      }
    case s_left: String =>
      r match {
        case n_right: Int => BinOpStringInt(s_left, op, n_right)
        case s_right: String => BinOpString(s_left, op, s_right)
      }
  }
}

你认为
l
r
的类型应该是什么?它们的案例返回非常不同的内容(包括
Unit
)。这不包括
l
r
类型为
BinOp
def BinOpInt(left: Int, op: operator, right: Int): Int = {
  op match {
    case operator.Add => left + right
    case operator.Sub => left - right
    case operator.Mult => left * right
    case operator.Div => left / right
    case operator.Mod => left % right
    case operator.Pow => math.pow(left, right).toInt
  }
}

def BinOpString(left: String, op: operator, right: String): String = {
  op match {
    case operator.Add => left + right
  }
}

def BinOpStringInt(left: String, op: operator, right: Int): String = {
  op match {
    case operator.Mult => left * right
  }
}

def BinOp(left: expr, op: operator, right: expr): Any = {
  val l = left match {
    case expr.Num(n) => n.toString.toInt
    case expr.Str(s) => s
    case expr.BinOp(left, op, right) => BinOp(left, op, right)
  }
  val r = right match {
    case expr.Num(n) => n.toString.toInt
    case expr.Str(s) => s
    case expr.BinOp(left, op, right) => BinOp(left, op, right)
  }

  l match {
    case n_left: Int =>
      r match {
        case n_right: Int => BinOpInt(n_left, op, n_right)
        case s_right: String => BinOpStringInt(s_right, op, n_left)  // first String!
      }
    case s_left: String =>
      r match {
        case n_right: Int => BinOpStringInt(s_left, op, n_right)
        case s_right: String => BinOpString(s_left, op, s_right)
      }
  }
}