summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2007-07-17 20:49:24 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2007-07-17 20:49:24 +0000
commitc5c6d4a8ce75993d2dcd80f6360b45de534a3f41 (patch)
treea4502a0bf95b9bf8904936b0bdb8eb4cd34b558f /docs
parent31b6dbf1c50b4b6fe3664691403e694de6a01513 (diff)
downloadscala-c5c6d4a8ce75993d2dcd80f6360b45de534a3f41.tar.gz
scala-c5c6d4a8ce75993d2dcd80f6360b45de534a3f41.tar.bz2
scala-c5c6d4a8ce75993d2dcd80f6360b45de534a3f41.zip
updated examples to new combinator library
Diffstat (limited to 'docs')
-rw-r--r--docs/examples/Parsers.scala108
-rw-r--r--docs/examples/parsers1.scala122
-rw-r--r--docs/examples/parsers2.scala69
-rw-r--r--docs/examples/parsing/ArithmeticParser.scala57
-rw-r--r--docs/examples/parsing/ListParser.scala33
5 files changed, 90 insertions, 299 deletions
diff --git a/docs/examples/Parsers.scala b/docs/examples/Parsers.scala
deleted file mode 100644
index 4129edca2d..0000000000
--- a/docs/examples/Parsers.scala
+++ /dev/null
@@ -1,108 +0,0 @@
-package examples
-
-abstract class Parsers {
-
- type inputType
-
- trait Parser[a] {
-
- type Result = Option[Pair[a, inputType]];
-
- def apply(in: inputType): Result;
-
- def filter(pred: a => boolean) = new Parser[a] {
- def apply(in: inputType): 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: a => b) = new Parser[b] {
- def apply(in: inputType): Result = Parser.this.apply(in) match {
- case None => None
- case Some(Pair(x, in1)) => Some(Pair(f(x), in1))
- }
- }
-
- def flatMap[b](f: a => Parser[b]) = new Parser[b] {
- def apply(in: inputType): Result = Parser.this.apply(in) match {
- case None => None
- case Some(Pair(x, in1)) => f(x).apply(in1)
- }
- }
-
- def ||| (p: => Parser[a]) = new Parser[a] {
- def apply(in: inputType): Result = Parser.this.apply(in) match {
- case None => p(in)
- case s => s
- }
- }
-
- def &&& [b](p: => Parser[b]): Parser[b] =
- for (_ <- this; x <- p) yield x
- }
-
- def succeed[a](x: a) = new Parser[a] {
- def apply(in: inputType): Result = Some(Pair(x, in))
- }
-
- def rep[a](p: Parser[a]): Parser[List[a]] =
- rep1(p) ||| succeed(List())
-
- def rep1[a](p: Parser[a]): Parser[List[a]] =
- for (x <- p; xs <- rep(p)) yield x :: xs
-
- def opt[a](p: Parser[a]): Parser[List[a]] =
- (for (x <- p) yield List(x)) ||| succeed(List())
-}
-
-class Tokenizer(in: Iterator[char], delimiters: String) extends Iterator[String] {
-
- val EOI: char = 0
-
- def nextChar() =
- if (in.hasNext) in.next else EOI
-
- private var ch = nextChar();
-
- def isDelimiter(ch: Char) = {
- var i = 0
- while (i < delimiters.length() && delimiters.charAt(i) != ch) { i += 1 }
- i < delimiters.length()
- }
-
- def hasNext: boolean = ch != EOI
-
- private val buf = new StringBuffer
-
- def next: String = {
- while (ch <= ' ' && ch != EOI) nextChar()
- if (ch == EOI) ""
- else {
- if (isDelimiter(ch)) ch.toString()
- else {
- buf.setLength(0); buf append ch
- while (ch > ' ' && ch != EOI && !isDelimiter(ch)) {
- buf append ch; nextChar();
- }
- buf.toString()
- }
- }
- }
-}
-
-trait TokenParsers extends Parsers {
- type inputType = Stream[String]
- def nextToken() = new Parser[String] {
- def apply(in: inputType): Result =
- if (in.isEmpty) None else Some(Pair(in.head, in.tail))
- }
-}
-
-trait CharParsers extends Parsers {
- def any: Parser[char]
- def chr(ch: char) =
- for (c <- any if c == ch) yield c
- def chr(p: char => boolean) =
- for (c <- any if p(c)) yield c
-}
diff --git a/docs/examples/parsers1.scala b/docs/examples/parsers1.scala
deleted file mode 100644
index e4aeea3613..0000000000
--- a/docs/examples/parsers1.scala
+++ /dev/null
@@ -1,122 +0,0 @@
-package examples
-
-object parsers1 {
-
- abstract class Parsers {
-
- type inputType;
-
- abstract class Parser {
-
- type Result = Option[inputType]
-
- def apply(in: inputType): Result
-
- /*** p &&& q applies first p, and if that succeeds, then q
- */
- def &&& (q: => Parser) = new Parser {
- def apply(in: inputType): Result = Parser.this.apply(in) match {
- case None => None
- case Some(in1) => q(in1)
- }
- }
-
- /*** p ||| q applies first p, and, if that fails, then q.
- */
- def ||| (q: => Parser) = new Parser {
- def apply(in: inputType): Result = Parser.this.apply(in) match {
- case None => q(in)
- case s => s
- }
- }
- }
-
- val empty = new Parser {
- def apply(in: inputType): Result = Some(in)
- }
-
- val fail = new Parser {
- def apply(in: inputType): Result = None
- }
-
- def opt(p: Parser): Parser = p ||| empty // p? = (p | <empty>)
- def rep(p: Parser): Parser = opt(rep1(p)) // p* = [p+]
- def rep1(p: Parser): Parser = p &&& rep(p) // p+ = p p*
- }
-
- trait ListParsers extends Parsers {
- def chr(p: char => boolean): Parser
- def chr(c: char): Parser = chr((d: char) => d == c)
-
- def letter : Parser = chr((c: char) => Character.isLetter(c))
- def digit : Parser = chr((c: char) => Character.isDigit(c))
-
- def ident : Parser = letter &&& rep(letter ||| digit)
- def number : Parser = digit &&& rep(digit)
- def list : Parser = chr('(') &&& listElems &&& chr(')')
- def listElems : Parser = expr &&& (chr(',') &&& listElems ||| empty)
- def expr : Parser = ident ||| number ||| list
- }
-
- trait ExprParsers extends Parsers {
- def chr(p: char => boolean): Parser
- def chr(c: char): Parser = chr((d: char) => d == c)
-
- def digit : Parser = chr((c: char) => Character.isDigit(c))
- def number : Parser = digit &&& rep(digit)
- def summand : Parser = number ||| chr('(') &&& expr &&& chr(')')
- def expr : Parser = summand &&& rep(chr('+') &&& summand)
- }
-
- class ParseString(s: String) extends Parsers {
- type inputType = Int
- val input = 0
- def chr(p: char => boolean) = new Parser {
- def apply(in: int): Parser#Result =
- if (in < s.length() && p(s charAt in)) Some(in + 1)
- else None
- }
- }
-
- object TestList {
- def main(args: Array[String]) {
- Console.println(
- if (args.length == 1) {
- val ps = new ParseString(args(0)) with ListParsers
- ps.expr(ps.input) match {
- case Some(n) =>
- "parsed: " + args(0).substring(0, n)
- case None =>
- "nothing parsed"
- }
- }
- else
- "usage: java examples.TestList <expr-string>"
- )
- }
- }
-
- object TestExpr {
- def main(args: Array[String]) {
- Console.println(
- if (args.length == 1) {
- val ps = new ParseString(args(0)) with ExprParsers
- ps.expr(ps.input) match {
- case Some(n) =>
- "parsed: " + args(0).substring(0, n)
- case None =>
- "nothing parsed"
- }
- }
- else
- "usage: java examples.TestExpr <expr-string>"
- )
- }
- }
-
- def main(args: Array[String]) {
- TestList.main(Array("(a,b,(1,2))"))
- TestExpr.main(Array("2+3+(4+1)"))
- }
-
-}
diff --git a/docs/examples/parsers2.scala b/docs/examples/parsers2.scala
deleted file mode 100644
index 71ece15552..0000000000
--- a/docs/examples/parsers2.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-package examples
-
-object parsers2 {
-
- abstract class Tree
- case class Id(s: String) extends Tree
- case class Num(n: int) extends Tree
- case class Lst(elems: List[Tree]) extends Tree
-
- def isLetter = (c: char) => Character.isLetter(c)
- def isLetterOrDigit: char => boolean = Character.isLetterOrDigit
- def isDigit: char => boolean = Character.isDigit
-
- trait ListParsers extends CharParsers {
-
- def ident: Parser[Tree] =
- for (
- c: char <- chr(isLetter);
- cs: List[char] <- rep(chr(isLetterOrDigit))
- ) yield Id((c :: cs).mkString("", "", ""))
-
- def number: Parser[Tree] =
- for (
- d: char <- chr(isDigit);
- ds: List[char] <- rep(chr(isDigit))
- ) yield Num(((d - '0') /: ds) ((x, digit) => x * 10 + digit - '0'))
-
- def list: Parser[Tree] =
- for (
- _ <- chr('(');
- es <- listElems ||| succeed(List());
- _ <- chr(')')
- ) yield Lst(es)
-
- def listElems: Parser[List[Tree]] =
- for (
- x <- expr;
- xs <- chr(',') &&& listElems ||| succeed(List())
- ) yield x :: xs
-
- def expr: Parser[Tree] =
- list ||| ident ||| number
-
- }
-
- class ParseString(s: String) extends Parsers {
- type inputType = int
- val input = 0
- def any = new Parser[char] {
- def apply(in: int): Parser[char]#Result =
- if (in < s.length()) Some(Pair(s charAt in, in + 1)) else None
- }
- }
-
- def main(args: Array[String]) {
- Console.println(
- if (args.length == 1) {
- val ps = new ParseString(args(0)) with ListParsers
- ps.expr(ps.input) match {
- case Some(Pair(list, _)) => "parsed: " + list
- case None => "nothing parsed"
- }
- }
- else
- "usage: scala examples.parsers2 <expr-string>"
- )
- }
-
-}
diff --git a/docs/examples/parsing/ArithmeticParser.scala b/docs/examples/parsing/ArithmeticParser.scala
new file mode 100644
index 0000000000..2aac4b6f6c
--- /dev/null
+++ b/docs/examples/parsing/ArithmeticParser.scala
@@ -0,0 +1,57 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package examples.parsing
+
+import scala.util.parsing.combinator.lexical.StdLexical
+import scala.util.parsing.combinator.syntactical.StdTokenParsers
+
+/** Parse and evaluate a numeric expression as a sequence of terms, separated by + or -
+ * a term is a sequence of factors, separated by * or /
+ * a factor is a parenthesized expression or a number
+ *
+ * @author Adriaan Moors
+ */
+object arithmeticParser extends StdTokenParsers {
+ type Tokens = StdLexical ; val lexical = new StdLexical
+ lexical.delimiters ++= List("(", ")", "+", "-", "*", "/")
+
+ lazy val expr = term*("+" ^^ {(x: int, y: int) => x + y} | "-" ^^ {(x: int, y: int) => x - y})
+ lazy val term = factor*("*" ^^ {(x: int, y: int) => x * y} | "/" ^^ {(x: int, y: int) => x / y})
+ lazy val factor: Parser[int] = "(" ~ expr ~ ")" | numericLit ^^ (_.toInt)
+
+ def main(args: Array[String]) {
+ println(
+ if (args.length == 1) {
+ expr(new lexical.Scanner(args(0)))
+ }
+ else
+ "usage: scala examples.parsing.arithmeticParser <expr-string>"
+ )
+ }
+}
+
+
+object arithmeticParserDesugared extends StdTokenParsers {
+ type Tokens = StdLexical ; val lexical = new StdLexical
+ lexical.delimiters ++= List("(", ")", "+", "-", "*", "/")
+
+ lazy val expr = chainl1(term, (keyword("+").^^{(x: int, y: int) => x + y}).|(keyword("-").^^{(x: int, y: int) => x - y}))
+ lazy val term = chainl1(factor, (keyword("*").^^{(x: int, y: int) => x * y}).|(keyword("/").^^{(x: int, y: int) => x / y}))
+ lazy val factor: Parser[int] = keyword("(").~(expr.~(keyword(")"))).|(numericLit.^^(x => x.toInt))
+
+ def main(args: Array[String]) {
+ println(
+ if (args.length == 1) {
+ expr(new lexical.Scanner(args(0)))
+ }
+ else
+ "usage: scala examples.parsing.arithmeticParser <expr-string>"
+ )
+ }
+} \ No newline at end of file
diff --git a/docs/examples/parsing/ListParser.scala b/docs/examples/parsing/ListParser.scala
new file mode 100644
index 0000000000..65354482f3
--- /dev/null
+++ b/docs/examples/parsing/ListParser.scala
@@ -0,0 +1,33 @@
+package examples.parsing
+
+import scala.util.parsing.combinator.{Parsers, ImplicitConversions, ~, mkTilde}
+import scala.util.parsing.input.CharArrayReader
+
+object listParser {
+ abstract class Tree
+ case class Id(s: String) extends Tree
+ case class Num(n: Int) extends Tree
+ case class Lst(elems: List[Tree]) extends Tree
+
+ import Character.{isLetter, isLetterOrDigit, isDigit}
+ def mkString(cs: List[Any]) = cs.mkString("")
+
+ class ListParsers extends Parsers {
+ type Elem = Char
+
+ lazy val ident = rep1(elem("letter", isLetter), elem("letter or digit", isLetterOrDigit)) ^^ {cs => Id(mkString(cs))}
+ lazy val number = chainl1(elem("digit", isDigit) ^^ (_ - '0'), success ^^ {(accum: Int, d: Int) => accum * 10 + d}) ^^ Num
+ lazy val list = '(' ~ repsep(expr, ',') ~ ')' ^^ Lst
+ lazy val expr: Parser[Tree] = list | ident | number
+ }
+
+ def main(args: Array[String]) {
+ println(
+ if (args.length == 1) {
+ (new ListParsers).expr(new CharArrayReader(args(0).toCharArray()))
+ }
+ else
+ "usage: scala examples.parsing.listParser <list-string>"
+ )
+ }
+}