我正在研究Scala中的解釋器,我需要找到一種方法來分配變量,名稱和可更新的值。示例輸入可能如下所示Scala解釋器
(x = x + 1) // results to: Assign("x",Plus(Var("x"),Num(1)))
任何想法或建議將不勝感激。
我正在研究Scala中的解釋器,我需要找到一種方法來分配變量,名稱和可更新的值。示例輸入可能如下所示Scala解釋器
(x = x + 1) // results to: Assign("x",Plus(Var("x"),Num(1)))
任何想法或建議將不勝感激。
下面是使用Scala的解析器組合器來解決這個問題的一個非常簡單的起點。你可以把這段代碼擴大到適合你的實際需求,但是這應該告訴你基本思想:
trait Expression
case class Plus(a: Expression, b: Expression) extends Expression
case class Var(name: String) extends Expression
case class Num(n: Int) extends Expression
trait Statement
case class Assign(v: String, ex: Expression) extends Statement
object StatementParser extends RegexParsers {
private def num: Parser[Num] = regex(new Regex("""(\d+)""")).map(n => Num(n.toInt))
private def identifier: Parser[String] = regex(new Regex("""([A-Za-z][A-Za-z0-9]*)"""))
private def variable: Parser[Var] = identifier.map(Var(_))
private def expression: Parser[Expression] = plus | variable | num
private def plus: Parser[Plus] = ("(" ~> expression ~ "+" ~ expression <~ ")").map { case (l ~ _ ~ r) => Plus(l, r) }
private def assign: Parser[Assign] = (identifier ~ "=" ~ expression).map { case (v ~ _ ~ ex) => Assign(v, ex) }
private def parse(str: String): ParseResult[Statement] = parse(assign, str)
def apply(str: String): Statement = parse(str) match {
case Success(result: Statement, _) => result
case _ => sys.error("Could not parse the input string: " + str)
}
}
val s = StatementParser("x = (x + 1)")
println(s) // Assign(x,Plus(Var(x),Num(1)))
'regex(new Regex(「x」))'可以寫成'「x」.r','p map f'可以寫成'p ^^ f',而不是'parse'應該使用如果整個輸入應該被解析(前者不會消耗尾隨字符),那麼不需要使用模式匹配的括號,'lazy val'代替'def'會更有效率,'p ^^(Var(_) )''只能寫成'p ^^ Var',而不是在錯誤時打印輸入字符串,這會更加明智地返回錯誤信息,一些空行對讀取流暢性會很好=> [result](https:/ /gist.github.com/3826030)。 – sschaef
問題是什麼? – sschaef