저는 스칼라에서 통역사로 일하고 있으며 변수, 이름 및 업데이트 할 수있는 값을 할당하는 방법을 찾아야합니다. 입력 예는 다음과 같을 수 있습니다.스칼라 인터프리터
(x = x + 1) // results to: Assign("x",Plus(Var("x"),Num(1)))
모든 의견이나 제안은 대단히 감사하겠습니다.
저는 스칼라에서 통역사로 일하고 있으며 변수, 이름 및 업데이트 할 수있는 값을 할당하는 방법을 찾아야합니다. 입력 예는 다음과 같을 수 있습니다.스칼라 인터프리터
(x = x + 1) // results to: Assign("x",Plus(Var("x"),Num(1)))
모든 의견이나 제안은 대단히 감사하겠습니다.
다음은 스칼라 파서 결합자를 사용하여이를 해결하는 간단한 시작점입니다. 이 코드를 사용하여 실제 필요에 맞게 확장 할 수 있지만 기본 아이디어가 표시되어야합니다.
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''는''pse'' 대신에''p ^^ f''로 쓸 수 있습니다. ''parseAll'은 전체 입력을 구문 분석해야한다면 (이전은 뒤 따르는 문자를 먹지 않습니다), 패턴 일치를 둘러싼 괄호는 불필요합니다.'def' 대신'lazy val'이 더 효율적입니다.'p ^^ (Var (_))'는'p ^^ Var'로만 쓰여질 수 있습니다. 오류시 입력 문자열을 출력하는 대신 오류 메시지를 반환하는 것이 더 현명합니다. 일부 빈 줄은 유창성을 읽기에 좋을 것입니다.> [result] (https : /) /gist.github.com/3826030). – sschaef
무엇이 문제입니까? – sschaef