csquare-cast 0.2.2

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.
@@ -0,0 +1,901 @@
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 COLON statement {val[2].labels.unshift(PlainLabel.new_at(val[0].pos, val[0].val)); result = val[2]}
42
+ | CASE constant_expression COLON statement {val[3].labels.unshift(Case .new_at(val[0].pos, val[1] )); result = val[3]}
43
+ | DEFAULT COLON 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 COLON 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
+ : LBRACE block_item_list RBRACE {result = Block.new_at(val[0].pos, val[1])}
50
+ | LBRACE RBRACE {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 SEMICOLON {result = ExpressionStatement.new_at(val[0].pos, val[0])}
65
+ | SEMICOLON {result = ExpressionStatement.new_at(val[0].pos )}
66
+
67
+ # Returns Statement
68
+ selection_statement
69
+ : IF LPAREN expression RPAREN statement {result = If .new_at(val[0].pos, val[2], val[4] )}
70
+ | IF LPAREN expression RPAREN statement ELSE statement {result = If .new_at(val[0].pos, val[2], val[4], val[6])}
71
+ | SWITCH LPAREN expression RPAREN statement {result = Switch.new_at(val[0].pos, val[2], val[4] )}
72
+
73
+ # Returns Statement
74
+ iteration_statement
75
+ : WHILE LPAREN expression RPAREN statement {result = While.new_at(val[0].pos, val[2], val[4] )}
76
+ | DO statement WHILE LPAREN expression RPAREN SEMICOLON {result = While.new_at(val[0].pos, val[4], val[1], :do => true )}
77
+ | FOR LPAREN expression SEMICOLON expression SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], val[4], val[6], val[8])}
78
+ | FOR LPAREN expression SEMICOLON expression SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], val[4], nil , val[7])}
79
+ | FOR LPAREN expression SEMICOLON SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , val[5], val[7])}
80
+ | FOR LPAREN expression SEMICOLON SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , nil , val[6])}
81
+ | FOR LPAREN SEMICOLON expression SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, nil , val[3], val[5], val[7])}
82
+ | FOR LPAREN SEMICOLON expression SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, nil , val[3], nil , val[6])}
83
+ | FOR LPAREN SEMICOLON SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, nil , nil , val[4], val[6])}
84
+ | FOR LPAREN SEMICOLON SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, nil , nil , nil , val[5])}
85
+ | FOR LPAREN declaration expression SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], val[3], val[5], val[7])}
86
+ | FOR LPAREN declaration expression SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], val[3], nil , val[6])}
87
+ | FOR LPAREN declaration SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , val[4], val[6])}
88
+ | FOR LPAREN declaration SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , nil , val[5])}
89
+
90
+ # Returns Statement
91
+ jump_statement
92
+ : GOTO identifier SEMICOLON {result = Goto .new_at(val[0].pos, val[1].val)}
93
+ | CONTINUE SEMICOLON {result = Continue.new_at(val[0].pos )}
94
+ | BREAK SEMICOLON {result = Break .new_at(val[0].pos )}
95
+ | RETURN expression SEMICOLON {result = Return .new_at(val[0].pos, val[1] )}
96
+ | RETURN SEMICOLON {result = Return .new_at(val[0].pos )}
97
+ # type names can also be used as labels
98
+ | GOTO typedef_name SEMICOLON {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 SEMICOLON {result = make_declaration(val[0][0], val[0][1], val[1])}
105
+ | declaration_specifiers SEMICOLON {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 COMMA init_declarator {result = val[0] << val[2]}
122
+
123
+ # Returns Declarator
124
+ init_declarator
125
+ : declarator {result = val[0]}
126
+ | declarator EQ initializer {val[0].init = val[2]; result = val[0]}
127
+
128
+ # Returns [Pos, Symbol]
129
+ storage_class_specifier
130
+ : TYPEDEF {result = [val[0].pos, :typedef ]}
131
+ | EXTERN {result = [val[0].pos, :extern ]}
132
+ | STATIC {result = [val[0].pos, :static ]}
133
+ | AUTO {result = [val[0].pos, :auto ]}
134
+ | REGISTER {result = [val[0].pos, :register]}
135
+
136
+ # Returns [Pos, Type|Symbol]
137
+ type_specifier
138
+ : VOID {result = [val[0].pos, :void ]}
139
+ | CHAR {result = [val[0].pos, :char ]}
140
+ | SHORT {result = [val[0].pos, :short ]}
141
+ | INT {result = [val[0].pos, :int ]}
142
+ | LONG {result = [val[0].pos, :long ]}
143
+ | FLOAT {result = [val[0].pos, :float ]}
144
+ | DOUBLE {result = [val[0].pos, :double ]}
145
+ | SIGNED {result = [val[0].pos, :signed ]}
146
+ | UNSIGNED {result = [val[0].pos, :unsigned ]}
147
+ | BOOL {result = [val[0].pos, :_Bool ]}
148
+ | COMPLEX {result = [val[0].pos, :_Complex ]}
149
+ | IMAGINARY {result = [val[0].pos, :_Imaginary]}
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 LBRACE struct_declaration_list RBRACE {result = val[0][1].new_at(val[0][0], val[1].val, val[3])}
157
+ | struct_or_union LBRACE struct_declaration_list RBRACE {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 LBRACE struct_declaration_list RBRACE {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 SEMICOLON {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 COMMA struct_declarator {result = val[0] << val[2]}
188
+
189
+ # Returns Declarator
190
+ struct_declarator
191
+ : declarator {result = val[0]}
192
+ | declarator COLON constant_expression {result = val[0]; val[0].num_bits = val[2]}
193
+ | COLON constant_expression {result = Declarator.new_at(val[0].pos, :num_bits => val[1])}
194
+
195
+ # Returns Enum
196
+ enum_specifier
197
+ : ENUM identifier LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, val[1].val, val[3])}
198
+ | ENUM LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, nil , val[2])}
199
+ | ENUM identifier LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, val[1].val, val[3])}
200
+ | ENUM LBRACE enumerator_list COMMA RBRACE {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 LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, val[1].name, val[3])}
204
+ | ENUM typedef_name LBRACE enumerator_list COMMA RBRACE {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 COMMA 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 EQ 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, :const ]}
220
+ | RESTRICT {result = [val[0].pos, :restrict]}
221
+ | VOLATILE {result = [val[0].pos, :volatile]}
222
+
223
+ # Returns [Pos, Symbol]
224
+ function_specifier
225
+ : INLINE {result = [val[0].pos, :inline]}
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
+ | LPAREN declarator RPAREN {result = val[1]}
236
+ | direct_declarator LBRACKET type_qualifier_list assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
237
+ | direct_declarator LBRACKET type_qualifier_list RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
238
+ | direct_declarator LBRACKET assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos, nil, val[2]))}
239
+ | direct_declarator LBRACKET RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))}
240
+ | direct_declarator LBRACKET STATIC type_qualifier_list assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
241
+ | direct_declarator LBRACKET STATIC assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
242
+ | direct_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
243
+ | direct_declarator LBRACKET type_qualifier_list MUL RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
244
+ | direct_declarator LBRACKET MUL RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
245
+ | direct_declarator LPAREN parameter_type_list RPAREN {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 LPAREN identifier_list RPAREN {result = add_decl_type(val[0], Function.new_at(val[0].pos, nil, val[2]))}
247
+ | direct_declarator LPAREN RPAREN {result = add_decl_type(val[0], Function.new_at(val[0].pos ))}
248
+
249
+ # Returns Pointer
250
+ pointer
251
+ : MUL type_qualifier_list {result = add_type_quals(Pointer.new_at(val[0].pos), val[1][1]) }
252
+ | MUL {result = Pointer.new_at(val[0].pos) }
253
+ | MUL 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
+ | MUL 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 COMMA ELLIPSIS {result = [val[0], true ]}
265
+
266
+ # Returns NodeArray[Parameter]
267
+ parameter_list
268
+ : parameter_declaration {result = NodeArray[val[0]]}
269
+ | parameter_list COMMA 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 COMMA 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
+ : LPAREN abstract_declarator RPAREN {result = val[1]}
297
+ | direct_abstract_declarator LBRACKET assignment_expression RBRACKET {val[0].direct_type = Array.new_at(val[0].pos, nil, val[2]); result = val[0]}
298
+ | direct_abstract_declarator LBRACKET RBRACKET {val[0].direct_type = Array.new_at(val[0].pos, nil, nil ); result = val[0]}
299
+ | LBRACKET assignment_expression RBRACKET {result = Array.new_at(val[0].pos, nil, val[1])}
300
+ | LBRACKET RBRACKET {result = Array.new_at(val[0].pos )}
301
+ | direct_abstract_declarator LBRACKET MUL RBRACKET {val[0].direct_type = Array.new_at(val[0].pos); result = val[0]} # TODO
302
+ | LBRACKET MUL RBRACKET {result = Array.new_at(val[0].pos)} # TODO
303
+ | direct_abstract_declarator LPAREN parameter_type_list RPAREN {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 LPAREN RPAREN {val[0].direct_type = Function.new_at(val[0].pos ); result = val[0]}
305
+ | LPAREN parameter_type_list RPAREN {result = Function.new_at(val[0].pos, nil, param_list(*val[1]), val[1][1])}
306
+ | LPAREN RPAREN {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
+ : TYPENAME {result = CustomType.new_at(val[0].pos, val[0].val)}
313
+
314
+ # Returns Expression
315
+ initializer
316
+ : assignment_expression {result = val[0]}
317
+ | LBRACE initializer_list RBRACE {result = CompoundLiteral.new_at(val[0].pos, nil, val[1])}
318
+ | LBRACE initializer_list COMMA RBRACE {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 COMMA designation initializer {result = val[0] << MemberInit.new_at(val[2][0] , val[2][1], val[3])}
325
+ | initializer_list COMMA 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 EQ {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
+ : LBRACKET constant_expression RBRACKET {result = [val[1].pos, val[1] ]}
339
+ | DOT 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
+ # GCC EXTENSION: allow a compound statement in parentheses as an expression
349
+ | LPAREN expression RPAREN {result = val[1]}
350
+ | LPAREN compound_statement RPAREN {block_expressions_enabled? or parse_error val[0].pos, "compound statement found where expression expected"
351
+ result = BlockExpression.new(val[1]); result.pos = val[0].pos}
352
+
353
+ # Returns Expression
354
+ postfix_expression
355
+ : primary_expression {result = val[0]}
356
+ | postfix_expression LBRACKET expression RBRACKET {result = Index .new_at(val[0].pos, val[0], val[2])}
357
+ | postfix_expression LPAREN argument_expression_list RPAREN {result = Call .new_at(val[0].pos, val[0], val[2] )}
358
+ | postfix_expression LPAREN RPAREN {result = Call .new_at(val[0].pos, val[0], NodeArray[])}
359
+ | postfix_expression DOT identifier {result = Dot .new_at(val[0].pos, val[0], Member.new(val[2].val))}
360
+ | postfix_expression ARROW identifier {result = Arrow .new_at(val[0].pos, val[0], Member.new(val[2].val))}
361
+ | postfix_expression INC {result = PostInc .new_at(val[0].pos, val[0] )}
362
+ | postfix_expression DEC {result = PostDec .new_at(val[0].pos, val[0] )}
363
+ | LPAREN type_name RPAREN LBRACE initializer_list RBRACE {result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])}
364
+ | LPAREN type_name RPAREN LBRACE initializer_list COMMA RBRACE {result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])}
365
+
366
+ # Returns [Expression|Type]
367
+ argument_expression_list
368
+ : argument_expression {result = NodeArray[val[0]]}
369
+ | argument_expression_list COMMA argument_expression {result = val[0] << val[2]}
370
+
371
+ # Returns Expression|Type -- EXTENSION: allow type names here too, to support some standard library macros (e.g., va_arg [7.15.1.1])
372
+ argument_expression
373
+ : assignment_expression {result = val[0]}
374
+ | type_name {result = val[0]}
375
+
376
+ # Returns Expression
377
+ unary_expression
378
+ : postfix_expression {result = val[0]}
379
+ | INC unary_expression {result = PreInc.new_at(val[0].pos, val[1])}
380
+ | DEC unary_expression {result = PreDec.new_at(val[0].pos, val[1])}
381
+ | unary_operator cast_expression {result = val[0][0].new_at(val[0][1], val[1])}
382
+ | SIZEOF unary_expression {result = Sizeof.new_at(val[0].pos, val[1])}
383
+ | SIZEOF LPAREN type_name RPAREN {result = Sizeof.new_at(val[0].pos, val[2])}
384
+
385
+ # Returns [Class, Pos]
386
+ unary_operator
387
+ : AND {result = [Address , val[0].pos]}
388
+ | MUL {result = [Dereference, val[0].pos]}
389
+ | ADD {result = [Positive , val[0].pos]}
390
+ | SUB {result = [Negative , val[0].pos]}
391
+ | NOT {result = [BitNot , val[0].pos]}
392
+ | BANG {result = [Not , val[0].pos]}
393
+
394
+ # Returns Expression
395
+ cast_expression
396
+ : unary_expression {result = val[0]}
397
+ | LPAREN type_name RPAREN cast_expression {result = Cast.new_at(val[0].pos, val[1], val[3])}
398
+
399
+ # Returns Expression
400
+ multiplicative_expression
401
+ : cast_expression {result = val[0]}
402
+ | multiplicative_expression MUL cast_expression {result = Multiply.new_at(val[0].pos, val[0], val[2])}
403
+ | multiplicative_expression DIV cast_expression {result = Divide .new_at(val[0].pos, val[0], val[2])}
404
+ | multiplicative_expression MOD cast_expression {result = Mod .new_at(val[0].pos, val[0], val[2])}
405
+
406
+ # Returns Expression
407
+ additive_expression
408
+ : multiplicative_expression {result = val[0]}
409
+ | additive_expression ADD multiplicative_expression {result = Add .new_at(val[0].pos, val[0], val[2])}
410
+ | additive_expression SUB multiplicative_expression {result = Subtract.new_at(val[0].pos, val[0], val[2])}
411
+
412
+ # Returns Expression
413
+ shift_expression
414
+ : additive_expression {result = val[0]}
415
+ | shift_expression LSHIFT additive_expression {result = ShiftLeft .new_at(val[0].pos, val[0], val[2])}
416
+ | shift_expression RSHIFT additive_expression {result = ShiftRight.new_at(val[0].pos, val[0], val[2])}
417
+
418
+ # Returns Expression
419
+ relational_expression
420
+ : shift_expression {result = val[0]}
421
+ | relational_expression LT shift_expression {result = Less.new_at(val[0].pos, val[0], val[2])}
422
+ | relational_expression GT shift_expression {result = More.new_at(val[0].pos, val[0], val[2])}
423
+ | relational_expression LEQ shift_expression {result = LessOrEqual.new_at(val[0].pos, val[0], val[2])}
424
+ | relational_expression GEQ shift_expression {result = MoreOrEqual.new_at(val[0].pos, val[0], val[2])}
425
+
426
+ # Returns Expression
427
+ equality_expression
428
+ : relational_expression {result = val[0]}
429
+ | equality_expression EQEQ relational_expression {result = Equal .new_at(val[0].pos, val[0], val[2])}
430
+ | equality_expression NEQ relational_expression {result = NotEqual.new_at(val[0].pos, val[0], val[2])}
431
+
432
+ # Returns Expression
433
+ and_expression
434
+ : equality_expression {result = val[0]}
435
+ | and_expression AND equality_expression {result = BitAnd.new_at(val[0].pos, val[0], val[2])}
436
+
437
+ # Returns Expression
438
+ exclusive_or_expression
439
+ : and_expression {result = val[0]}
440
+ | exclusive_or_expression XOR and_expression {result = BitXor.new_at(val[0].pos, val[0], val[2])}
441
+
442
+ # Returns Expression
443
+ inclusive_or_expression
444
+ : exclusive_or_expression {result = val[0]}
445
+ | inclusive_or_expression OR exclusive_or_expression {result = BitOr.new_at(val[0].pos, val[0], val[2])}
446
+
447
+ # Returns Expression
448
+ logical_and_expression
449
+ : inclusive_or_expression {result = val[0]}
450
+ | logical_and_expression ANDAND inclusive_or_expression {result = And.new_at(val[0].pos, val[0], val[2])}
451
+
452
+ # Returns Expression
453
+ logical_or_expression
454
+ : logical_and_expression {result = val[0]}
455
+ | logical_or_expression OROR logical_and_expression {result = Or.new_at(val[0].pos, val[0], val[2])}
456
+
457
+ # Returns Expression
458
+ conditional_expression
459
+ : logical_or_expression {result = val[0]}
460
+ | logical_or_expression QUESTION expression COLON conditional_expression {result = Conditional.new_at(val[0].pos, val[0], val[2], val[4])}
461
+
462
+ # Returns Expression
463
+ assignment_expression
464
+ : conditional_expression {result = val[0]}
465
+ | unary_expression assignment_operator assignment_expression {result = val[1].new_at(val[0].pos, val[0], val[2])}
466
+
467
+ # Returns Class
468
+ assignment_operator
469
+ : EQ {result = Assign}
470
+ | MULEQ {result = MultiplyAssign}
471
+ | DIVEQ {result = DivideAssign}
472
+ | MODEQ {result = ModAssign}
473
+ | ADDEQ {result = AddAssign}
474
+ | SUBEQ {result = SubtractAssign}
475
+ | LSHIFTEQ {result = ShiftLeftAssign}
476
+ | RSHIFTEQ {result = ShiftRightAssign}
477
+ | ANDEQ {result = BitAndAssign}
478
+ | XOREQ {result = BitXorAssign}
479
+ | OREQ {result = BitOrAssign}
480
+
481
+ # Returns Expression
482
+ expression
483
+ : assignment_expression {result = val[0]}
484
+ | expression COMMA assignment_expression {
485
+ if val[0].is_a? Comma
486
+ if val[2].is_a? Comma
487
+ val[0].exprs.push(*val[2].exprs)
488
+ else
489
+ val[0].exprs << val[2]
490
+ end
491
+ result = val[0]
492
+ else
493
+ if val[2].is_a? Comma
494
+ val[2].exprs.unshift(val[0])
495
+ val[2].pos = val[0].pos
496
+ result = val[2]
497
+ else
498
+ result = Comma.new_at(val[0].pos, NodeArray[val[0], val[2]])
499
+ end
500
+ end
501
+ }
502
+
503
+ # Returns Expression
504
+ constant_expression
505
+ : conditional_expression {result = val[0]}
506
+
507
+ # A.1.1 -- Lexical elements
508
+ #
509
+ # token
510
+ # : keyword (raw string)
511
+ # | identifier expanded below
512
+ # | constant expanded below
513
+ # | string_literal expanded below
514
+ # | punctuator (raw string)
515
+ #
516
+ # preprocessing-token (skip)
517
+
518
+ # Returns Token
519
+ identifier
520
+ : ID {result = val[0]}
521
+
522
+ # Returns Literal
523
+ constant
524
+ : ICON {result = val[0].val; result.pos = val[0].pos}
525
+ | FCON {result = val[0].val; result.pos = val[0].pos}
526
+ #| enumeration_constant -- these are parsed as identifiers at all
527
+ # places the `constant' nonterminal appears
528
+ | CCON {result = val[0].val; result.pos = val[0].pos}
529
+
530
+ # Returns Token
531
+ enumeration_constant
532
+ : ID {result = val[0]}
533
+
534
+ # Returns StringLiteral
535
+ string_literal
536
+ : SCON {result = val[0].val; result.pos = val[0].pos}
537
+
538
+ ---- inner
539
+ # A.1.9 -- Preprocessing numbers -- skip
540
+ # A.1.8 -- Header names -- skip
541
+
542
+ # A.1.7 -- Puncuators -- we don't bother with {##,#,%:,%:%:} since
543
+ # we don't do preprocessing
544
+ @@punctuators = %r'\+\+|-[->]|&&|\|\||\.\.\.|(?:<<|>>|[<>=!*/%+\-&^|])=?|[\[\](){}.~?:;,]'
545
+ @@digraphs = %r'<[:%]|[:%]>'
546
+
547
+ # A.1.6 -- String Literals -- simple for us because we don't decode
548
+ # the string (and indeed accept some illegal strings)
549
+ @@string_literal = %r'L?"(?:[^\\]|\\.)*?"'m
550
+
551
+ # A.1.5 -- Constants
552
+ @@decimal_floating_constant = %r'(?:(?:\d*\.\d+|\d+\.)(?:e[-+]?\d+)?|\d+e[-+]?\d+)[fl]?'i
553
+ @@hexadecimal_floating_constant = %r'0x(?:(?:[0-9a-f]*\.[0-9a-f]+|[0-9a-f]+\.)|[0-9a-f]+)p[-+]?\d+[fl]?'i
554
+
555
+ @@integer_constant = %r'(?:[1-9][0-9]*|0x[0-9a-f]+|0[0-7]*)(?:ul?l?|ll?u?)?'i
556
+ @@floating_constant = %r'#{@@decimal_floating_constant}|#{@@hexadecimal_floating_constant}'
557
+ @@enumeration_constant = %r'[a-zA-Z_\\][a-zA-Z_\\0-9]*'
558
+ @@character_constant = %r"L?'(?:[^\\]|\\.)+?'"
559
+ # (note that as with string-literals, we accept some illegal
560
+ # character-constants)
561
+
562
+ # A.1.4 -- Universal character names -- skip
563
+
564
+ # A.1.3 -- Identifiers -- skip, since an identifier is lexically
565
+ # identical to an enumeration constant
566
+
567
+ # A.1.2 Keywords
568
+ keywords = %w'auto break case char const continue default do
569
+ double else enum extern float for goto if inline int long register
570
+ restrict return short signed sizeof static struct switch typedef union
571
+ unsigned void volatile while _Bool _Complex _Imaginary'
572
+ @@keywords = %r"#{keywords.join('|')}"
573
+
574
+ def initialize
575
+ @type_names = ::Set.new %w{__builtin_va_list}
576
+
577
+ @warning_proc = lambda{}
578
+ @pos = C::Node::Pos.new(nil, 1, 0)
579
+ end
580
+ def initialize_copy(x)
581
+ @pos = x.pos.dup
582
+ @type_names = x.type_names.dup
583
+ end
584
+ attr_accessor :pos, :type_names
585
+
586
+ def parse(str)
587
+ if str.respond_to? :read
588
+ str = str.read
589
+ end
590
+ @str = str
591
+ begin
592
+ prepare_lexer(str)
593
+ return do_parse
594
+ rescue ParseError => e
595
+ e.set_backtrace(caller)
596
+ raise
597
+ end
598
+ end
599
+
600
+ #
601
+ # Error handler, as used by racc.
602
+ #
603
+ def on_error(error_token_id, error_value, value_stack)
604
+ if error_value == '$'
605
+ parse_error @pos, "unexpected EOF"
606
+ else
607
+ parse_error(error_value.pos,
608
+ "parse error on #{token_to_str(error_token_id)} (#{error_value.val})")
609
+ end
610
+ end
611
+
612
+ def self.feature(name)
613
+ attr_writer "#{name}_enabled"
614
+ class_eval <<-EOS
615
+ def enable_#{name}
616
+ @#{name}_enabled = true
617
+ end
618
+ def #{name}_enabled?
619
+ @#{name}_enabled
620
+ end
621
+ EOS
622
+ end
623
+ private_class_method :feature
624
+
625
+ #
626
+ # Allow blocks in parentheses as expressions, as per the gcc
627
+ # extension. [http://rubyurl.com/iB7]
628
+ #
629
+ feature :block_expressions
630
+
631
+ private # ---------------------------------------------------------
632
+
633
+ class Token
634
+ attr_accessor :pos, :val
635
+ def initialize(pos, val)
636
+ @pos = pos
637
+ @val = val
638
+ end
639
+ end
640
+ def eat(str)
641
+ lines = str.split(/\r\n|[\r\n]/, -1)
642
+ if lines.length == 1
643
+ @pos.col_num += lines[0].length
644
+ else
645
+ @pos.line_num += lines.length - 1
646
+ @pos.col_num = lines[-1].length
647
+ end
648
+ end
649
+
650
+ #
651
+ # Make a Declaration from the given specs and declarators.
652
+ #
653
+ def make_declaration(pos, specs, declarators)
654
+ specs.all?{|x| x.is_a?(Symbol) || x.is_a?(Type)} or raise specs.map{|x| x.class}.inspect
655
+ decl = Declaration.new_at(pos, nil, declarators)
656
+
657
+ # set storage class
658
+ storage_classes = specs.find_all do |x|
659
+ [:typedef, :extern, :static, :auto, :register].include? x
660
+ end
661
+ # 6.7.1p2: at most, one storage-class specifier may be given in
662
+ # the declaration specifiers in a declaration
663
+ storage_classes.length <= 1 or
664
+ begin
665
+ if declarators.length == 0
666
+ for_name = ''
667
+ else
668
+ for_name = "for `#{declarators[0].name}'"
669
+ end
670
+ parse_error pos, "multiple or duplicate storage classes given #{for_name}'"
671
+ end
672
+ decl.storage = storage_classes[0]
673
+
674
+ # set type (specifiers, qualifiers)
675
+ decl.type = make_direct_type(pos, specs)
676
+
677
+ # set function specifiers
678
+ decl.inline = specs.include?(:inline)
679
+
680
+ # look for new type names
681
+ if decl.typedef?
682
+ decl.declarators.each do |d|
683
+ if d.name
684
+ @type_names << d.name
685
+ end
686
+ end
687
+ end
688
+
689
+ return decl
690
+ end
691
+
692
+ def make_function_def(pos, specs, func_declarator, decl_list, defn)
693
+ add_decl_type(func_declarator, make_direct_type(pos, specs))
694
+
695
+ # get types from decl_list if necessary
696
+ function = func_declarator.indirect_type
697
+ function.is_a? Function or
698
+ parse_error pos, "non function type for function `#{func_declarator.name}'"
699
+ params = function.params
700
+ if decl_list
701
+ params.all?{|p| p.type.nil?} or
702
+ parse_error pos, "both prototype and declaration list given for `#{func_declarator.name}'"
703
+ decl_list.each do |declaration|
704
+ declaration.declarators.each do |declarator|
705
+ param = params.find{|p| p.name == declarator.name} or
706
+ parse_error pos, "no parameter named #{declarator.name}"
707
+ if declarator.indirect_type
708
+ param.type = declarator.indirect_type
709
+ param.type.direct_type = declaration.type.dup
710
+ else
711
+ param.type = declaration.type.dup
712
+ end
713
+ end
714
+ end
715
+ params.all?{|p| p.type} or
716
+ begin
717
+ s = params.find_all{|p| p.type.nil?}.map{|p| "`#{p.name}'"}.join(' and ')
718
+ parse_error pos, "types missing for parameters #{s}"
719
+ end
720
+ end
721
+
722
+ fd = FunctionDef.new_at(pos,
723
+ function.detach,
724
+ func_declarator.name,
725
+ defn,
726
+ :no_prototype => !decl_list.nil?)
727
+
728
+ # set storage class
729
+ # 6.9.1p4: only extern or static allowed
730
+ specs.each do |s|
731
+ [:typedef, :auto, :register].include?(s) and
732
+ "`#{s}' illegal for function"
733
+ end
734
+ storage_classes = specs.find_all do |s|
735
+ s == :extern || s == :static
736
+ end
737
+ # 6.7.1p2: at most, one storage-class specifier may be given in
738
+ # the declaration specifiers in a declaration
739
+ storage_classes.length <= 1 or
740
+ "multiple or duplicate storage classes given for `#{func_declarator.name}'"
741
+ fd.storage = storage_classes[0] if storage_classes[0]
742
+
743
+ # set function specifiers
744
+ # 6.7.4p5 'inline' can be repeated
745
+ fd.inline = specs.include?(:inline)
746
+
747
+ return fd
748
+ end
749
+
750
+ #
751
+ # Make a direct type from the list of type specifiers and type
752
+ # qualifiers.
753
+ #
754
+ def make_direct_type(pos, specs)
755
+ specs_order = [:signed, :unsigned, :short, :long, :double, :void,
756
+ :char, :int, :float, :_Bool, :_Complex, :_Imaginary]
757
+
758
+ type_specs = specs.find_all do |x|
759
+ specs_order.include?(x) || !x.is_a?(Symbol)
760
+ end
761
+ type_specs.sort! do |a, b|
762
+ (specs_order.index(a)||100) <=> (specs_order.index(b)||100)
763
+ end
764
+
765
+ # set type specifiers
766
+ # 6.7.2p2: the specifier list should be one of these
767
+ type =
768
+ case type_specs
769
+ when [:void]
770
+ Void.new
771
+ when [:char]
772
+ Char.new
773
+ when [:signed, :char]
774
+ Char.new :signed => true
775
+ when [:unsigned, :char]
776
+ Char.new :signed => false
777
+ when [:short], [:signed, :short], [:short, :int],
778
+ [:signed, :short, :int]
779
+ Int.new :longness => -1
780
+ when [:unsigned, :short], [:unsigned, :short, :int]
781
+ Int.new :unsigned => true, :longness => -1
782
+ when [:int], [:signed], [:signed, :int]
783
+ Int.new
784
+ when [:unsigned], [:unsigned, :int]
785
+ Int.new :unsigned => true
786
+ when [:long], [:signed, :long], [:long, :int],
787
+ [:signed, :long, :int]
788
+ Int.new :longness => 1
789
+ when [:unsigned, :long], [:unsigned, :long, :int]
790
+ Int.new :longness => 1, :unsigned => true
791
+ when [:long, :long], [:signed, :long, :long],
792
+ [:long, :long, :int], [:signed, :long, :long, :int]
793
+ Int.new :longness => 2
794
+ when [:unsigned, :long, :long], [:unsigned, :long, :long, :int]
795
+ Int.new :longness => 2, :unsigned => true
796
+ when [:float]
797
+ Float.new
798
+ when [:double]
799
+ Float.new :longness => 1
800
+ when [:long, :double]
801
+ Float.new :longness => 2
802
+ when [:_Bool]
803
+ Bool.new
804
+ when [:float, :_Complex]
805
+ Complex.new
806
+ when [:double, :_Complex]
807
+ Complex.new :longness => 1
808
+ when [:long, :double, :_Complex]
809
+ Complex.new :longness => 2
810
+ when [:float, :_Imaginary]
811
+ Imaginary.new
812
+ when [:double, :_Imaginary]
813
+ Imaginary.new :longness => 1
814
+ when [:long, :double, :_Imaginary]
815
+ Imaginary.new :longness => 2
816
+ else
817
+ if type_specs.length == 1 &&
818
+ [CustomType, Struct, Union, Enum].any?{|c| type_specs[0].is_a? c}
819
+ type_specs[0]
820
+ else
821
+ if type_specs == []
822
+ parse_error pos, "no type specifiers given"
823
+ else
824
+ parse_error pos, "invalid type specifier combination: #{type_specs.join(' ')}"
825
+ end
826
+ end
827
+ end
828
+ type.pos ||= pos
829
+
830
+ # set type qualifiers
831
+ # 6.7.3p4: type qualifiers can be repeated
832
+ type.const = specs.any?{|x| x.equal? :const }
833
+ type.restrict = specs.any?{|x| x.equal? :restrict}
834
+ type.volatile = specs.any?{|x| x.equal? :volatile}
835
+
836
+ return type
837
+ end
838
+
839
+ def make_parameter(pos, specs, indirect_type, name)
840
+ type = indirect_type
841
+ if type
842
+ type.direct_type = make_direct_type(pos, specs)
843
+ else
844
+ type = make_direct_type(pos, specs)
845
+ end
846
+ [:typedef, :extern, :static, :auto, :inline].each do |sym|
847
+ specs.include? sym and
848
+ parse_error pos, "parameter `#{declarator.name}' declared `#{sym}'"
849
+ end
850
+ return Parameter.new_at(pos, type, name,
851
+ :register => specs.include?(:register))
852
+ end
853
+
854
+ def add_type_quals(type, quals)
855
+ type.const = quals.include?(:const )
856
+ type.restrict = quals.include?(:restrict)
857
+ type.volatile = quals.include?(:volatile)
858
+ return type
859
+ end
860
+
861
+ #
862
+ # Add te given type as the "most direct" type to the given
863
+ # declarator. Return the declarator.
864
+ #
865
+ def add_decl_type(declarator, type)
866
+ if declarator.indirect_type
867
+ declarator.indirect_type.direct_type = type
868
+ else
869
+ declarator.indirect_type = type
870
+ end
871
+ return declarator
872
+ end
873
+
874
+ def param_list(params, var_args)
875
+ if params.length == 1 &&
876
+ params[0].type.is_a?(Void) &&
877
+ params[0].name.nil?
878
+ return NodeArray[]
879
+ elsif params.empty?
880
+ return nil
881
+ else
882
+ return params
883
+ end
884
+ end
885
+
886
+ def parse_error(pos, str)
887
+ raise ParseError, "#{pos}: #{str}"
888
+ end
889
+
890
+ ---- header
891
+
892
+ require 'set'
893
+
894
+ # Error classes
895
+ module C
896
+ class ParseError < StandardError; end
897
+ end
898
+
899
+ # Local variables:
900
+ # mode: ruby
901
+ # end: