8 // amm fun_parser.sc defs.fun |
8 // amm fun_parser.sc defs.fun |
9 // |
9 // |
10 // this will generate a parse-tree from a list |
10 // this will generate a parse-tree from a list |
11 // of tokens |
11 // of tokens |
12 |
12 |
|
13 //> using toolkit 0.5.0 |
|
14 // > using file fun_tokens.scala |
|
15 |
|
16 |
13 import scala.language.implicitConversions |
17 import scala.language.implicitConversions |
14 import scala.language.reflectiveCalls |
18 import scala.language.reflectiveCalls |
15 |
19 |
16 import $file.fun_tokens, fun_tokens._ |
20 |
|
21 //import $file.fun_tokens, fun_tokens._ |
17 |
22 |
18 |
23 |
19 // Parser combinators |
24 // Parser combinators |
20 // type parameter I needs to be of Seq-type |
25 // type parameter I needs to be of Seq-type |
21 // |
26 // |
22 type IsSeq[I] = I => Seq[_] |
27 type IsSeq[I] = I => Seq[?] |
23 |
28 |
24 /* |
29 /* |
25 abstract class Parser[I, T](using is: I => Seq[_]) { |
30 abstract class Parser[I, T](using is: I => Seq[_]) { |
26 def parse(in: I): Set[(T, I)] |
31 def parse(in: I): Set[(T, I)] |
27 |
32 |
30 if is(tl).isEmpty) yield hd |
35 if is(tl).isEmpty) yield hd |
31 } |
36 } |
32 */ |
37 */ |
33 |
38 |
34 |
39 |
35 abstract class Parser[I, T](using is: I => Seq[_]) { |
40 abstract class Parser[I, T](using is: I => Seq[?]) { |
36 def parse(ts: I): Set[(T, I)] |
41 def parse(ts: I): Set[(T, I)] |
37 |
42 |
38 def parse_single(ts: I) : T = |
43 def parse_single(ts: I) : T = |
39 parse(ts).partition(p => is(p._2).isEmpty) match { |
44 parse(ts).partition(p => is(p._2).isEmpty) match { |
40 case (good, _) if !good.isEmpty => good.head._1 |
45 case (good, _) if !good.isEmpty => good.head._1 |
74 def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q) |
79 def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q) |
75 def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q) |
80 def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q) |
76 def map[S](f: => T => S) = new MapParser[I, T, S](p, f) |
81 def map[S](f: => T => S) = new MapParser[I, T, S](p, f) |
77 } |
82 } |
78 |
83 |
79 def ListParser[I, T, S](p: => Parser[I, T], q: => Parser[I, S])(using is: I => Seq[_]): Parser[I, List[T]] = { |
84 def ListParser[I, T, S](p: => Parser[I, T], q: => Parser[I, S])(using is: I => Seq[?]): Parser[I, List[T]] = { |
80 (p ~ q ~ ListParser(p, q)).map{ case (x:T) ~ (y:S) ~ (z:List[T]) => x :: z } || |
85 (p ~ q ~ ListParser(p, q)).map{ case (x:T) ~ (y:S) ~ (z:List[T]) => x :: z } || |
81 (p.map[List[T]]{s => List(s)}) |
86 (p.map[List[T]]{s => List(s)}) |
82 } |
87 } |
83 |
88 |
84 case class TokParser(tok: Token) extends Parser[List[Token], Token] { |
89 case class TokParser(tok: Token) extends Parser[List[Token], Token] { |
182 |
187 |
183 def parse_tks(tks: List[Token]) : List[Decl] = |
188 def parse_tks(tks: List[Token]) : List[Decl] = |
184 Prog.parse_single(tks) |
189 Prog.parse_single(tks) |
185 |
190 |
186 //@doc("Parses a file.") |
191 //@doc("Parses a file.") |
187 @main |
192 //@main |
188 def main(fname: String) : Unit = { |
193 def main(fname: String) : Unit = { |
189 val tks = tokenise(os.read(os.pwd / fname)) |
194 val tks = tokenise(os.read(os.pwd / fname)) |
190 println(parse_tks(tks)) |
195 println(parse_tks(tks)) |
191 } |
196 } |
192 |
197 |