-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParser.y
136 lines (111 loc) · 4.52 KB
/
Parser.y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
{
module Parser(parse) where
import Tokenizer
import Datatypes
}
%name parser
%tokentype { Token }
%error { parseError }
%token
int { TokenInt $$ }
hexint { TokenHexInt $$ }
in { TokenIn }
and { TokenAnd }
or { TokenOr }
"?" { TokenQuestionMark }
":" { TokenColon }
"+" { TokenPlus }
"-" { TokenMinus }
"*" { TokenMultiply }
"**" { TokenPower }
"<<" { TokenShiftLeft }
">>" { TokenShiftRight }
">>>" { TokenShiftRightArithmetic }
"<" { TokenLessThan }
">" { TokenGreaterThan }
"==" { TokenEqual }
"&" { TokenBinaryAnd }
"|" { TokenBinaryOr }
"^" { TokenBinaryXor }
"=" { TokenAssignment }
"|=" { TokenAssignmentOr }
"&=" { TokenAssignmentAnd }
"+=" { TokenAssignmentPlus }
"-=" { TokenAssignmentMinus }
"*=" { TokenAssignmentMultiply }
"$" { TokenDollar }
"(" { TokenLParen }
")" { TokenRParen }
"[" { TokenLBracket }
"]" { TokenRBracket }
"," { TokenComma }
load_statement { TokenLoad }
store_statement { TokenStore }
constants { TokenConstants }
identifier { TokenIdentifier $$ }
%right "?" ":"
%left or
%left and
%left in
%left "==" "<" ">"
%left "|"
%left "^"
%left "&"
%left "<<" ">>" ">>>"
%left "+" "-"
%left "*"
%left "**"
%nonassoc UMINUS
%%
program : statement_list { Program (reverse $1) }
statement_list : statement_list statement { $2 : $1 }
| statement { [$1] }
statement : assignment { AssignmentStatement $1 }
| builtin { BuiltinStatement $1 }
builtin : load_statement { LoadStatement }
| store_statement { StoreStatement }
assignment : variable assignment_operator expression { Assignment $1 $2 $3 }
| register assignment_operator expression { Assignment $1 $2 $3 }
assignment_operator : "=" { AssignmentStraightUp }
| "|=" { AssignmentBinaryOp BitwiseOr }
| "&=" { AssignmentBinaryOp BitwiseAnd }
| "+=" { AssignmentBinaryOp Plus }
| "-=" { AssignmentBinaryOp Minus }
| "*=" { AssignmentBinaryOp Multiply }
expression : expression and expression { BinaryExpression BitwiseAnd $1 $3 }
| expression or expression { BinaryExpression BitwiseOr $1 $3 }
| expression "&" expression { BinaryExpression BitwiseAnd $1 $3 }
| expression "|" expression { BinaryExpression BitwiseOr $1 $3 }
| expression "^" expression { BinaryExpression BitwiseXor $1 $3 }
| expression "+" expression { BinaryExpression Plus $1 $3 }
| expression "-" expression { BinaryExpression Minus $1 $3 }
| expression "*" expression { BinaryExpression Multiply $1 $3 }
| expression "**" immediate { BinaryExpression Power $1 (ExpressionItem $3) }
| expression "<" expression { BinaryExpression LessThan $1 $3 }
| expression ">" expression { BinaryExpression GreaterThan $1 $3 }
| expression "==" expression { BinaryExpression EqualTo $1 $3 }
| expression "<<" immediate { BinaryExpression ShiftLeft $1 (ExpressionItem $3) }
| expression ">>" immediate { BinaryExpression ShiftRightArithmetic $1 (ExpressionItem $3) }
| expression ">>>" immediate { BinaryExpression ShiftRight $1 (ExpressionItem $3) }
| expression "?" expression ":" expression { TernaryExpression $1 $3 $5 }
| "-" expression %prec UMINUS { BinaryExpression Minus (ExpressionItem (Immediate 0)) $2 }
| expression in "[" list "]" { IsInList $1 $4 }
| "(" expression ")" { $2 }
| items { ExpressionItem $1 }
list : list "," expression { $3 : $1 }
| expression { [$1] }
items : variable { $1 }
| register { $1 }
| immediate { $1 }
| constant { $1 }
variable : identifier { Variable $1 }
register : "$" identifier { Register $2 }
constant : "$" constants "[" int "]" { Constant $4 }
immediate : int { Immediate $1 }
| hexint { Immediate $1 }
{
parseError :: [Token] -> a
parseError s = error ("Parse error" ++ show s)
parse :: String -> Program
parse = parser . tokenize
}