Skip to content

Instantly share code, notes, and snippets.

@dpp
Created October 13, 2011 14:24
Show Gist options
  • Save dpp/1284334 to your computer and use it in GitHub Desktop.
Save dpp/1284334 to your computer and use it in GitHub Desktop.
Sample Parser Combinator shown at Scala Lift Off London 2011 #scalalol
import scala.util.parsing.combinator._
trait RunParser {
this: RegexParsers =>
type RootType
def root: Parser[RootType]
def run(in: String): ParseResult[RootType] = parseAll(root, in)
}
val vars = Map("a" -> 4d, "pi" -> 3.1415d)
object Calc extends JavaTokenParsers with RunParser {
lazy val sumExpr = prodExpr ~
rep("+" ~> prodExpr ^^ (d => (x: Double) => x + d) |
"-" ~> prodExpr ^^ (d => (x: Double) => x - d)) ^^ {
case seed ~ fs => fs.foldLeft(seed)((a, f) => f(a))
}
lazy val prodExpr = factor ~
rep("*" ~> factor ^^ (d => (x: Double) => x * d) |
"/" ~> factor ^^ (d => (x: Double) => x / d)) ^^ {
case seed ~ fs => fs.foldLeft(seed)((a, f) => f(a))
}
lazy val letters: Parser[String] = "[a-zA-Z]+".r
lazy val variable: Parser[Double] = "$" ~> letters ^^ ((chars: String) => vars(chars))
lazy val factor: Parser[Double] =
variable |
floatingPointNumber ^^ (_.toDouble) | "(" ~> sumExpr <~ ")"
type RootType = Double
def root = sumExpr
}
println(Calc.run("1 + 5 * $pi"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment