progs/while-arrays/compile_bfc.sc
changeset 943 5365ef60707e
parent 870 739039774cee
child 949 61797848eede
equal deleted inserted replaced
942:c82a45f48bfc 943:5365ef60707e
    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 
   318 
   322 
   319 
   323 
   320 
   324 
   321 
   325 
   322 
   326 
   323 
   327 */
   324 
       
   325 // runs with amm2 and amm3