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) で書かれた入力として?

そのような入力を評価するには、リフレクションまたは同様のもの*を使用する必要がありますか? 研究すべきソース コードの推奨事項はありますか (グルーヴィーなソースでしょうか?)。

おそらくこれは似たようなものです: runtime compilationですが、これが最良の代替手段であるかどうかはわかりません。

編集

「{」と「}」を使用して以下の回答を完成させてください。「{{」の方がいいかもしれません。

4

2 に答える 2

0

そのようなインポートステートメントの意味がどうあるべきかという問題です。

おそらく、最初に言語で Java メソッドへの参照を許可することから始めます (ラムダ計算だと思いますか?)。

例えば:

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 コードを実行する方法を管理しました。

Scala コードへの DSL 変数の挿入と戻り値の回復はおまけです。:)

構文解析と解釈から組み込み 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 に答える