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 expr = "12-5*3+7*(2+5)*1+0"
val parser = new MiniParser
val ast = parser.parse(expr).get
val visitor = new ExprVisitor
var result = visitor.visit(ast);
println(result)
}
}
class ExprVisitor{
def visit(ast:AST):Any = {
ast match{
case AddOp(left, right) =>{
(visit(left), visit(right)) match{
case (lval:Int, rval:Int) => lval + rval
}
}
case SubOp(left, right) =>{
(visit(left), visit(right)) match{
case (lval:Int, rval:Int) => lval - rval
}
}
case MulOp(left, right) =>{
(visit(left), visit(right)) match{
case (lval:Int, rval:Int) => lval * rval
}
}
case IntVal(value) => value
}
}
}
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] = chainl1(term,
"+"^^{op => (left:AST, right:AST) => AddOp(left, right)}|
"-"^^{op => (left:AST, right:AST) => SubOp(left, right)})
//term ::= factor {"*" factor}
def term : Parser[AST] = chainl1(factor,
"*"^^{op => (left:AST, right:AST) => MulOp(left, right)})
//factor ::= intLiteral | "(" expr ")"
def factor: Parser[AST] = intLiteral | "("~>expr<~")"^^{
x=>x}
//intLiteral ::= ["1"-"9"] {"0"-"9"}
def intLiteral : Parser[AST] = """[1-9][0-9]*|0""".r^^{
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