diff -r e6868bd2942b -r 7717f20f0504 parser2.scala --- a/parser2.scala Wed Nov 21 09:04:11 2012 +0000 +++ b/parser2.scala Fri Nov 23 14:08:31 2012 +0000 @@ -1,18 +1,21 @@ -:load matcher.scala +// A naive version of parser combinators producing parse trees +// +// Needs +// :load matcher.scala // some regular expressions -val LETTER = RANGE("abcdefghijklmnopqrstuvwxyz".toList) +val LETTER = RANGE("abcdefghijklmnopqrstuvwxyz") val ID = PLUS(LETTER) -val DIGIT = RANGE("0123456789".toList) -val NONZERODIGIT = RANGE("123456789".toList) +val DIGIT = RANGE("0123456789") +val NONZERODIGIT = RANGE("123456789") val NUMBER = ALT(SEQ(NONZERODIGIT, STAR(DIGIT)), "0") val LPAREN = CHAR('(') val RPAREN = CHAR(')') -val WHITESPACE = PLUS(RANGE(" \n".toList)) -val OPS = RANGE("+-*".toList) +val WHITESPACE = PLUS(RANGE(" \n")) +val OPS = RANGE("+-*") // for classifying the strings that have been recognised abstract class Token @@ -27,13 +30,6 @@ case object T_THEN extends Token case object T_ELSE extends Token -def tokenizer(rs: List[Rule[Token]], s: String) : List[Token] = - tokenize(rs, s.toList).filterNot(_ match { - case T_WHITESPACE => true - case _ => false - }) - - // lexing rules for arithmetic expressions val lexing_rules: List[Rule[Token]]= List(("if", (s) => T_IF), @@ -46,6 +42,8 @@ (RPAREN, (s) => T_RPAREN), (OPS, (s) => T_OP(s.mkString))) +val Tok = Tokenizer(lexing_rules, List(T_WHITESPACE)) + // parse trees abstract class ParseTree @@ -115,8 +113,8 @@ lazy val T: Parser = (F ~ T_OP("*") ~ T) || F lazy val F: Parser = (T_LPAREN ~ E ~ T_RPAREN) || NumParser -tokenizer(lexing_rules, "1 + 2 + 3") -println(E.parse_all(tokenizer(lexing_rules, "1 + 2 + 3"))) +println(Tok.fromString("1 + 2 + 3")) +println(E.parse_all(Tok.fromString("1 + 2 + 3"))) def eval(t: ParseTree) : Int = t match { case Leaf(T_NUM(n)) => n.toInt @@ -125,17 +123,16 @@ case Branch(List(Leaf(T_LPAREN), t, Leaf(T_RPAREN))) => eval(t) } -(E.parse_all(tokenizer(lexing_rules, "1 + 2 + 3"))).map(eval(_)) -(E.parse_all(tokenizer(lexing_rules, "1 + 2 * 3"))).map(eval(_)) -(E.parse_all(tokenizer(lexing_rules, "(1 + 2) * 3"))).map(eval(_)) +(E.parse_all(Tok.fromString("1 + 2 + 3"))).map(eval(_)) +(E.parse_all(Tok.fromString("1 + 2 * 3"))).map(eval(_)) lazy val EXPR: Parser = new ListParser(List(T_IF, EXPR, T_THEN, EXPR)) || new ListParser(List(T_IF, EXPR, T_THEN, EXPR, T_ELSE, EXPR)) || IdParser -println(EXPR.parse_all(tokenizer(lexing_rules, "if a then b else c"))) -println(EXPR.parse_all(tokenizer(lexing_rules, "if a then if x then y else c"))) +println(EXPR.parse_all(Tok.fromString("if a then b else c"))) +println(EXPR.parse_all(Tok.fromString("if a then if x then y else c")))