cast 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/c.y ADDED
@@ -0,0 +1,935 @@
1
+ class C::Parser
2
+ ## shift/reduce conflict on "if (c) if (c) ; else ; else ;"
3
+ expect 1
4
+ rule
5
+
6
+ ## A.2.4 External definitions
7
+
8
+ ## Returns TranslationUnit
9
+ translation_unit
10
+ : external_declaration {result = TranslationUnit.new_at(val[0].pos, NodeChain[val[0]])}
11
+ | translation_unit external_declaration {result = val[0]; result.entities << val[1]}
12
+
13
+ ## Returns Declaration|FunctionDef
14
+ external_declaration
15
+ : function_definition {result = val[0]}
16
+ | declaration {result = val[0]}
17
+
18
+ ## Returns FunctionDef
19
+ function_definition
20
+ : declaration_specifiers declarator declaration_list compound_statement {result = make_function_def(val[0][0], val[0][1], val[1], val[2], val[3])}
21
+ | declaration_specifiers declarator compound_statement {result = make_function_def(val[0][0], val[0][1], val[1], nil , val[2])}
22
+
23
+ ## Returns [Declaration]
24
+ declaration_list
25
+ : declaration {result = [val[0]]}
26
+ | declaration_list declaration {result = val[0] << val[1]}
27
+
28
+ ## A.2.3 Statements
29
+
30
+ ## Returns Statement
31
+ statement
32
+ : labeled_statement {result = val[0]}
33
+ | compound_statement {result = val[0]}
34
+ | expression_statement {result = val[0]}
35
+ | selection_statement {result = val[0]}
36
+ | iteration_statement {result = val[0]}
37
+ | jump_statement {result = val[0]}
38
+
39
+ ## Returns Statement
40
+ labeled_statement
41
+ : identifier ':' statement {val[2].labels.unshift(PlainLabel.new_at(val[0].pos, val[0].val)); result = val[2]}
42
+ | 'case' constant_expression ':' statement {val[3].labels.unshift(Case .new_at(val[0].pos, val[1] )); result = val[3]}
43
+ | 'default' ':' statement {val[2].labels.unshift(Default .new_at(val[0].pos )); result = val[2]}
44
+ ## type names can also be used as labels
45
+ | typedef_name ':' statement {val[2].labels.unshift(PlainLabel.new_at(val[0].pos, val[0].name)); result = val[2]}
46
+
47
+ ## Returns Block
48
+ compound_statement
49
+ : '{' block_item_list '}' {result = Block.new_at(val[0].pos, val[1])}
50
+ | '{' '}' {result = Block.new_at(val[0].pos )}
51
+
52
+ ## Returns NodeChain[Declaration|Statement]
53
+ block_item_list
54
+ : block_item {result = NodeChain[val[0]]}
55
+ | block_item_list block_item {result = val[0] << val[1]}
56
+
57
+ ## Returns Declaration|Statement
58
+ block_item
59
+ : declaration {result = val[0]}
60
+ | statement {result = val[0]}
61
+
62
+ ## Returns ExpressionStatement
63
+ expression_statement
64
+ : expression ';' {result = ExpressionStatement.new_at(val[0].pos, val[0])}
65
+ | ';' {result = ExpressionStatement.new_at(val[0].pos )}
66
+
67
+ ## Returns Statement
68
+ selection_statement
69
+ : 'if' '(' expression ')' statement {result = If .new_at(val[0].pos, val[2], val[4] )}
70
+ | 'if' '(' expression ')' statement 'else' statement {result = If .new_at(val[0].pos, val[2], val[4], val[6])}
71
+ | 'switch' '(' expression ')' statement {result = Switch.new_at(val[0].pos, val[2], val[4] )}
72
+
73
+ ## Returns Statement
74
+ iteration_statement
75
+ : 'while' '(' expression ')' statement {result = While.new_at(val[0].pos, val[2], val[4] )}
76
+ | 'do' statement 'while' '(' expression ')' ';' {result = While.new_at(val[0].pos, val[4], val[1], :do => true )}
77
+ | 'for' '(' expression ';' expression ';' expression ')' statement {result = For.new_at(val[0].pos, val[2], val[4], val[6], val[8])}
78
+ | 'for' '(' expression ';' expression ';' ')' statement {result = For.new_at(val[0].pos, val[2], val[4], nil , val[7])}
79
+ | 'for' '(' expression ';' ';' expression ')' statement {result = For.new_at(val[0].pos, val[2], nil , val[5], val[7])}
80
+ | 'for' '(' expression ';' ';' ')' statement {result = For.new_at(val[0].pos, val[2], nil , nil , val[6])}
81
+ | 'for' '(' ';' expression ';' expression ')' statement {result = For.new_at(val[0].pos, nil , val[3], val[5], val[7])}
82
+ | 'for' '(' ';' expression ';' ')' statement {result = For.new_at(val[0].pos, nil , val[3], nil , val[6])}
83
+ | 'for' '(' ';' ';' expression ')' statement {result = For.new_at(val[0].pos, nil , nil , val[4], val[6])}
84
+ | 'for' '(' ';' ';' ')' statement {result = For.new_at(val[0].pos, nil , nil , nil , val[5])}
85
+ | 'for' '(' declaration expression ';' expression ')' statement {result = For.new_at(val[0].pos, val[2], val[3], val[5], val[7])}
86
+ | 'for' '(' declaration expression ';' ')' statement {result = For.new_at(val[0].pos, val[2], val[3], nil , val[6])}
87
+ | 'for' '(' declaration ';' expression ')' statement {result = For.new_at(val[0].pos, val[2], nil , val[4], val[6])}
88
+ | 'for' '(' declaration ';' ')' statement {result = For.new_at(val[0].pos, val[2], nil , nil , val[5])}
89
+
90
+ ## Returns Statement
91
+ jump_statement
92
+ : 'goto' identifier ';' {result = Goto .new_at(val[0].pos, val[1].val)}
93
+ | 'continue' ';' {result = Continue.new_at(val[0].pos )}
94
+ | 'break' ';' {result = Break .new_at(val[0].pos )}
95
+ | 'return' expression ';' {result = Return .new_at(val[0].pos, val[1] )}
96
+ | 'return' ';' {result = Return .new_at(val[0].pos )}
97
+ ## type names can also be used as labels
98
+ | 'goto' typedef_name ';' {result = Goto .new_at(val[0].pos, val[1].name)}
99
+
100
+ ## A.2.2 Declarations
101
+
102
+ ## Returns Declaration
103
+ declaration
104
+ : declaration_specifiers init_declarator_list ';' {result = make_declaration(val[0][0], val[0][1], val[1])}
105
+ | declaration_specifiers ';' {result = make_declaration(val[0][0], val[0][1], NodeArray[])}
106
+
107
+ ## Returns {Pos, [Symbol]}
108
+ declaration_specifiers
109
+ : storage_class_specifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]}
110
+ | storage_class_specifier {result = [val[0][0], [val[0][1]]]}
111
+ | type_specifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]}
112
+ | type_specifier {result = [val[0][0], [val[0][1]]]}
113
+ | type_qualifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]}
114
+ | type_qualifier {result = [val[0][0], [val[0][1]]]}
115
+ | function_specifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]}
116
+ | function_specifier {result = [val[0][0], [val[0][1]]]}
117
+
118
+ ## Returns NodeArray[Declarator]
119
+ init_declarator_list
120
+ : init_declarator {result = NodeArray[val[0]]}
121
+ | init_declarator_list ',' init_declarator {result = val[0] << val[2]}
122
+
123
+ ## Returns Declarator
124
+ init_declarator
125
+ : declarator {result = val[0]}
126
+ | declarator '=' initializer {val[0].init = val[2]; result = val[0]}
127
+
128
+ ## Returns [Pos, Symbol]
129
+ storage_class_specifier
130
+ : 'typedef' {result = [val[0].pos, val[0].val]}
131
+ | 'extern' {result = [val[0].pos, val[0].val]}
132
+ | 'static' {result = [val[0].pos, val[0].val]}
133
+ | 'auto' {result = [val[0].pos, val[0].val]}
134
+ | 'register' {result = [val[0].pos, val[0].val]}
135
+
136
+ ## Returns [Pos, Type|Symbol]
137
+ type_specifier
138
+ : 'void' {result = [val[0].pos, val[0].val]}
139
+ | 'char' {result = [val[0].pos, val[0].val]}
140
+ | 'short' {result = [val[0].pos, val[0].val]}
141
+ | 'int' {result = [val[0].pos, val[0].val]}
142
+ | 'long' {result = [val[0].pos, val[0].val]}
143
+ | 'float' {result = [val[0].pos, val[0].val]}
144
+ | 'double' {result = [val[0].pos, val[0].val]}
145
+ | 'signed' {result = [val[0].pos, val[0].val]}
146
+ | 'unsigned' {result = [val[0].pos, val[0].val]}
147
+ | '_Bool' {result = [val[0].pos, val[0].val]}
148
+ | '_Complex' {result = [val[0].pos, val[0].val]}
149
+ | '_Imaginary' {result = [val[0].pos, val[0].val]}
150
+ | struct_or_union_specifier {result = [val[0].pos, val[0] ]}
151
+ | enum_specifier {result = [val[0].pos, val[0] ]}
152
+ | typedef_name {result = [val[0].pos, val[0] ]}
153
+
154
+ ## Returns Struct|Union
155
+ struct_or_union_specifier
156
+ : struct_or_union identifier '{' struct_declaration_list '}' {result = val[0][1].new_at(val[0][0], val[1].val, val[3])}
157
+ | struct_or_union '{' struct_declaration_list '}' {result = val[0][1].new_at(val[0][0], nil , val[2])}
158
+ | struct_or_union identifier {result = val[0][1].new_at(val[0][0], val[1].val, nil )}
159
+ ## type names can also be used as struct identifiers
160
+ | struct_or_union typedef_name '{' struct_declaration_list '}' {result = val[0][1].new_at(val[0][0], val[1].name, val[3])}
161
+ | struct_or_union typedef_name {result = val[0][1].new_at(val[0][0], val[1].name, nil )}
162
+
163
+ ## Returns [Pos, Class]
164
+ struct_or_union
165
+ : 'struct' {result = [val[0].pos, Struct]}
166
+ | 'union' {result = [val[0].pos, Union ]}
167
+
168
+ ## Returns NodeArray[Declaration]
169
+ struct_declaration_list
170
+ : struct_declaration {result = NodeArray[val[0]]}
171
+ | struct_declaration_list struct_declaration {val[0] << val[1]; result = val[0]}
172
+
173
+ ## Returns Declaration
174
+ struct_declaration
175
+ : specifier_qualifier_list struct_declarator_list ';' {result = make_declaration(val[0][0], val[0][1], val[1])}
176
+
177
+ ## Returns {Pos, [Symbol]}
178
+ specifier_qualifier_list
179
+ : type_specifier specifier_qualifier_list {val[1][1] << val[0][1]; result = val[1]}
180
+ | type_specifier {result = [val[0][0], [val[0][1]]]}
181
+ | type_qualifier specifier_qualifier_list {val[1][1] << val[0][1]; result = val[1]}
182
+ | type_qualifier {result = [val[0][0], [val[0][1]]]}
183
+
184
+ ## Returns NodeArray[Declarator]
185
+ struct_declarator_list
186
+ : struct_declarator {result = NodeArray[val[0]]}
187
+ | struct_declarator_list ',' struct_declarator {result = val[0] << val[2]}
188
+
189
+ ## Returns Declarator
190
+ struct_declarator
191
+ : declarator {result = val[0]}
192
+ | declarator ':' constant_expression {result = val[0]; val[0].num_bits = val[2]}
193
+ | ':' constant_expression {result = Declarator.new_at(val[0].pos, :num_bits => val[1])}
194
+
195
+ ## Returns Enum
196
+ enum_specifier
197
+ : 'enum' identifier '{' enumerator_list '}' {result = Enum.new_at(val[0].pos, val[1].val, val[3])}
198
+ | 'enum' '{' enumerator_list '}' {result = Enum.new_at(val[0].pos, nil , val[2])}
199
+ | 'enum' identifier '{' enumerator_list ',' '}' {result = Enum.new_at(val[0].pos, val[1].val, val[3])}
200
+ | 'enum' '{' enumerator_list ',' '}' {result = Enum.new_at(val[0].pos, nil , val[2])}
201
+ | 'enum' identifier {result = Enum.new_at(val[0].pos, val[1].val, nil )}
202
+ ## type names can also be used as enum names
203
+ | 'enum' typedef_name '{' enumerator_list '}' {result = Enum.new_at(val[0].pos, val[1].name, val[3])}
204
+ | 'enum' typedef_name '{' enumerator_list ',' '}' {result = Enum.new_at(val[0].pos, val[1].name, val[3])}
205
+ | 'enum' typedef_name {result = Enum.new_at(val[0].pos, val[1].name, nil )}
206
+
207
+ ## Returns NodeArray[Enumerator]
208
+ enumerator_list
209
+ : enumerator {result = NodeArray[val[0]]}
210
+ | enumerator_list ',' enumerator {result = val[0] << val[2]}
211
+
212
+ ## Returns Enumerator
213
+ enumerator
214
+ : enumeration_constant {result = Enumerator.new_at(val[0].pos, val[0].val, nil )}
215
+ | enumeration_constant '=' constant_expression {result = Enumerator.new_at(val[0].pos, val[0].val, val[2])}
216
+
217
+ ## Returns [Pos, Symbol]
218
+ type_qualifier
219
+ : 'const' {result = [val[0].pos, val[0].val]}
220
+ | 'restrict' {result = [val[0].pos, val[0].val]}
221
+ | 'volatile' {result = [val[0].pos, val[0].val]}
222
+
223
+ ## Returns [Pos, Symbol]
224
+ function_specifier
225
+ : 'inline' {result = [val[0].pos, val[0].val]}
226
+
227
+ ## Returns Declarator
228
+ declarator
229
+ : pointer direct_declarator {result = add_decl_type(val[1], val[0])}
230
+ | direct_declarator {result = val[0]}
231
+
232
+ ## Returns Declarator
233
+ direct_declarator
234
+ : identifier {result = Declarator.new_at(val[0].pos, nil, val[0].val)}
235
+ | '(' declarator ')' {result = val[1]}
236
+ | direct_declarator '[' type_qualifier_list assignment_expression ']' {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
237
+ | direct_declarator '[' type_qualifier_list ']' {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
238
+ | direct_declarator '[' assignment_expression ']' {result = add_decl_type(val[0], Array.new_at(val[0].pos, nil, val[2]))}
239
+ | direct_declarator '[' ']' {result = add_decl_type(val[0], Array.new_at(val[0].pos ))}
240
+ | direct_declarator '[' 'static' type_qualifier_list assignment_expression ']' {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
241
+ | direct_declarator '[' 'static' assignment_expression ']' {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
242
+ | direct_declarator '[' type_qualifier_list 'static' assignment_expression ']' {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
243
+ | direct_declarator '[' type_qualifier_list '*' ']' {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
244
+ | direct_declarator '[' '*' ']' {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
245
+ | direct_declarator '(' parameter_type_list ')' {result = add_decl_type(val[0], Function.new_at(val[0].pos, nil, param_list(*val[2]), :var_args => val[2][1]))}
246
+ | direct_declarator '(' identifier_list ')' {result = add_decl_type(val[0], Function.new_at(val[0].pos, nil, val[2]))}
247
+ | direct_declarator '(' ')' {result = add_decl_type(val[0], Function.new_at(val[0].pos ))}
248
+
249
+ ## Returns Pointer
250
+ pointer
251
+ : '*' type_qualifier_list {result = add_type_quals(Pointer.new_at(val[0].pos), val[1][1]) }
252
+ | '*' {result = Pointer.new_at(val[0].pos) }
253
+ | '*' type_qualifier_list pointer {p = add_type_quals(Pointer.new_at(val[0].pos), val[1][1]); val[2].direct_type = p; result = val[2]}
254
+ | '*' pointer {p = Pointer.new_at(val[0].pos) ; val[1].direct_type = p; result = val[1]}
255
+
256
+ ## Returns {Pos, [Symbol]}
257
+ type_qualifier_list
258
+ : type_qualifier {result = [val[0][0], [val[0][1]]]}
259
+ | type_qualifier_list type_qualifier {val[0][1] << val[1][1]; result = val[0]}
260
+
261
+ ## Returns [NodeArray[Parameter], var_args?]
262
+ parameter_type_list
263
+ : parameter_list {result = [val[0], false]}
264
+ | parameter_list ',' '...' {result = [val[0], true ]}
265
+
266
+ ## Returns NodeArray[Parameter]
267
+ parameter_list
268
+ : parameter_declaration {result = NodeArray[val[0]]}
269
+ | parameter_list ',' parameter_declaration {result = val[0] << val[2]}
270
+
271
+ ## Returns Parameter
272
+ parameter_declaration
273
+ : declaration_specifiers declarator {ind_type = val[1].indirect_type and ind_type.detach
274
+ result = make_parameter(val[0][0], val[0][1], ind_type, val[1].name)}
275
+ | declaration_specifiers abstract_declarator {result = make_parameter(val[0][0], val[0][1], val[1] , nil )}
276
+ | declaration_specifiers {result = make_parameter(val[0][0], val[0][1], nil , nil )}
277
+
278
+ ## Returns NodeArray[Parameter]
279
+ identifier_list
280
+ : identifier {result = NodeArray[Parameter.new_at(val[0].pos, nil, val[0].val)]}
281
+ | identifier_list ',' identifier {result = val[0] << Parameter.new_at(val[2].pos, nil, val[2].val)}
282
+
283
+ ## Returns Type
284
+ type_name
285
+ : specifier_qualifier_list abstract_declarator {val[1].direct_type = make_direct_type(val[0][0], val[0][1]); result = val[1]}
286
+ | specifier_qualifier_list {result = make_direct_type(val[0][0], val[0][1]) }
287
+
288
+ ## Returns Type
289
+ abstract_declarator
290
+ : pointer {result = val[0]}
291
+ | pointer direct_abstract_declarator {val[1].direct_type = val[0]; result = val[1]}
292
+ | direct_abstract_declarator {result = val[0]}
293
+
294
+ ## Returns Type
295
+ direct_abstract_declarator
296
+ : '(' abstract_declarator ')' {result = val[1]}
297
+ | direct_abstract_declarator '[' assignment_expression ']' {val[0].direct_type = Array.new_at(val[0].pos, nil, val[2]); result = val[0]}
298
+ | direct_abstract_declarator '[' ']' {val[0].direct_type = Array.new_at(val[0].pos, nil, nil ); result = val[0]}
299
+ | '[' assignment_expression ']' {result = Array.new_at(val[0].pos, nil, val[1])}
300
+ | '[' ']' {result = Array.new_at(val[0].pos )}
301
+ | direct_abstract_declarator '[' '*' ']' {val[0].direct_type = Array.new_at(val[0].pos); result = val[0]} # TODO
302
+ | '[' '*' ']' {result = Array.new_at(val[0].pos)} # TODO
303
+ | direct_abstract_declarator '(' parameter_type_list ')' {val[0].direct_type = Function.new_at(val[0].pos, nil, param_list(*val[2]), val[2][1]); result = val[0]}
304
+ | direct_abstract_declarator '(' ')' {val[0].direct_type = Function.new_at(val[0].pos ); result = val[0]}
305
+ | '(' parameter_type_list ')' {result = Function.new_at(val[0].pos, nil, param_list(*val[1]), val[1][1])}
306
+ | '(' ')' {result = Function.new_at(val[0].pos )}
307
+
308
+ ## Returns CustomType
309
+ typedef_name
310
+ #: identifier -- insufficient since we must distinguish between type
311
+ # names and var names (otherwise we have a conflict)
312
+ : TYPE_ID {result = CustomType.new_at(val[0].pos, val[0].val)}
313
+
314
+ ## Returns Expression
315
+ initializer
316
+ : assignment_expression {result = val[0]}
317
+ | '{' initializer_list '}' {result = CompoundLiteral.new_at(val[0].pos, nil, val[1])}
318
+ | '{' initializer_list ',' '}' {result = CompoundLiteral.new_at(val[0].pos, nil, val[1])}
319
+
320
+ ## Returns NodeArray[MemberInit]
321
+ initializer_list
322
+ : designation initializer {result = NodeArray[MemberInit.new_at(val[0][0] , val[0][1], val[1])]}
323
+ | initializer {result = NodeArray[MemberInit.new_at(val[0].pos, nil , val[0])]}
324
+ | initializer_list ',' designation initializer {result = val[0] << MemberInit.new_at(val[2][0] , val[2][1], val[3])}
325
+ | initializer_list ',' initializer {result = val[0] << MemberInit.new_at(val[2].pos, nil , val[2])}
326
+
327
+ ## Returns {Pos, NodeArray[Expression|Token]}
328
+ designation
329
+ : designator_list '=' {result = val[0]}
330
+
331
+ ## Returns {Pos, NodeArray[Expression|Token]}
332
+ designator_list
333
+ : designator {result = val[0]; val[0][1] = NodeArray[val[0][1]]}
334
+ | designator_list designator {result = val[0]; val[0][1] << val[1][1]}
335
+
336
+ ## Returns {Pos, Expression|Member}
337
+ designator
338
+ : '[' constant_expression ']' {result = [val[1].pos, val[1] ]}
339
+ | '.' identifier {result = [val[1].pos, Member.new_at(val[1].pos, val[1].val)]}
340
+
341
+ ### A.2.1 Expressions
342
+
343
+ ## Returns Expression
344
+ primary_expression
345
+ : identifier {result = Variable.new_at(val[0].pos, val[0].val)}
346
+ | constant {result = val[0]}
347
+ | string_literal {result = val[0]}
348
+ | '(' expression ')' {result = val[1]}
349
+
350
+ ## Returns Expression
351
+ postfix_expression
352
+ : primary_expression {result = val[0]}
353
+ | postfix_expression '[' expression ']' {result = Index .new_at(val[0].pos, val[0], val[2])}
354
+ | postfix_expression '(' argument_expression_list ')' {result = Call .new_at(val[0].pos, val[0], val[2] )}
355
+ | postfix_expression '(' ')' {result = Call .new_at(val[0].pos, val[0], NodeArray[])}
356
+ | postfix_expression '.' identifier {result = Dot .new_at(val[0].pos, val[0], Member.new(val[2].val))}
357
+ | postfix_expression '->' identifier {result = Arrow .new_at(val[0].pos, val[0], Member.new(val[2].val))}
358
+ | postfix_expression '++' {result = PostInc .new_at(val[0].pos, val[0] )}
359
+ | postfix_expression '--' {result = PostDec .new_at(val[0].pos, val[0] )}
360
+ | '(' type_name ')' '{' initializer_list '}' {result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])}
361
+ | '(' type_name ')' '{' initializer_list ',' '}' {result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])}
362
+
363
+ ## Returns [Expression]
364
+ argument_expression_list
365
+ : assignment_expression {result = NodeArray[val[0]]}
366
+ | argument_expression_list ',' assignment_expression {result = val[0] << val[2]}
367
+
368
+ ## Returns Expression
369
+ unary_expression
370
+ : postfix_expression {result = val[0]}
371
+ | '++' unary_expression {result = PreInc.new_at(val[0].pos, val[1])}
372
+ | '--' unary_expression {result = PreDec.new_at(val[0].pos, val[1])}
373
+ | unary_operator cast_expression {result = val[0][0].new_at(val[0][1], val[1])}
374
+ | 'sizeof' unary_expression {result = Sizeof.new_at(val[0].pos, val[1])}
375
+ | 'sizeof' '(' type_name ')' {result = Sizeof.new_at(val[0].pos, val[2])}
376
+
377
+ ## Returns [Class, Pos]
378
+ unary_operator
379
+ : '&' {result = [Address , val[0].pos]}
380
+ | '*' {result = [Dereference, val[0].pos]}
381
+ | '+' {result = [Positive , val[0].pos]}
382
+ | '-' {result = [Negative , val[0].pos]}
383
+ | '~' {result = [BitNot , val[0].pos]}
384
+ | '!' {result = [Not , val[0].pos]}
385
+
386
+ ## Returns Expression
387
+ cast_expression
388
+ : unary_expression {result = val[0]}
389
+ | '(' type_name ')' cast_expression {result = Cast.new_at(val[0].pos, val[1], val[3])}
390
+
391
+ ## Returns Expression
392
+ multiplicative_expression
393
+ : cast_expression {result = val[0]}
394
+ | multiplicative_expression '*' cast_expression {result = Multiply.new_at(val[0].pos, val[0], val[2])}
395
+ | multiplicative_expression '/' cast_expression {result = Divide .new_at(val[0].pos, val[0], val[2])}
396
+ | multiplicative_expression '%' cast_expression {result = Mod .new_at(val[0].pos, val[0], val[2])}
397
+
398
+ ## Returns Expression
399
+ additive_expression
400
+ : multiplicative_expression {result = val[0]}
401
+ | additive_expression '+' multiplicative_expression {result = Add .new_at(val[0].pos, val[0], val[2])}
402
+ | additive_expression '-' multiplicative_expression {result = Subtract.new_at(val[0].pos, val[0], val[2])}
403
+
404
+ ## Returns Expression
405
+ shift_expression
406
+ : additive_expression {result = val[0]}
407
+ | shift_expression '<<' additive_expression {result = ShiftLeft .new_at(val[0].pos, val[0], val[2])}
408
+ | shift_expression '>>' additive_expression {result = ShiftRight.new_at(val[0].pos, val[0], val[2])}
409
+
410
+ ## Returns Expression
411
+ relational_expression
412
+ : shift_expression {result = val[0]}
413
+ | relational_expression '<' shift_expression {result = Less.new_at(val[0].pos, val[0], val[2])}
414
+ | relational_expression '>' shift_expression {result = More.new_at(val[0].pos, val[0], val[2])}
415
+ | relational_expression '<=' shift_expression {result = LessOrEqual.new_at(val[0].pos, val[0], val[2])}
416
+ | relational_expression '>=' shift_expression {result = MoreOrEqual.new_at(val[0].pos, val[0], val[2])}
417
+
418
+ ## Returns Expression
419
+ equality_expression
420
+ : relational_expression {result = val[0]}
421
+ | equality_expression '==' relational_expression {result = Equal .new_at(val[0].pos, val[0], val[2])}
422
+ | equality_expression '!=' relational_expression {result = NotEqual.new_at(val[0].pos, val[0], val[2])}
423
+
424
+ ## Returns Expression
425
+ and_expression
426
+ : equality_expression {result = val[0]}
427
+ | and_expression '&' equality_expression {result = BitAnd.new_at(val[0].pos, val[0], val[2])}
428
+
429
+ ## Returns Expression
430
+ exclusive_or_expression
431
+ : and_expression {result = val[0]}
432
+ | exclusive_or_expression '^' and_expression {result = BitXor.new_at(val[0].pos, val[0], val[2])}
433
+
434
+ ## Returns Expression
435
+ inclusive_or_expression
436
+ : exclusive_or_expression {result = val[0]}
437
+ | inclusive_or_expression '|' exclusive_or_expression {result = BitOr.new_at(val[0].pos, val[0], val[2])}
438
+
439
+ ## Returns Expression
440
+ logical_and_expression
441
+ : inclusive_or_expression {result = val[0]}
442
+ | logical_and_expression '&&' inclusive_or_expression {result = And.new_at(val[0].pos, val[0], val[2])}
443
+
444
+ ## Returns Expression
445
+ logical_or_expression
446
+ : logical_and_expression {result = val[0]}
447
+ | logical_or_expression '||' logical_and_expression {result = Or.new_at(val[0].pos, val[0], val[2])}
448
+
449
+ ## Returns Expression
450
+ conditional_expression
451
+ : logical_or_expression {result = val[0]}
452
+ | logical_or_expression '?' expression ':' conditional_expression {result = Conditional.new_at(val[0].pos, val[0], val[2], val[4])}
453
+
454
+ ## Returns Expression
455
+ assignment_expression
456
+ : conditional_expression {result = val[0]}
457
+ | unary_expression assignment_operator assignment_expression {result = val[1].new_at(val[0].pos, val[0], val[2])}
458
+
459
+ ## Returns Class
460
+ assignment_operator
461
+ : '=' {result = Assign}
462
+ | '*=' {result = MultiplyAssign}
463
+ | '/=' {result = DivideAssign}
464
+ | '%=' {result = ModAssign}
465
+ | '+=' {result = AddAssign}
466
+ | '-=' {result = SubtractAssign}
467
+ | '<<=' {result = ShiftLeftAssign}
468
+ | '>>=' {result = ShiftRightAssign}
469
+ | '&=' {result = BitAndAssign}
470
+ | '^=' {result = BitXorAssign}
471
+ | '|=' {result = BitOrAssign}
472
+
473
+ ## Returns Expression
474
+ expression
475
+ : assignment_expression {result = val[0]}
476
+ | expression ',' assignment_expression {
477
+ if val[0].is_a? Comma
478
+ if val[2].is_a? Comma
479
+ val[0].exprs.push(*val[2].exprs)
480
+ else
481
+ val[0].exprs << val[2]
482
+ end
483
+ result = val[0]
484
+ else
485
+ if val[2].is_a? Comma
486
+ val[2].exprs.unshift(val[0])
487
+ val[2].pos = val[0].pos
488
+ result = val[2]
489
+ else
490
+ result = Comma.new_at(val[0].pos, NodeArray[val[0], val[2]])
491
+ end
492
+ end
493
+ }
494
+
495
+ ## Returns Expression
496
+ constant_expression
497
+ : conditional_expression {result = val[0]}
498
+
499
+ ### A.1.1 -- Lexical elements
500
+ ##
501
+ ## token
502
+ ## : keyword (raw string)
503
+ ## | identifier expanded below
504
+ ## | constant expanded below
505
+ ## | string_literal expanded below
506
+ ## | punctuator (raw string)
507
+ ##
508
+ ## preprocessing-token (skip)
509
+
510
+ ## Returns Token
511
+ identifier
512
+ : ID {result = val[0]}
513
+
514
+ ## Returns Literal
515
+ constant
516
+ : INT {result = IntLiteral.new_at(val[0].pos, val[0].val)}
517
+ | FLOAT {result = FloatLiteral.new_at(val[0].pos, val[0].val)}
518
+ #| enumeration_constant -- these are parsed as identifiers at all
519
+ # places the `constant' nonterminal appears
520
+ | CHAR {result = CharLiteral.new_at(val[0].pos, val[0].val)}
521
+
522
+ ## Returns Token
523
+ enumeration_constant
524
+ : ID {result = val[0]}
525
+
526
+ ## Returns StringLiteral
527
+ string_literal
528
+ : STRING {result = StringLiteral.new_at(val[0].pos, val[0].val)}
529
+
530
+ ---- inner
531
+ ## A.1.9 -- Preprocessing numbers -- skip
532
+ ## A.1.8 -- Header names -- skip
533
+
534
+ ## A.1.7 -- Puncuators -- we don't bother with {##,#,%:,%:%:} since
535
+ ## we don't do preprocessing
536
+ @@punctuators = %r'\+\+|-[->]|&&|\|\||\.\.\.|(?:<<|>>|[<>=!*/%+\-&^|])=?|[\[\](){}.~?:;,]'
537
+ @@digraphs = %r'<[:%]|[:%]>'
538
+
539
+ ## A.1.6 -- String Literals -- simple for us because we don't decode
540
+ ## the string (and indeed accept some illegal strings)
541
+ @@string_literal = %r'L?"(?:[^\\]|\\.)*?"'m
542
+
543
+ ## A.1.5 -- Constants
544
+ @@decimal_floating_constant = %r'(?:(?:\d*\.\d+|\d+\.)(?:e[-+]?\d+)?|\d+e[-+]?\d+)[fl]?'i
545
+ @@hexadecimal_floating_constant = %r'0x(?:(?:[0-9a-f]*\.[0-9a-f]+|[0-9a-f]+\.)|[0-9a-f]+)p[-+]?\d+[fl]?'i
546
+
547
+ @@integer_constant = %r'(?:[1-9][0-9]*|0x[0-9a-f]+|0[0-7]*)(?:ul?l?|ll?u?)?'i
548
+ @@floating_constant = %r'#{@@decimal_floating_constant}|#{@@hexadecimal_floating_constant}'
549
+ @@enumeration_constant = %r'[a-zA-Z_\\][a-zA-Z_\\0-9]*'
550
+ @@character_constant = %r"L?'(?:[^\\]|\\.)+?'"
551
+ ## (note that as with string-literals, we accept some illegal
552
+ ## character-constants)
553
+
554
+ ## A.1.4 -- Universal character names -- skip
555
+
556
+ ## A.1.3 -- Identifiers -- skip, since an identifier is lexically
557
+ ## identical to an enumeration constant
558
+
559
+ ## A.1.2 Keywords
560
+ keywords = %w'auto break case char const continue default do
561
+ double else enum extern float for goto if inline int long register
562
+ restrict return short signed sizeof static struct switch typedef union
563
+ unsigned void volatile while _Bool _Complex _Imaginary'
564
+ @@keywords = %r"#{keywords.join('|')}"
565
+
566
+ def initialize
567
+ @type_names = ::Set.new
568
+
569
+ @warning_proc = lambda{}
570
+ @pos = C::Node::Pos.new(nil, 1, 0)
571
+ end
572
+ def initialize_copy x
573
+ @pos = x.pos.dup
574
+ @type_names = x.type_names.dup
575
+ end
576
+ attr_accessor :pos, :type_names
577
+
578
+ def parse str
579
+ if str.respond_to? :read
580
+ str = str.read
581
+ end
582
+ @str = str
583
+ begin
584
+ return do_parse
585
+ rescue ParseError => e
586
+ e.set_backtrace(caller)
587
+ raise
588
+ end
589
+ end
590
+
591
+ ### Obsolete? Todo? What was I thinking?
592
+ def on_error error_token_id, error_value, value_stack
593
+ if error_value == '$'
594
+ parse_error @pos, "unexpected EOF"
595
+ else
596
+ parse_error(error_value.pos,
597
+ "parse error on #{error_value.val.inspect}")
598
+ end
599
+ end
600
+
601
+ private
602
+
603
+ class Token
604
+ attr_accessor :pos, :val
605
+ def initialize pos, val
606
+ @pos = pos
607
+ @val = val
608
+ end
609
+ end
610
+ def eat str
611
+ lines = str.split(/\r\n|[\r\n]/, -1)
612
+ if lines.length == 1
613
+ @pos.col_num += lines[0].length
614
+ else
615
+ @pos.line_num += lines.length - 1
616
+ @pos.col_num = lines[-1].length
617
+ end
618
+ end
619
+ def next_token
620
+ return nil if @str == ''
621
+ case @str
622
+ when %r'\A\s+'
623
+ ## whitespace
624
+ eat $&
625
+ @str[0...$&.length] = ''
626
+ return next_token
627
+ when %r'\A/\*.*?\*/'m
628
+ ## comment
629
+ eat $&
630
+ @str[0...$&.length] = ''
631
+ return next_token
632
+ when %r'\A#{@@keywords}\b'
633
+ ## keyword
634
+ ret = [$&, $&.to_sym]
635
+ when %r'\A#{@@enumeration_constant}'
636
+ ## identifier, enumeration_constant, or typedef_name
637
+ case
638
+ when @type_names.include?($&)
639
+ ret = [:TYPE_ID, $&]
640
+ else
641
+ ret = [:ID, $&]
642
+ end
643
+ when %r'\A#{@@floating_constant}'
644
+ ## floating-constant
645
+ ret = [:FLOAT, $&.to_f]
646
+ when %r'\A#{@@integer_constant}'
647
+ ## integer-constant
648
+ ret = [:INT, $&.to_i]
649
+ when %r'\A#{@@character_constant}'
650
+ ## character constant
651
+ ret = [:CHAR, $&[1...-1]]
652
+ when %r'\A#{@@string_literal}'
653
+ ## string-literal
654
+ ret = [:STRING, $&[1...-1]]
655
+ when %r'\A#{@@punctuators}'
656
+ ## punctuator
657
+ ret = [$&, $&]
658
+ when %r'\A#{@@digraphs}'
659
+ ## digraph
660
+ case $&
661
+ when '<:'
662
+ ret = ['[', '[']
663
+ when ':>'
664
+ ret = [']', ']']
665
+ when '<%'
666
+ ret = ['{', '{']
667
+ when '%>'
668
+ ret = ['}', '}']
669
+ else
670
+ raise 'bug'
671
+ end
672
+ else
673
+ if @str.length > 40
674
+ s = @str[0...37] << '...'
675
+ else
676
+ s = @str
677
+ end
678
+ raise ParseError, "#{@pos}: invalid token: #{s.inspect}"
679
+ end
680
+ ret[1] = Token.new(@pos.dup, ret[1])
681
+ eat $&
682
+ @str[0...$&.length] = ''
683
+ return ret
684
+ end
685
+
686
+ private
687
+
688
+ #### Helper methods
689
+
690
+ ## Make a Declaration from the given specs and declarators.
691
+ def make_declaration pos, specs, declarators
692
+ specs.all?{|x| x.is_a?(Symbol) || x.is_a?(Type)} or raise specs.map{|x| x.class}.inspect
693
+ decl = Declaration.new_at(pos, nil, declarators)
694
+
695
+ ## set storage class
696
+ storage_classes = specs.find_all do |x|
697
+ [:typedef, :extern, :static, :auto, :register].include? x
698
+ end
699
+ ## 6.7.1p2: at most, one storage-class specifier may be given in
700
+ ## the declaration specifiers in a declaration
701
+ storage_classes.length <= 1 or
702
+ begin
703
+ if declarators.length == 0
704
+ for_name = ''
705
+ else
706
+ for_name = "for `#{declarators[0].name}'"
707
+ end
708
+ parse_error pos, "multiple or duplicate storage classes given #{for_name}'"
709
+ end
710
+ decl.storage = storage_classes[0]
711
+
712
+ ## set type (specifiers, qualifiers)
713
+ decl.type = make_direct_type(pos, specs)
714
+
715
+ ## set function specifiers
716
+ decl.inline = specs.include?(:inline)
717
+
718
+ ## look for new type names
719
+ if decl.typedef?
720
+ decl.declarators.each do |d|
721
+ if d.name
722
+ @type_names << d.name
723
+ end
724
+ end
725
+ end
726
+
727
+ return decl
728
+ end
729
+
730
+ def make_function_def pos, specs, func_declarator, decl_list, defn
731
+ add_decl_type(func_declarator, make_direct_type(pos, specs))
732
+
733
+ ## get types from decl_list if necessary
734
+ function = func_declarator.indirect_type
735
+ function.is_a? Function or
736
+ parse_error pos, "non function type for function `#{func_declarator.name}'"
737
+ params = function.params
738
+ if decl_list
739
+ params.all?{|p| p.type.nil?} or
740
+ parse_error pos, "both prototype and declaration list given for `#{func_declarator.name}'"
741
+ decl_list.each do |declaration|
742
+ declaration.declarators.each do |declarator|
743
+ param = params.find{|p| p.name == declarator.name} or
744
+ parse_error pos, "no parameter named #{declarator.name}"
745
+ if declarator.indirect_type
746
+ param.type = declarator.indirect_type
747
+ param.type.direct_type = declaration.type.dup
748
+ else
749
+ param.type = declaration.type.dup
750
+ end
751
+ end
752
+ end
753
+ params.all?{|p| p.type} or
754
+ begin
755
+ s = params.find_all{|p| p.type.nil?}.map{|p| "`#{p.name}'"}.join(' and ')
756
+ parse_error pos, "types missing for parameters #{s}"
757
+ end
758
+ end
759
+
760
+ fd = FunctionDef.new_at(pos,
761
+ function.detach,
762
+ func_declarator.name,
763
+ defn,
764
+ :no_prototype => !decl_list.nil?)
765
+
766
+ ## set storage class
767
+ ## 6.9.1p4: only extern or static allowed
768
+ specs.each do |s|
769
+ [:typedef, :auto, :register].include?(s) and
770
+ "`#{s}' illegal for function"
771
+ end
772
+ storage_classes = specs.find_all do |s|
773
+ s == :extern || s == :static
774
+ end
775
+ ## 6.7.1p2: at most, one storage-class specifier may be given in
776
+ ## the declaration specifiers in a declaration
777
+ storage_classes.length <= 1 or
778
+ "multiple or duplicate storage classes given for `#{declarator.name}'"
779
+ fd.storage = storage_classes[0] if storage_classes[0]
780
+
781
+ ## set function specifiers
782
+ ## 6.7.4p5 'inline' can be repeated
783
+ fd.inline = specs.include?(:inline)
784
+
785
+ return fd
786
+ end
787
+
788
+ ## Make a direct type from the list of type specifiers and type
789
+ ## qualifiers.
790
+ def make_direct_type pos, specs
791
+ specs_order = [:signed, :unsigned, :short, :long, :double, :void,
792
+ :char, :int, :float, :_Bool, :_Complex, :_Imaginary]
793
+
794
+ type_specs = specs.find_all do |x|
795
+ specs_order.include?(x) || !x.is_a?(Symbol)
796
+ end
797
+ type_specs.sort! do |a, b|
798
+ (specs_order.index(a)||100) <=> (specs_order.index(b)||100)
799
+ end
800
+
801
+ ## set type specifiers
802
+ ## 6.7.2p2: the specifier list should be one of these
803
+ type =
804
+ case type_specs
805
+ when [:void]
806
+ Void.new
807
+ when [:char]
808
+ Char.new
809
+ when [:signed, :char]
810
+ Char.new :signed => true
811
+ when [:unsigned, :char]
812
+ Char.new :signed => false
813
+ when [:short], [:signed, :short], [:short, :int],
814
+ [:signed, :short, :int]
815
+ Int.new :longness => -1
816
+ when [:unsigned, :short], [:unsigned, :short, :int]
817
+ Int.new :unsigned => true, :longness => -1
818
+ when [:int], [:signed], [:signed, :int]
819
+ Int.new
820
+ when [:unsigned], [:unsigned, :int]
821
+ Int.new :unsigned => true
822
+ when [:long], [:signed, :long], [:long, :int],
823
+ [:signed, :long, :int]
824
+ Int.new :longness => 1
825
+ when [:unsigned, :long], [:unsigned, :long, :int]
826
+ Int.new :longness => 1, :unsigned => true
827
+ when [:long, :long], [:signed, :long, :long],
828
+ [:long, :long, :int], [:signed, :long, :long, :int]
829
+ Int.new :longness => 2
830
+ when [:unsigned, :long, :long], [:unsigned, :long, :long, :int]
831
+ Int.new :longness => 2, :unsigned => true
832
+ when [:float]
833
+ Float.new
834
+ when [:double]
835
+ Float.new :longness => 1
836
+ when [:long, :double]
837
+ Float.new :longness => 2
838
+ when [:_Bool]
839
+ Bool.new
840
+ when [:float, :_Complex]
841
+ Complex.new
842
+ when [:double, :_Complex]
843
+ Complex.new :longness => 1
844
+ when [:long, :double, :_Complex]
845
+ Complex.new :longness => 2
846
+ when [:float, :_Imaginary]
847
+ Imaginary.new
848
+ when [:double, :_Imaginary]
849
+ Imaginary.new :longness => 1
850
+ when [:long, :double, :_Imaginary]
851
+ Imaginary.new :longness => 2
852
+ else
853
+ if type_specs.length == 1 &&
854
+ [CustomType, Struct, Union, Enum].any?{|c| type_specs[0].is_a? c}
855
+ type_specs[0]
856
+ else
857
+ if type_specs == []
858
+ parse_error pos, "no type specifiers given"
859
+ else
860
+ parse_error pos, "invalid type specifier combination: #{type_specs.join(' ')}"
861
+ end
862
+ end
863
+ end
864
+ type.pos ||= pos
865
+
866
+ ## set type qualifiers
867
+ ## 6.7.3p4: type qualifiers can be repeated
868
+ type.const = specs.any?{|x| x.equal? :const }
869
+ type.restrict = specs.any?{|x| x.equal? :restrict}
870
+ type.volatile = specs.any?{|x| x.equal? :volatile}
871
+
872
+ return type
873
+ end
874
+
875
+ def make_parameter pos, specs, indirect_type, name
876
+ type = indirect_type
877
+ if type
878
+ type.direct_type = make_direct_type(pos, specs)
879
+ else
880
+ type = make_direct_type(pos, specs)
881
+ end
882
+ [:typedef, :extern, :static, :auto, :inline].each do |sym|
883
+ specs.include? sym and
884
+ parse_error pos, "parameter `#{declarator.name}' declared `#{sym}'"
885
+ end
886
+ return Parameter.new_at(pos, type, name,
887
+ :register => specs.include?(:register))
888
+ end
889
+
890
+ def add_type_quals type, quals
891
+ type.const = quals.include?(:const )
892
+ type.restrict = quals.include?(:restrict)
893
+ type.volatile = quals.include?(:volatile)
894
+ return type
895
+ end
896
+
897
+ ## Add te given type as the "most direct" type to the given
898
+ ## declarator. Return the declarator.
899
+ def add_decl_type declarator, type
900
+ if declarator.indirect_type
901
+ declarator.indirect_type.direct_type = type
902
+ else
903
+ declarator.indirect_type = type
904
+ end
905
+ return declarator
906
+ end
907
+
908
+ def param_list params, var_args
909
+ if params.length == 1 &&
910
+ params[0].type.is_a?(Void) &&
911
+ params[0].name.nil?
912
+ return NodeArray[]
913
+ elsif params.empty?
914
+ return nil
915
+ else
916
+ return params
917
+ end
918
+ end
919
+
920
+ def parse_error pos, str
921
+ raise ParseError, "#{pos}: #{str}"
922
+ end
923
+
924
+ ---- header
925
+
926
+ require 'set'
927
+
928
+ #### Error classes
929
+ module C
930
+ class ParseError < StandardError; end
931
+ end
932
+
933
+ ### Local variables:
934
+ ### mode: ruby
935
+ ### end: