parser2.scala
changeset 71 7717f20f0504
parent 64 2d625418c011
--- 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")))