diff options
author | Martin Odersky <odersky@gmail.com> | 2004-01-05 11:38:11 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2004-01-05 11:38:11 +0000 |
commit | 0adfc8d42abed2b4019a866672c497eb5d67e5b9 (patch) | |
tree | 11c3b94a1d6df352d313d0496275cd0dc7db23df /sources/examples/parsers1.scala | |
parent | 3b1253891b888c191e9b96d566b3eb304213eeee (diff) | |
download | scala-0adfc8d42abed2b4019a866672c497eb5d67e5b9.tar.gz scala-0adfc8d42abed2b4019a866672c497eb5d67e5b9.tar.bz2 scala-0adfc8d42abed2b4019a866672c497eb5d67e5b9.zip |
*** empty log message ***
Diffstat (limited to 'sources/examples/parsers1.scala')
-rw-r--r-- | sources/examples/parsers1.scala | 143 |
1 files changed, 69 insertions, 74 deletions
diff --git a/sources/examples/parsers1.scala b/sources/examples/parsers1.scala index bbd0a0dbe0..06e8ed0fe0 100644 --- a/sources/examples/parsers1.scala +++ b/sources/examples/parsers1.scala @@ -1,52 +1,49 @@ package examples; -trait Tree {} -case class Var(n: String) : Tree extends Tree {} -case class Num(n: Int) : Tree extends Tree {} -case class Binop(op: Char, l: Tree, r: Tree): Tree extends Tree {} +abstract class Parsers { -module Parse { + type input; - trait Parser[p] { + trait Parser[a] { - type Result = Option[Pair[p, List[Char]]]; + type Result = Option[Pair[a, input]]; - def apply(in: List[Char]): Result; + def apply(in: input): Result; - def filter(p: p => Boolean) = new Parser[p] { - def apply(in: List[Char]): Result = Parser.this.apply(in) match { - case Some(Pair(x, in1)) => if (p(x)) Some(Pair(x, in1)) else None() - case n => n + def filter(pred: a => boolean) = new Parser[a] { + def apply(in: input): Result = Parser.this.apply(in) match { + case None => None + case Some(Pair(x, in1)) => if (pred(x)) Some(Pair(x, in1)) else None } } - def map[b](f: p => b) = new Parser[b] { - def apply(in: List[Char]): Result = Parser.this.apply(in) match { + def map[b](f: a => b) = new Parser[b] { + def apply(in: input): Result = Parser.this.apply(in) match { + case None => None case Some(Pair(x, in1)) => Some(Pair(f(x), in1)) - case None() => None() } } - def flatMap[b](f: p => Parser[b]) = new Parser[b] { - def apply(in: List[Char]): Result = Parser.this.apply(in) match { - case Some(Pair(x, in1)) => f(x)(in1) - case None() => None() + def flatMap[b](f: a => Parser[b]) = new Parser[b] { + def apply(in: input): Result = Parser.this.apply(in) match { + case None => None + case Some(Pair(x, in1)) => f(x).apply(in1) } } - def ||| (def p: Parser[p]) = new Parser[p] { - def apply(in: List[Char]): Result = Parser.this.apply(in) match { - case None() => p(in) + def ||| (def p: Parser[a]) = new Parser[a] { + def apply(in: input): Result = Parser.this.apply(in) match { + case None => p(in) case s => s } } def &&& [b](def p: Parser[b]): Parser[b] = - for (val _ <- this; val result <- p) yield result; + for (val _ <- this; val x <- p) yield x; } - def succeed[p](x: p) = new Parser[p] { - def apply(in: List[Char]) = Some(Pair(x, in)) + def succeed[a](x: a) = new Parser[a] { + def apply(in: input) = Some(Pair(x, in)) } def rep[a](p: Parser[a]): Parser[List[a]] = @@ -56,60 +53,58 @@ module Parse { for (val x <- p; val xs <- rep(p)) yield x :: xs; def opt[a](p: Parser[a]): Parser[Option[a]] = - (for (val x <- p) yield Some(x): Option[a]) ||| succeed(None(): Option[a]); + (for (val x <- p) yield List(x)) ||| List(); } +abstract class ExprParsers extends Parsers { -module ExprParser { - import Parse._; + def any: Parser[char]; - def chrWith(p: Char => Boolean) = new Parser[Char] { - def apply(in: List[Char]): Result = in match { - case List() => None() - case (c :: in1) => if (p(c)) Some(Pair(c, in1)) else None() - } - } + def chr(ch: char) = + for (val c <- any; c == ch) yield c; - def chr(c: Char): Parser[Char] = chrWith(d => d == c); - - def letter: Parser[Char] = chrWith(c => c.isLetter); - def digit : Parser[Char] = chrWith(c => c.isDigit); + def chr(p: char => boolean) = + for (val c <- any; p(c)) yield c; def ident: Parser[String] = - for (val c <- letter; val cs <- rep(letter ||| digit)) - yield ((c :: cs) foldr "") {(c, s) => c+ s} - - def number: Parser[Int] = - for (val d <- digit; val ds <- rep(digit)) - yield ((d - '0') foldl_: ds) {(x, y) => x * 10 + (y - '0')}; - - def expr: Parser[Tree] = - for { - val e1 <- expr1; - val es <- rep ( - for { - val op <- chr('+') ||| chr('-'); - val e <- expr1 - } yield (x: Tree => Binop(op, x, e)) - ) - } yield (e1 foldl_: es) {(x,f) => f(x)} - - def expr1: Parser[Tree] = - for { - val e1 <- expr2; - val es <- rep ( - for { - val op <- chr('*') ||| chr('/'); - val e <- expr2 - } yield (x: Tree => Binop(op, x, e)) - ) - } yield (e1 foldl_: es) {(x,f) => f(x)} - - def expr2: Parser[Tree] = - (for { val n <- ident } yield Var(n)) - ||| (for { val n <- number } yield Num(n)) - ||| (for { val _ <- chr('('); val e <- expr; val _ <- chr(')') } yield e); - - private def applyAll[a](fs: List[a => a], x: a) = - (x foldl_: fs) { (x, f) => f(x) } + for ( + val c: char <- chr(Character.isLetter); + val cs: List[char] <- rep(chr(Character.isLetterOrDigit)) + ) yield (c :: cs).mkString("", "", ""); + + def number: Parser[int] = + for ( + val d: char <- chr(Character.isDigit); + val ds: List[char] <- rep(chr(Character.isDigit)) + ) yield ((d - '0') /: ds) ((x, digit) => x * 10 + digit - '0'); + + def list: Parser[List[Tree]] = + for ( + val _ <- chr('('); + val es <- listElems ||| succeed(List()); + val _ <- chr(')') + ) yield es; + + def listElems: Parser[List[Any]] = + for ( + val x <- expr; + val xs <- chr(',') &&& listElems ||| succeed(List()) + ) yield x :: xs; + + def expr: Parser[Any] = + list ||| ident ||| number; + } + +object Test { + def main(args: Array[String]) = + System.out.println( + if (args.length == 1) + new ExprParserFamily(args(0)).expr(0) match { + case Some(Pair(tree, _)) => tree.toString(); + case None => "Syntax error" + } + else "usage: java examples.Test <expr-string>" + ); +} + |