0

我不知道此信息是否与问题相关,但我正在学习 Scala 解析器组合器。使用一些示例(在本硕士论文中),我能够编写一种简单的函数式(在某种意义上它是非命令式的)编程语言。

有没有办法改进我的解析器/评估器,以便它可以允许/评估这样的输入:

<%
import scala.<some package / classes>
import weka.<some package / classes>
%>

some DSL code (lambda calculus)

<%
System.out.println("asdasd");
J48 j48 = new J48();
%>

作为用访客语言 (DSL) 编写的输入?

我应该使用反射或类似的东西*来评估这样的输入吗?是否有一些源代码推荐可供研究(可能是 groovy 源?)?

也许这是类似的东西:运行时编译,但我不确定这是最好的选择。

编辑

下面用“{”和“}”给出完整答案。也许“{{”会更好。

4

2 回答 2

0

问题在于此类导入语句的含义应该是什么。

也许您首先允许在您的语言中引用 java 方法(我猜是 Lambda 演算?)。

例如:

java.lang.System.out.println "foo"

如果有,则可以添加不合格名称的解析,例如

println "foo"

但是第一个问题来了:println存在于System.out和System.err中,或者更准确的说:它是PrintStream的一个方法,而System.err和System.out都是PrintStreams。

因此,您需要一些有关对象、类、类型等的概念才能正确执行此操作。

于 2013-01-19T17:45:37.197 回答
0

我管理了如何运行嵌入在我解释的 DSL 中的 Scala 代码。

将 DSL 变量插入 Scala 代码并恢复返回值是一个好处。:)

从解析和解释到执行嵌入式 Scala 代码运行时执行(Main Parser AST 和 Interpreter)的最少相关代码:

object Main extends App {
     val ast = Parser1 parse "some dsl code here"
     Interpreter eval ast
}

object Parser1 extends RegexParsers with ImplicitConversions {
  import AST._
  val separator = ";"
  def parse(input: String): Expr = parseAll(program, input).get
  type P[+T] = Parser[T]
  def program = rep1sep(expr, separator) <~ separator ^^ Sequence
  def expr: Parser[Expr] = (assign /*more calls here*/)
  def scalacode: P[Expr] = "{" ~> rep(scala_text) <~ "}" ^^ {case l => Scalacode(l.flatten)}
  def scala_text = text_no_braces ~ "$" ~ ident ~ text_no_braces ^^ {case a ~ b ~ c ~ d => List(a, b + c, d)}
  //more rules here
  def assign = ident ~ ("=" ~> atomic_expr) ^^ Assign
  //more rules here
  def atomic_expr = (
     ident ^^ Var
        //more calls here 
        | "(" ~> expr <~ ")"
        | scalacode
        | failure("expression expected")
     )
  def text_no_braces = """[a-zA-Z0-9\"\'\+\-\_!@#%\&\(\)\[\]\/\?\:;\.\>\<\,\|= \*\\\n]*""".r //| fail("Scala code expected")
  def ident = """[a-zA-Z]+[a-zA-Z0-9]*""".r
}

object AST {
   sealed abstract class Expr
   // more classes here
   case class Scalacode(items: List[String]) extends Expr
   case class Literal(v: Any) extends Expr
   case class Var(name: String) extends Expr
}

object Interpreter {
  import AST._
  val env = collection.immutable.Map[VarName, VarValue]()
  def run(code: String) = {
     val code2 = "val res_1 = (" + code + ")"
     interpret.interpret(code2)
     val res = interpret.valueOfTerm("res_1")
     if (res == None) Literal() else Literal(res.get)
  }

  class Context(private var env: Environment = initEnv) {
    def eval(e: Expr): Any = e match {
       case Scalacode(l: List[String]) => {
          val r = l map {
             x =>
                if (x.startsWith("$")) {
                   eval(Var(x.drop(1)))
                } else {
                   x
                }
          }
          eval(run(r.mkString))
       }
       case Assign(id, expr) => env += (id -> eval(expr))
       //more pattern matching here
       case Literal(v) => v
       case Var(id) => {
          env getOrElse(id, sys.error("Undefined " + id))
       }
     }
    }  
  }
于 2013-02-02T18:02:31.967 回答