cast 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: