Skip to content

Instantly share code, notes, and snippets.

@kmizu
Forked from kishida/MiniParser.scala
Created November 14, 2011 16:22
Show Gist options
  • Save kmizu/1364341 to your computer and use it in GitHub Desktop.
Save kmizu/1364341 to your computer and use it in GitHub Desktop.
Toy language with parser combinators of scala, which is derived from Kishida-san's code. Original language has dynamic scope. But It has static scope and so-called lexical closure.
package miniparser
import scala.util.parsing.combinator.RegexParsers
object Main {
def main(args: Array[String]): Unit = {
val parser = new MiniParser
println(parser.parse("12-5*3+7*(2+5)+0"))
}
trait AST
case class AddOp(left: AST, right:AST) extends AST
case class SubOp(left: AST, right:AST) extends AST
case class MulOp(left: AST, right:AST) extends AST
case class IntVal(value: Int) extends AST
class MiniParser extends RegexParsers{
//expr ::= add
def expr: Parser[AST] = add
//expr ::= term {"+" term | "-" term}.
def add: Parser[AST] = term~rep("+"~term|"-"~term)^^{
case left~rest => {
var ast = left
rest.foreach{
case "+"~right => {ast = AddOp(ast, right)}
case "-"~right => {ast = SubOp(ast, right)}
}
ast
}
}
//term ::= factor {"*" factor}
def term : Parser[AST] = factor~rep("*"~factor)^^{
case left~rest => {
var ast = left
rest.foreach{
case _~right => {ast = MulOp(ast, right)}
}
ast
}
}
//factor ::= intLiteral | "(" expr ")"
def factor: Parser[AST] = intLiteral | "("~expr~")"^^{
case _~exp~_ => exp
}
//intLiteral ::= ["1"-"9"] {"0"-"9"}
def intLiteral : Parser[AST] = """[1-9][0-9]*|0""".r^^{
case value => IntVal(value.toInt)
}
def parse(str:String) = parseAll(expr, str)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment