blob: 47fa8d0f2e38a150eee2e2aeb27ea4390ea998c9 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
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 {}
abstract class ListParsers extends CharParsers {
def ident: Parser[Tree] =
for (
val c: char <- chr(Character.isLetter);
val cs: List[char] <- rep(chr(Character.isLetterOrDigit))
) yield Id((c :: cs).mkString("", "", ""));
def number: Parser[Tree] =
for (
val d: char <- chr(Character.isDigit);
val ds: List[char] <- rep(chr(Character.isDigit))
) yield Num(((d - '0') /: ds) ((x, digit) => x * 10 + digit - '0'));
def list: Parser[Tree] =
for (
val _ <- chr('(');
val es <- listElems ||| succeed(List());
val _ <- chr(')')
) yield Lst(es);
def listElems: Parser[List[Tree]] =
for (
val x <- expr;
val 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]): unit =
Console.println(
if (args.length == 1) {
val ps = new ListParsers with ParseString(args(0));
ps.expr(ps.input) match {
case Some(Pair(list, _)) => Console.println("parsed: " + list);
case None => "nothing parsed"
}
} else "usage: scala examples.parsers2 <expr-string>"
);
}
|