유일한 방법은 가져 오기에서 지정한 파일을 열고 구문 분석하는 것입니다. 여기에서 모듈에 대한 하위 표현식 트리를 작성할 수 있습니다. 예를 들어, ^^
및/또는 ^^^
을 사용하여 고유 한 표현식을 반환하는 경우 트리 내에서 올바른 위치에 관련 표현식을 간단하게 내보낼 수 있어야합니다. 예를 들어 구문 분석 할 때 수동으로 트리를 병합하지 않아도됩니다. :
import scala.util.parsing.combinator.syntactical.StandardTokenParsers
import scala.io.Source
object Example {
sealed trait Expr
case class Imports(modules: List[Module]) extends Expr
case class Module(modulePath: String, root: Option[Expr]) extends Expr
case class BracedExpr(x: String, y: String) extends Expr
case class Main(imports: Imports, braced: BracedExpr) extends Expr
class BlahTest extends StandardTokenParsers {
def importExpr: Parser[Module] = "import" ~> "\"" ~> stringLit <~ "\"" ^^ {
case modulePath =>
//you could use something other than `expr` below if you
//wanted to limit the expressions available in modules
//e.g. you could stop one module importing another.
phrase(expr)(new lexical.Scanner(Source.fromFile(modulePath).mkString)) match {
case Success(result, _) =>
Module(modulePath, Some(result))
case failure : NoSuccess =>
//TODO log or act on failure
Module(modulePath, None)
}
}
def prologExprs = rep(importExpr) ^^ {
case modules =>
Imports(modules)
}
def bracedExpr = "{" ~> stringLit ~ "," ~ stringLit <~ "}" ^^ {
case x ~ "," ~ y =>
BracedExpr(x, y)
}
def bodyExprs = bracedExpr
def expr = prologExprs ~ bodyExprs ^^ {
case prolog ~ body =>
Main(prolog, body)
}
}
}
당신은 단순히 각각의 서브 클래스에 필요한 평가 및 다음 방문자가 재귀 AST를 내려 구현, 당신의 표현 특성에 eval
을 추가 할 수 있습니다. 이 방식으로 수식 트리를 수동으로 병합 할 필요가 없습니다.
아, 고마워. 제 생각에는이 일을 할 수 있다고 생각합니다. BTW, 나는 당신이 importExpr에서 이스케이프 된 따옴표가 필요하다고 생각하지 않습니까? stringLit은 이미 따옴표를 고려하지 않습니까? – melston
예, 실제로는 importExpr에 이스케이프 된 따옴표가 필요하지 않습니다. 'stringLit'은 실제로 그것을 포함하고 버립니다. 사과를하면 코드를 작성했을 때 꽤 늦었습니다. 따라서'importExpr'은 아래와 같이 시작될 수 있습니다 : 'def importExpr : 파서 [Module] = "import"~> stringLit ^^' – adamretter