diff options
Diffstat (limited to 'docs/examples/parsing/lambda/TestParser.scala')
-rwxr-xr-x | docs/examples/parsing/lambda/TestParser.scala | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/docs/examples/parsing/lambda/TestParser.scala b/docs/examples/parsing/lambda/TestParser.scala new file mode 100755 index 0000000000..92d370c29b --- /dev/null +++ b/docs/examples/parsing/lambda/TestParser.scala @@ -0,0 +1,68 @@ +package examples.parsing.lambda + +import scala.util.parsing.input.Reader +import scala.util.parsing.combinator.lexical.StdLexical +import scala.util.parsing.combinator.syntactical.StdTokenParsers +import scala.util.parsing.combinator.ImplicitConversions + +/** + * Parser for an untyped lambda calculus + * + * @author Miles Sabin (adapted slightly by Adriaan Moors) + */ +trait TestParser extends StdTokenParsers with ImplicitConversions with TestSyntax +{ + type Tokens = StdLexical + val lexical = new StdLexical + lexical.reserved ++= List("unit", "let", "in", "if", "then", "else") + lexical.delimiters ++= List("=>", "->", "==", "(", ")", "=", "\\", "+", "-", "*", "/") + + + def name : Parser[Name] = ident ^^ Name + + // meaning of the argumens to the closure during subsequent iterations + // (...(expr2 op1 expr1) ... op1 expr1) + // ^a^^^ ^o^ ^b^^^ + // ^^^^^^^a^^^^^^^ ^o^ ^^b^^ + def expr1 : Parser[Term] = + chainl1(expr2, expr1, op1 ^^ {o => (a: Term, b: Term) => App(App(o, a), b)}) + + def expr2 : Parser[Term] = + chainl1(expr3, expr2, op2 ^^ {o => (a: Term, b: Term) => App(App(o, a), b)}) + + def expr3 : Parser[Term] = + chainl1(expr4, expr3, op3 ^^ {o => (a: Term, b: Term) => App(App(o, a), b)}) + + def expr4 : Parser[Term] = + ( "\\" ~ lambdas + | "let" ~ name ~ "=" ~ expr1 ~ "in" ~ expr1 ^^ flatten3(Let) + | "if" ~ expr1 ~ "then" ~ expr1 ~ "else" ~ expr1 ^^ flatten3(If) + | chainl1(aexpr, success(App(_: Term, _: Term))) + ) + + def lambdas : Parser[Term] = + name ~ ("->" ~ expr1 | lambdas) ^^ flatten2(Lam) + + def aexpr : Parser[Term] = + ( numericLit ^^ (_.toInt) ^^ Lit + | name ^^ Ref + | "unit" ^^ Unit + | "(" ~ expr1 ~ ")" + ) + + def op1 : Parser[Term] = + "==" ^^ Ref(Name("==")) + + def op2 : Parser[Term] = + ( "+" ^^ Ref(Name("+")) + | "-" ^^ Ref(Name("-")) + ) + + def op3 : Parser[Term] = + ( "*" ^^ Ref(Name("*")) + | "/" ^^ Ref(Name("/")) + ) + + def parse(r: Reader[char]) : ParseResult[Term] = + phrase(expr1)(new lexical.Scanner(r)) +} |