while.scala
changeset 70 e6868bd2942b
parent 69 cc3f7908b942
child 71 7717f20f0504
equal deleted inserted replaced
69:cc3f7908b942 70:e6868bd2942b
     1 
     1 
     2 //:load matcher.scala
     2 //:load matcher.scala
       
     3 //:load parser3.scala
     3 
     4 
     4 // some regular expressions
     5 // some regular expressions
     5 val SYM = RANGE("""ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz_""")
     6 val SYM = RANGE("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz_")
     6 val DIGIT = RANGE("0123456789")
     7 val DIGIT = RANGE("0123456789")
     7 val ID = SEQ(SYM, STAR(ALT(SYM, DIGIT))) 
     8 val ID = SEQ(SYM, STAR(ALT(SYM, DIGIT))) 
     8 val NUM = PLUS(DIGIT)
     9 val NUM = PLUS(DIGIT)
     9 val KEYWORD = ALTS("skip", "while", "do", "if", "then", "else", "begin", "end", "true", "false") 
    10 val KEYWORD = ALTS("skip", "while", "do", "if", "then", "else", "true", "false") 
    10 val SEMI: Rexp = ";"
    11 val SEMI: Rexp = ";"
    11 val OP: Rexp = ALTS(":=", "=", "+", "-", "*")
    12 val OP: Rexp = ALTS(":=", "=", "+", "-", "*")
    12 val WHITESPACE = PLUS(RANGE(" \n"))
    13 val WHITESPACE = PLUS(RANGE(" \n"))
    13 val RPAREN: Rexp = ")"
    14 val RPAREN: Rexp = ")"
    14 val LPAREN: Rexp = "("
    15 val LPAREN: Rexp = "("
    15 val BEGIN: Rexp = "{"
    16 val BEGIN: Rexp = "{"
    16 val END: Rexp = "}"
    17 val END: Rexp = "}"
    17 
    18 
    18 // for classifying the strings that have been recognised
    19 // tokens for classifying the strings that have been recognised
    19 abstract class Token
    20 abstract class Token
    20 case object T_WHITESPACE extends Token
    21 case object T_WHITESPACE extends Token
    21 case object T_SEMI extends Token
    22 case object T_SEMI extends Token
    22 case object T_LPAREN extends Token
    23 case object T_LPAREN extends Token
    23 case object T_RPAREN extends Token
    24 case object T_RPAREN extends Token
    25 case object T_END extends Token
    26 case object T_END extends Token
    26 case class T_ID(s: String) extends Token
    27 case class T_ID(s: String) extends Token
    27 case class T_OP(s: String) extends Token
    28 case class T_OP(s: String) extends Token
    28 case class T_NUM(s: String) extends Token
    29 case class T_NUM(s: String) extends Token
    29 case class T_KWD(s: String) extends Token
    30 case class T_KWD(s: String) extends Token
    30 
       
    31 
    31 
    32 val lexing_rules: List[Rule[Token]] = 
    32 val lexing_rules: List[Rule[Token]] = 
    33   List((KEYWORD, (s) => T_KWD(s.mkString)),
    33   List((KEYWORD, (s) => T_KWD(s.mkString)),
    34        (ID, (s) => T_ID(s.mkString)),
    34        (ID, (s) => T_ID(s.mkString)),
    35        (OP, (s) => T_OP(s.mkString)),
    35        (OP, (s) => T_OP(s.mkString)),
    51 type Block = List[Stmt]
    51 type Block = List[Stmt]
    52 case object Skip extends Stmt
    52 case object Skip extends Stmt
    53 case class If(a: BExp, bl1: Block, bl2: Block) extends Stmt
    53 case class If(a: BExp, bl1: Block, bl2: Block) extends Stmt
    54 case class While(b: BExp, bl: Block) extends Stmt
    54 case class While(b: BExp, bl: Block) extends Stmt
    55 case class Assign(s: String, a: AExp) extends Stmt
    55 case class Assign(s: String, a: AExp) extends Stmt
       
    56 
    56 case class Var(s: String) extends AExp
    57 case class Var(s: String) extends AExp
    57 case class Num(i: Int) extends AExp
    58 case class Num(i: Int) extends AExp
    58 case class Aop(o: String, a1: AExp, a2: AExp) extends AExp
    59 case class Aop(o: String, a1: AExp, a2: AExp) extends AExp
       
    60 
    59 case object True extends BExp
    61 case object True extends BExp
    60 case object False extends BExp
    62 case object False extends BExp
    61 case class Bop(o: String, a1: AExp, a2: AExp) extends BExp
    63 case class Bop(o: String, a1: AExp, a2: AExp) extends BExp
    62 
    64 
    63 
    65 // atomic parsers
    64 case class TokParser(tok: Token) extends Parser[List[Token], Token] {
    66 case class TokParser(tok: Token) extends Parser[List[Token], Token] {
    65   def parse(ts: List[Token]) = ts match {
    67   def parse(ts: List[Token]) = ts match {
    66     case t::ts if (t == tok) => Set((t, ts)) 
    68     case t::ts if (t == tok) => Set((t, ts)) 
    67     case _ => Set ()
    69     case _ => Set ()
    68   }
    70   }
    89   (T ~ T_OP("-") ~ AExp) ==> { case ((x, y), z) => Aop("-", x, z): AExp } || T  
    91   (T ~ T_OP("-") ~ AExp) ==> { case ((x, y), z) => Aop("-", x, z): AExp } || T  
    90 lazy val T: Parser[List[Token], AExp] = 
    92 lazy val T: Parser[List[Token], AExp] = 
    91   (F ~ T_OP("*") ~ T) ==> { case ((x, y), z) => Aop("*", x, z): AExp } || F
    93   (F ~ T_OP("*") ~ T) ==> { case ((x, y), z) => Aop("*", x, z): AExp } || F
    92 lazy val F: Parser[List[Token], AExp] = 
    94 lazy val F: Parser[List[Token], AExp] = 
    93   (T_LPAREN ~> AExp <~ T_RPAREN) || 
    95   (T_LPAREN ~> AExp <~ T_RPAREN) || 
    94   IdParser ==> ((s) => Var(s)) || 
    96   IdParser ==> Var || 
    95   NumParser ==> ((i) => Num(i))
    97   NumParser ==> Num
    96 
    98 
    97 lazy val BExp: Parser[List[Token], BExp] = 
    99 lazy val BExp: Parser[List[Token], BExp] = 
    98   (AExp ~ T_OP("=") ~ AExp) ==> { case ((x, y), z) => Bop("=", x, z): BExp } || 
   100   (AExp ~ T_OP("=") ~ AExp) ==> { case ((x, y), z) => Bop("=", x, z): BExp } || 
    99   (T_KWD("true") ==> ((_) => True: BExp)) || 
   101   (T_KWD("true") ==> ((_) => True)) || 
   100   (T_KWD("false") ==> ((_) => False: BExp))
   102   (T_KWD("false") ==> ((_) => False: BExp))
   101 
   103 
   102 lazy val Stmt: Parser[List[Token], Stmt] =
   104 lazy val Stmt: Parser[List[Token], Stmt] =
   103   (T_KWD("skip") ==> ((_) => Skip: Stmt)) ||
   105   (T_KWD("skip") ==> ((_) => Skip: Stmt)) ||
   104   (IdParser ~ T_OP(":=") ~ AExp) ==> { case ((x, y), z) => Assign(x, z): Stmt } ||
   106   (IdParser ~ T_OP(":=") ~ AExp) ==> { case ((x, y), z) => Assign(x, z): Stmt } ||
   111 
   113 
   112 lazy val Block: Parser[List[Token], Block] =
   114 lazy val Block: Parser[List[Token], Block] =
   113   (T_BEGIN ~> Stmts <~ T_END) || 
   115   (T_BEGIN ~> Stmts <~ T_END) || 
   114   (Stmt ==> ((s) => List(s)))
   116   (Stmt ==> ((s) => List(s)))
   115 
   117 
       
   118 
       
   119 // examples
   116 val p1 = "x := 5"
   120 val p1 = "x := 5"
   117 val p1_toks = Tok.fromString(p1) 
   121 val p1_toks = Tok.fromString(p1) 
   118 val p1_ast = Block.parse_all(p1_toks)
   122 val p1_ast = Block.parse_all(p1_toks)
   119 println(p1_toks)
   123 println(p1_toks)
   120 println(p1_ast)
   124 println(p1_ast)
   121 
   125 
       
   126 val p1a = "{ x := 5; y := 8}"
       
   127 val p1a_toks = Tok.fromString(p1a) 
       
   128 val p1a_ast = Block.parse_all(p1a_toks)
       
   129 println(p1a_ast)
       
   130 
   122 val p2 = "5 = 6"
   131 val p2 = "5 = 6"
   123 val p2_toks = Tok.fromString(p2) 
   132 val p2_toks = Tok.fromString(p2) 
   124 val p2_ast = BExp.parse_all(p2_toks)
   133 val p2_ast = BExp.parse_all(p2_toks)
   125 println(p2_toks)
       
   126 println(p2_ast)
   134 println(p2_ast)
   127 
   135 
   128 val p2a = "true"
   136 val p2a = "true"
   129 val p2a_toks = Tok.fromString(p2a) 
   137 val p2a_toks = Tok.fromString(p2a) 
   130 val p2a_ast = BExp.parse_all(p2a_toks)
   138 val p2a_ast = BExp.parse_all(p2a_toks)
   131 println(p2a_toks)
       
   132 println(p2a_ast)
   139 println(p2a_ast)
   133 
   140 
   134 val p3 = "if true then skip else skip"
   141 val p3 = "if true then skip else skip"
   135 val p3_toks = Tok.fromString(p3) 
   142 val p3_toks = Tok.fromString(p3) 
   136 val p3_ast = Stmt.parse_all(p3_toks)
   143 val p3_ast = Stmt.parse_all(p3_toks)
   137 println(p3_toks)
       
   138 println(p3_ast)
   144 println(p3_ast)
   139 
   145 
   140 val p3a = "if true then x := 5 else x := 10"
   146 val p3a = "if true then x := 5 else x := 10"
   141 val p3a_toks = Tok.fromString(p3a) 
   147 val p3a_toks = Tok.fromString(p3a) 
   142 val p3a_ast = Stmt.parse_all(p3a_toks)
   148 val p3a_ast = Stmt.parse_all(p3a_toks)
   143 println(p3a_toks)
       
   144 println(p3a_ast)
   149 println(p3a_ast)
   145 
   150 
   146 val p3b = "if false then x := 5 else x := 10"
   151 val p3b = "if false then x := 5 else x := 10"
   147 val p3b_toks = Tok.fromString(p3b) 
   152 val p3b_toks = Tok.fromString(p3b) 
   148 val p3b_ast = Stmt.parse_all(p3b_toks)
   153 val p3b_ast = Stmt.parse_all(p3b_toks)
   149 println(p3b_toks)
       
   150 println(p3b_ast)
   154 println(p3b_ast)
   151 
   155 
       
   156 val p4 = """{ x := 5;
       
   157               y := 3;
       
   158               r := 0;
       
   159               while y = 0 do {
       
   160                  r := r + x;
       
   161                  y := y - 1
       
   162               } 
       
   163             }"""
       
   164 val p4_toks = Tok.fromString(p4) 
       
   165 val p4_ast = Block.parse_all(p4_toks)
       
   166 println(p4_ast)
   152 
   167 
       
   168 
       
   169 // interpreter
   153 type Env = Map[String, Int]
   170 type Env = Map[String, Int]
   154 
   171 
   155 def eval_bexp(b: BExp, env: Env) : Boolean = b match {
   172 def eval_bexp(b: BExp, env: Env) : Boolean = b match {
   156   case True => true
   173   case True => true
   157   case False => false
   174   case False => false