90 |
90 |
91 //===================================== |
91 //===================================== |
92 // Grammar Rules for WHILE with arrays |
92 // Grammar Rules for WHILE with arrays |
93 //===================================== |
93 //===================================== |
94 |
94 |
|
95 import $ivy.`com.lihaoyi::fastparse:3.0.2` |
95 import fastparse._ |
96 import fastparse._ |
96 import MultiLineWhitespace._ |
97 import MultiLineWhitespace._ |
97 |
98 |
98 def lowercase [_ : P] = P( CharIn("a-z") ) |
99 def string[A: P]: P[String] = P(CharIn("a-zA-Z0-9").rep(1).!) |
99 def uppercase[_ : P] = P( CharIn("A-Z") ) |
100 |
100 def letter[_ : P] = P( lowercase | uppercase ) |
101 /* |
101 def digit [_ : P] = P( CharIn("0-9") ) |
102 def lowercase [$ : P] = P( CharIn("a-z") ) |
102 |
103 def uppercase[$ : P] = P( CharIn("A-Z") ) |
103 def Number[_ : P]: P[Int] = P( digit.rep(1) ).!.map(_.toInt) |
104 def letter[$ : P] = P( lowercase | uppercase ) |
104 def Ident[_ : P]: P[String] = P( letter ~ (letter | digit | "_").rep ).! |
105 def digit [$ : P] = P( CharIn("0-9") ) |
|
106 |
|
107 def Number[$ : P]: P[Int] = P( digit.rep(1) ).!.map(_.toInt) |
|
108 def Ident[$ : P]: P[String] = P( letter ~ (letter | digit | "_").rep ).! |
105 |
109 |
106 // arithmetic expressions |
110 // arithmetic expressions |
107 def AExp[_ : P]: P[AExp] = |
111 def AExp[$ : P]: P[AExp] = |
108 P( P(Te ~ "+" ~ AExp).map{ case (l, r) => Aop("+", l, r)} |
112 P( P(Te ~ "+" ~ AExp).map{ case (l, r) => Aop("+", l, r)} |
109 | P(Te ~ "-" ~ AExp).map{ case (l, r) => Aop("-", l, r)} |
113 | P(Te ~ "-" ~ AExp).map{ case (l, r) => Aop("-", l, r)} |
110 | Te ) |
114 | Te ) |
111 def Te[_ : P]: P[AExp] = |
115 def Te[$ : P]: P[AExp] = |
112 P( P(Fa ~ "*" ~ Te).map{ case (l, r) => Aop("*", l, r)} |
116 P( P(Fa ~ "*" ~ Te).map{ case (l, r) => Aop("*", l, r)} |
113 | Fa ) |
117 | Fa ) |
114 def Fa[_ : P]: P[AExp] = |
118 def Fa[$ : P]: P[AExp] = |
115 P( "(" ~ AExp ~ ")" |
119 P( "(" ~ AExp ~ ")" |
116 | P (Ident ~ "[" ~ AExp ~ "]").map{Ref.tupled} |
120 | P (Ident ~ "[" ~ AExp ~ "]").map{Ref.tupled} |
117 | P(Number).map{Num} |
121 | P(Number).map{Num} |
118 | P(Ident).map{Var} ) |
122 | P(Ident).map{Var} ) |
119 |
123 |
120 // boolean expressions |
124 // boolean expressions |
121 def BExp[_ : P]: P[BExp] = |
125 def BExp[$ : P]: P[BExp] = |
122 P( P(AExp ~ "=" ~ AExp).map{ case (x, z) => Bop("=", x, z)} |
126 P( P(AExp ~ "=" ~ AExp).map{ case (x, z) => Bop("=", x, z)} |
123 | P(AExp ~ "!=" ~ AExp).map{ case (x, z) => Bop("!=", x, z)} |
127 | P(AExp ~ "!=" ~ AExp).map{ case (x, z) => Bop("!=", x, z)} |
124 | P(AExp ~ "<" ~ AExp).map{ case (x, z) => Bop("<", x, z)} |
128 | P(AExp ~ "<" ~ AExp).map{ case (x, z) => Bop("<", x, z)} |
125 | P(AExp ~ ">" ~ AExp).map{ case (x, z) => Bop("<", z, x)} |
129 | P(AExp ~ ">" ~ AExp).map{ case (x, z) => Bop("<", z, x)} |
126 | P("true").map{ _ => True} |
130 | P("true").map{ _ => True} |
127 | P("false").map{ _ => False} |
131 | P("false").map{ _ => False} |
128 | "(" ~ BExp ~ ")" ) |
132 | "(" ~ BExp ~ ")" ) |
129 |
133 |
130 // statements and blocks |
134 // statements and blocks |
131 def Stmt[_ : P]: P[Stmt] = |
135 def Stmt[$ : P]: P[Stmt] = |
132 P( P("skip").map( _ => Skip) |
136 P( P("skip").map( _ => Skip) |
133 | P(Ident ~ ":=" ~ AExp).map{Assign.tupled} |
137 | P(Ident ~ ":=" ~ AExp).map{Assign.tupled} |
134 | P(Ident ~ "[" ~ AExp ~ "]" ~ ":=" ~ AExp).map{AssignA.tupled} |
138 | P(Ident ~ "[" ~ AExp ~ "]" ~ ":=" ~ AExp).map{AssignA.tupled} |
135 | P("if" ~ BExp ~ "then" ~ Block ~ "else" ~ Block).map{If.tupled} |
139 | P("if" ~ BExp ~ "then" ~ Block ~ "else" ~ Block).map{If.tupled} |
136 | P("while" ~ BExp ~ "do" ~ Block).map{While.tupled} |
140 | P("while" ~ BExp ~ "do" ~ Block).map{While.tupled} |
137 | P("new(" ~ Ident ~ "[" ~ Number ~ "])").map{ArrayDef.tupled} |
141 | P("new(" ~ Ident ~ "[" ~ Number ~ "])").map{ArrayDef.tupled} |
138 | P("write(" ~ Ident ~ ")").map{Write} ) |
142 | P("write(" ~ Ident ~ ")").map{Write} ) |
139 |
143 |
140 def Stmts[_ : P]: P[Block] = |
144 def Stmts[$ : P]: P[Block] = |
141 P( P(Stmt ~ ";" ~ Stmts).map{ case (x, z) => x :: z } |
145 P( P(Stmt ~ ";" ~ Stmts).map{ case (x, z) => x :: z } |
142 | P(Stmt).map{s => List(s)} ) |
146 | P(Stmt).map{s => List(s)} ) |
143 |
147 |
144 def Block[_ : P]: P[Block] = |
148 def Block[$ : P]: P[Block] = |
145 P( "{" ~ Stmts ~ "}" |
149 P( "{" ~ Stmts ~ "}" |
146 | P(Stmt).map(s => List(s)) ) |
150 | P(Stmt).map(s => List(s)) ) |
147 |
151 |
148 // some test cases for the parser |
152 // some test cases for the parser |
149 |
153 |