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}") |