progs/parser-combinators/comb2.sc
changeset 919 53f08d873e09
parent 906 2bf1516d730f
child 941 66adcae6c762
equal deleted inserted replaced
918:53e7da9f372a 919:53f08d873e09
    41     for ((hd1, tl1) <- p.parse(in); 
    41     for ((hd1, tl1) <- p.parse(in); 
    42          (hd2, tl2) <- q.parse(tl1)) yield (new ~(hd1, hd2), tl2)
    42          (hd2, tl2) <- q.parse(tl1)) yield (new ~(hd1, hd2), tl2)
    43 }
    43 }
    44 
    44 
    45 // map parser
    45 // map parser
    46 class MapParser[I, T, S](p: => Parser[I, T], 
    46 class maparser[I, T, S](p: => Parser[I, T], 
    47                          f: T => S)(using I => Seq[_]) extends Parser[I, S] {
    47                          f: T => S)(using I => Seq[_]) extends Parser[I, S] {
    48   def parse(in: I) = for ((hd, tl) <- p.parse(in)) yield (f(hd), tl)
    48   def parse(in: I) = for ((hd, tl) <- p.parse(in)) yield (f(hd), tl)
    49 }
    49 }
    50 
    50 
    51 
    51 
    91 
    91 
    92 // more convenient syntax for parser combinators
    92 // more convenient syntax for parser combinators
    93 extension [I, T](p: Parser[I, T])(using I => Seq[_]) {
    93 extension [I, T](p: Parser[I, T])(using I => Seq[_]) {
    94   def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q)
    94   def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q)
    95   def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q)
    95   def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q)
    96   def mapp[S](f: => T => S) = new MapParser[I, T, S](p, f)
    96   def map[S](f: => T => S) = new maparser[I, T, S](p, f)
    97 }
    97 }
    98 
    98 
    99 
    99 
   100 
   100 
   101 
   101 
   123 case class Or(b1: BExp, b2: BExp) extends BExp
   123 case class Or(b1: BExp, b2: BExp) extends BExp
   124 
   124 
   125 
   125 
   126 // arithmetic expressions
   126 // arithmetic expressions
   127 lazy val AExp: Parser[String, AExp] = 
   127 lazy val AExp: Parser[String, AExp] = 
   128   (Te ~ p"+" ~ AExp).mapp[AExp]{ case x ~ _ ~ z => Aop("+", x, z) } ||
   128   (Te ~ p"+" ~ AExp).map[AExp]{ case x ~ _ ~ z => Aop("+", x, z) } ||
   129   (Te ~ p"-" ~ AExp).mapp[AExp]{ case x ~ _ ~ z => Aop("-", x, z) } || Te
   129   (Te ~ p"-" ~ AExp).map[AExp]{ case x ~ _ ~ z => Aop("-", x, z) } || Te
   130 lazy val Te: Parser[String, AExp] = 
   130 lazy val Te: Parser[String, AExp] = 
   131   (Fa ~ p"*" ~ Te).mapp[AExp]{ case x ~ _ ~ z => Aop("*", x, z) } || 
   131   (Fa ~ p"*" ~ Te).map[AExp]{ case x ~ _ ~ z => Aop("*", x, z) } || 
   132   (Fa ~ p"/" ~ Te).mapp[AExp]{ case x ~ _ ~ z => Aop("/", x, z) } || Fa  
   132   (Fa ~ p"/" ~ Te).map[AExp]{ case x ~ _ ~ z => Aop("/", x, z) } || Fa  
   133 lazy val Fa: Parser[String, AExp] = 
   133 lazy val Fa: Parser[String, AExp] = 
   134    (p"(" ~ AExp ~ p")").mapp{ case _ ~ y ~ _ => y } || 
   134    (p"(" ~ AExp ~ p")").map{ case _ ~ y ~ _ => y } || 
   135    IdParser.mapp(Var) || 
   135    IdParser.map(Var) || 
   136    NumParser.mapp(Num)
   136    NumParser.map(Num)
   137 
   137 
   138 // boolean expressions with some simple nesting
   138 // boolean expressions with some simple nesting
   139 lazy val BExp: Parser[String, BExp] = 
   139 lazy val BExp: Parser[String, BExp] = 
   140    (AExp ~ p"==" ~ AExp).mapp[BExp]{ case x ~ _ ~ z => Bop("==", x, z) } || 
   140    (AExp ~ p"==" ~ AExp).map[BExp]{ case x ~ _ ~ z => Bop("==", x, z) } || 
   141    (AExp ~ p"!=" ~ AExp).mapp[BExp]{ case x ~ _ ~ z => Bop("!=", x, z) } || 
   141    (AExp ~ p"!=" ~ AExp).map[BExp]{ case x ~ _ ~ z => Bop("!=", x, z) } || 
   142    (AExp ~ p"<" ~ AExp).mapp[BExp]{ case x ~ _ ~ z => Bop("<", x, z) } || 
   142    (AExp ~ p"<" ~ AExp).map[BExp]{ case x ~ _ ~ z => Bop("<", x, z) } || 
   143    (AExp ~ p">" ~ AExp).mapp[BExp]{ case x ~ _ ~ z => Bop(">", x, z) } ||
   143    (AExp ~ p">" ~ AExp).map[BExp]{ case x ~ _ ~ z => Bop(">", x, z) } ||
   144    (p"(" ~ BExp ~ p")" ~ p"&&" ~ BExp).mapp[BExp]{ case _ ~ y ~ _ ~ _ ~ v => And(y, v) } ||
   144    (p"(" ~ BExp ~ p")" ~ p"&&" ~ BExp).map[BExp]{ case _ ~ y ~ _ ~ _ ~ v => And(y, v) } ||
   145    (p"(" ~ BExp ~ p")" ~ p"||" ~ BExp).mapp[BExp]{ case _ ~ y ~ _ ~ _ ~ v => Or(y, v) } ||
   145    (p"(" ~ BExp ~ p")" ~ p"||" ~ BExp).map[BExp]{ case _ ~ y ~ _ ~ _ ~ v => Or(y, v) } ||
   146    (p"true".mapp[BExp]{ _ => True }) || 
   146    (p"true".map[BExp]{ _ => True }) || 
   147    (p"false".mapp[BExp]{ _ => False }) ||
   147    (p"false".map[BExp]{ _ => False }) ||
   148    (p"(" ~ BExp ~ p")").mapp[BExp]{ case _ ~ x ~ _ => x }
   148    (p"(" ~ BExp ~ p")").map[BExp]{ case _ ~ x ~ _ => x }
   149 
   149 
   150 // a single statement 
   150 // a single statement 
   151 lazy val Stmt: Parser[String, Stmt] =
   151 lazy val Stmt: Parser[String, Stmt] =
   152   ((p"skip".mapp[Stmt]{_ => Skip }) ||
   152   ((p"skip".map[Stmt]{_ => Skip }) ||
   153    (IdParser ~ p":=" ~ AExp).mapp[Stmt]{ case x ~ _ ~ z => Assign(x, z) } ||
   153    (IdParser ~ p":=" ~ AExp).map[Stmt]{ case x ~ _ ~ z => Assign(x, z) } ||
   154    (p"write(" ~ IdParser ~ p")").mapp[Stmt]{ case _ ~ y ~ _ => Write(y) } ||
   154    (p"write(" ~ IdParser ~ p")").map[Stmt]{ case _ ~ y ~ _ => Write(y) } ||
   155    (p"if" ~ BExp ~ p"then" ~ Block ~ p"else" ~ Block)
   155    (p"if" ~ BExp ~ p"then" ~ Block ~ p"else" ~ Block)
   156      .mapp[Stmt]{ case _ ~ y ~ _ ~ u ~ _ ~ w => If(y, u, w) } ||
   156      .map[Stmt]{ case _ ~ y ~ _ ~ u ~ _ ~ w => If(y, u, w) } ||
   157    (p"while" ~ BExp ~ p"do" ~ Block).mapp[Stmt]{ case _ ~ y ~ _ ~ w => While(y, w) })   
   157    (p"while" ~ BExp ~ p"do" ~ Block).map[Stmt]{ case _ ~ y ~ _ ~ w => While(y, w) })   
   158  
   158  
   159  
   159  
   160 // statements
   160 // statements
   161 lazy val Stmts: Parser[String, Block] =
   161 lazy val Stmts: Parser[String, Block] =
   162   (Stmt ~ p";" ~ Stmts).mapp[Block]{ case x ~ _ ~ z => x :: z } ||
   162   (Stmt ~ p";" ~ Stmts).map[Block]{ case x ~ _ ~ z => x :: z } ||
   163   (Stmt.mapp[Block]{ s => List(s) })
   163   (Stmt.map[Block]{ s => List(s) })
   164 
   164 
   165 // blocks (enclosed in curly braces)
   165 // blocks (enclosed in curly braces)
   166 lazy val Block: Parser[String, Block] =
   166 lazy val Block: Parser[String, Block] =
   167   ((p"{" ~ Stmts ~ p"}").mapp{ case _ ~ y ~ _ => y } || 
   167   ((p"{" ~ Stmts ~ p"}").map{ case _ ~ y ~ _ => y } || 
   168    (Stmt.mapp(s => List(s))))
   168    (Stmt.map(s => List(s))))
   169 
   169 
   170 
   170 
   171 // Examples
   171 // Examples
   172 Stmt.parse_all("x2:=5+3")
   172 Stmt.parse_all("x2:=5+3")
   173 Block.parse_all("{x:=5;y:=8}")
   173 Block.parse_all("{x:=5;y:=8}")