Imp_Parse.y 2.24 KB
Newer Older
Tadej Borovšak's avatar
Tadej Borovšak committed
1
2
3
4
-- vim: set syntax=happy autoindent ts=4 sts=4 sw=4 :

{
module Imp_Parse (imp_parse) where
Tadej Borovšak's avatar
Tadej Borovšak committed
5

Alex Simpson's avatar
Alex Simpson committed
6
7
8
9
import Imp_Lex
import Imp_AbsSyntax
}

Tadej Borovšak's avatar
Tadej Borovšak committed
10
%name imp_parse Prog
Alex Simpson's avatar
Alex Simpson committed
11
12
13
%tokentype { Token }
%error { parseError }

Tadej Borovšak's avatar
Tadej Borovšak committed
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
-- tokens
%token '('         { LPAREN  _         }
       ')'         { RPAREN  _         }
       ';'         { DELIM   _         }
       assign      { ASSIGN  _         }
       '+'         { BINOP   _ "+"     }
       '-'         { BINOP   _ "-"     }
       '*'         { BINOP   _ "*"     }
       '<'         { BINOP   _ "<"     }
       '~'         { BINOP   _ "=="    }
       if          { KEYWORD _ "if"    }
       then        { KEYWORD _ "then"  }
       else        { KEYWORD _ "else"  }
       while       { KEYWORD _ "while" }
       do          { KEYWORD _ "do"    }
       skip        { KEYWORD _ "skip"  }
       num         { NUM     _ $$      }
       bool        { BOOL    _ $$      }
       loc         { LOC     _ $$      }
Alex Simpson's avatar
Alex Simpson committed
33
34
35
36


-- precedence and associativity declarations, lowest precedence first

Tadej Borovšak's avatar
Tadej Borovšak committed
37
38
39
40
41
42
43
44
-- these are needed to break shift/reduce conflict in while/if statements
%nonassoc do then else
%right ';'

%nonassoc assign
%nonassoc '~' '<'
%left '+' '-'
%left '*'
Tadej Borovšak's avatar
Tadej Borovšak committed
45

Alex Simpson's avatar
Alex Simpson committed
46
47
%%

Tadej Borovšak's avatar
Tadej Borovšak committed
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Prog : {- empty -} { Skip }
     | Command     { $1 }

Command : skip                               { Skip              }
        | loc assign AExpr                   { Assign ($1, $3)   }
        | if BExpr then Command else Command { Cond ($2, $4, $6) }
        | while BExpr do Command             { While ($2, $4)    }
        | Command ';' Command                { Seq ($1, $3)      }
        | '(' Command ')'                    { $2                }

AExpr : loc             { Loc $1            }
      | num             { Num $1            }
      | AExpr '+' AExpr { AOp ("+", $1, $3) }
      | AExpr '-' AExpr { AOp ("-", $1, $3) }
      | AExpr '*' AExpr { AOp ("*", $1, $3) }
Alex Simpson's avatar
Alex Simpson committed
63

Tadej Borovšak's avatar
Tadej Borovšak committed
64
65
66
BExpr : bool            { Boolean $1        }
      | AExpr '<' AExpr { BOp ("<", $1, $3) }
      | AExpr '~' AExpr { BOp ("==", $1, $3) }
Tadej Borovšak's avatar
Tadej Borovšak committed
67

Alex Simpson's avatar
Alex Simpson committed
68
{
Tadej Borovšak's avatar
Tadej Borovšak committed
69

Alex Simpson's avatar
Alex Simpson committed
70
parseError :: [Token] -> a
Tadej Borovšak's avatar
Tadej Borovšak committed
71
72
73
74
75
76
parseError ts = error ("Parse error at " ++ location ++ "\n")
    where
        location = case ts of
            []    -> "end of file"
            (t:_) -> "line " ++ show l ++ ", column " ++ show c
                where AlexPn _ l c = pos t
Alex Simpson's avatar
Alex Simpson committed
77
78
79

}