--- 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")))