Scala 언어에서 지원하는 매력적인 라이브러리가 있는데, 그 중 하나가 Parser Combinator 이다. 이 라이브러리를 이용하면, Parser 를 작성하기가 쉽고, 소스가 이해하기도 쉽다. 그러므로 유지보수도 쉬워진다.
그래서 연습삼아서 계산기 프로그램을 작성해 보았다.
간단하게 사칙연산을 지원하고 숫자는 자연수, 정수, 소수(floating point number) 까지만 지원된다.
소스는 아래와 같다.
package parser
import util.parsing.combinator.JavaTokenParsers
/**
* User: starblood
* Date: 8/1/11
* Floating point 를 계산하는 프로그램.
* Scala 언어에서 지원하는 Parser Combinator library 를 사용하여 간단 하게 구현함.
* 표현식은 부동소숫점을 나타내는 숫자들의 사칙연산 (곱하기, 나누기, 더하기, 빼기) 와 괄호("(", ")") 가 지원됨.
*
* 문법은 아래와 같다.
* expr := term , {("+" , term | "-" , term)}
* term := factor , {("*" , factor | "*" , factor)}
* factor := "(" , expr , ")" | floatingPointNumber
*/
object ExprParser extends JavaTokenParsers {
def expr : Parser[Double] = term ~! rep("+" ~! term | "-" ~! term) ^^ {
case term~termList => {
termList.foldLeft(term){(acc, termExpr) =>
termExpr match {
case "+"~trm => acc + trm
case "-"~trm => acc - trm
}
}
}
}
def term : Parser[Double] = factor ~! rep("*" ~! factor | "/" ~! factor) ^^ {
case factor~factorList => {
factorList.foldLeft(factor){(acc, facExpr) =>
facExpr match {
case "*"~fac => acc * fac
case "/"~fac => acc / fac
}
}
}
}
def factor : Parser[Double] = "(" ~! expr ~! ")" ^^ {case "("~expr~")" => expr} |
floatingPointNumber ^^ {case floatingPointNumber => floatingPointNumber.toDouble}
def main(args: Array[String]) {
val str = "(5 - 1) * (3 + 2)"
println(parseAll(expr, str)) // 결과 출력
}
}
'Programming > Scala' 카테고리의 다른 글
Scala - Pattern matching example 2 (Scala 언어로 패턴 매칭하기) (0) | 2011.11.10 |
---|---|
Scala - Creating IntelliJ Scala project using sbt (sbt 를 이용하여 IntelliJ 용 Scala project 생성하기) (0) | 2011.11.10 |
Scala - Pattern matching (0) | 2011.11.10 |
Scala - IDE recommendation (scala 를 위한 개발 IDE 추천) (0) | 2011.11.10 |
Scala - syntax highlighting for vi vim (0) | 2011.11.10 |