scala - 解析解析结果时返回类型错误
问题描述
我正在解析解析python代码的结果以获得结果。
项目结构:
PythonParseProject
build.sbt
src
main
scala
pyparse
Ast.scala
Lexical.scala
Expressions.scala
Statements.scala
Main.scala
我使用 fastparse 库。
构建.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 操作。这个类样本有 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)
}
}
}
推荐阅读
- php - 使用“简单的 html 解析器”提取表数据
- javascript - 如何将这个改变不透明度的 SVG onclick 属性放入 VS2017
- regex - 如何将特定路径上文件的文件扩展名与正则表达式匹配?
- smartcard - 在 Windows 上使用来自 SmartCard 的密钥签署证书
- php - 无法发布 php 文件。是否有另一种方式(代码)将表单数据发送到我的电子邮件?
- vue.js - 如何在 vue 中定义一个全局方法?
- python - 类型错误:列表索引必须是整数或切片,而不是 str
- docker - 是否可以将应用服务的发布方法从代码转换为 Docker?
- database - 当另一个事务在当前事务之前提交时,PostgreSQL 会回滚吗?
- python - 使用python用HTML表单“发布”数据填写“可填写的pdf”?