Return 解析解析结果时出现类型错误

Return type error while parsing parsing results

我正在解析解析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
        }
      }

    }
  }

}

我正在反汇编 BinOp 操作。此 class 示例采用 3 个参数:left、op、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 + "?")
}

如何解决?

声明了混合类型 "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)
      }
  }
}