cast 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,33 +1,33 @@
1
1
  class C::Parser
2
- ## shift/reduce conflict on "if (c) if (c) ; else ; else ;"
2
+ # shift/reduce conflict on "if (c) if (c) ; else ; else ;"
3
3
  expect 1
4
4
  rule
5
5
 
6
- ## A.2.4 External definitions
6
+ # A.2.4 External definitions
7
7
 
8
- ## Returns TranslationUnit
8
+ # Returns TranslationUnit
9
9
  translation_unit
10
10
  : external_declaration {result = TranslationUnit.new_at(val[0].pos, NodeChain[val[0]])}
11
11
  | translation_unit external_declaration {result = val[0]; result.entities << val[1]}
12
12
 
13
- ## Returns Declaration|FunctionDef
13
+ # Returns Declaration|FunctionDef
14
14
  external_declaration
15
15
  : function_definition {result = val[0]}
16
16
  | declaration {result = val[0]}
17
17
 
18
- ## Returns FunctionDef
18
+ # Returns FunctionDef
19
19
  function_definition
20
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
21
  | declaration_specifiers declarator compound_statement {result = make_function_def(val[0][0], val[0][1], val[1], nil , val[2])}
22
22
 
23
- ## Returns [Declaration]
23
+ # Returns [Declaration]
24
24
  declaration_list
25
25
  : declaration {result = [val[0]]}
26
26
  | declaration_list declaration {result = val[0] << val[1]}
27
27
 
28
- ## A.2.3 Statements
28
+ # A.2.3 Statements
29
29
 
30
- ## Returns Statement
30
+ # Returns Statement
31
31
  statement
32
32
  : labeled_statement {result = val[0]}
33
33
  | compound_statement {result = val[0]}
@@ -36,41 +36,41 @@ statement
36
36
  | iteration_statement {result = val[0]}
37
37
  | jump_statement {result = val[0]}
38
38
 
39
- ## Returns Statement
39
+ # Returns Statement
40
40
  labeled_statement
41
41
  : identifier COLON statement {val[2].labels.unshift(PlainLabel.new_at(val[0].pos, val[0].val)); result = val[2]}
42
42
  | CASE constant_expression COLON statement {val[3].labels.unshift(Case .new_at(val[0].pos, val[1] )); result = val[3]}
43
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
44
+ # type names can also be used as labels
45
45
  | typedef_name COLON statement {val[2].labels.unshift(PlainLabel.new_at(val[0].pos, val[0].name)); result = val[2]}
46
46
 
47
- ## Returns Block
47
+ # Returns Block
48
48
  compound_statement
49
49
  : LBRACE block_item_list RBRACE {result = Block.new_at(val[0].pos, val[1])}
50
50
  | LBRACE RBRACE {result = Block.new_at(val[0].pos )}
51
51
 
52
- ## Returns NodeChain[Declaration|Statement]
52
+ # Returns NodeChain[Declaration|Statement]
53
53
  block_item_list
54
54
  : block_item {result = NodeChain[val[0]]}
55
55
  | block_item_list block_item {result = val[0] << val[1]}
56
56
 
57
- ## Returns Declaration|Statement
57
+ # Returns Declaration|Statement
58
58
  block_item
59
59
  : declaration {result = val[0]}
60
60
  | statement {result = val[0]}
61
61
 
62
- ## Returns ExpressionStatement
62
+ # Returns ExpressionStatement
63
63
  expression_statement
64
64
  : expression SEMICOLON {result = ExpressionStatement.new_at(val[0].pos, val[0])}
65
65
  | SEMICOLON {result = ExpressionStatement.new_at(val[0].pos )}
66
66
 
67
- ## Returns Statement
67
+ # Returns Statement
68
68
  selection_statement
69
69
  : IF LPAREN expression RPAREN statement {result = If .new_at(val[0].pos, val[2], val[4] )}
70
70
  | IF LPAREN expression RPAREN statement ELSE statement {result = If .new_at(val[0].pos, val[2], val[4], val[6])}
71
71
  | SWITCH LPAREN expression RPAREN statement {result = Switch.new_at(val[0].pos, val[2], val[4] )}
72
72
 
73
- ## Returns Statement
73
+ # Returns Statement
74
74
  iteration_statement
75
75
  : WHILE LPAREN expression RPAREN statement {result = While.new_at(val[0].pos, val[2], val[4] )}
76
76
  | DO statement WHILE LPAREN expression RPAREN SEMICOLON {result = While.new_at(val[0].pos, val[4], val[1], :do => true )}
@@ -87,24 +87,24 @@ iteration_statement
87
87
  | FOR LPAREN declaration SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , val[4], val[6])}
88
88
  | FOR LPAREN declaration SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , nil , val[5])}
89
89
 
90
- ## Returns Statement
90
+ # Returns Statement
91
91
  jump_statement
92
92
  : GOTO identifier SEMICOLON {result = Goto .new_at(val[0].pos, val[1].val)}
93
93
  | CONTINUE SEMICOLON {result = Continue.new_at(val[0].pos )}
94
94
  | BREAK SEMICOLON {result = Break .new_at(val[0].pos )}
95
95
  | RETURN expression SEMICOLON {result = Return .new_at(val[0].pos, val[1] )}
96
96
  | RETURN SEMICOLON {result = Return .new_at(val[0].pos )}
97
- ## type names can also be used as labels
97
+ # type names can also be used as labels
98
98
  | GOTO typedef_name SEMICOLON {result = Goto .new_at(val[0].pos, val[1].name)}
99
99
 
100
- ## A.2.2 Declarations
100
+ # A.2.2 Declarations
101
101
 
102
- ## Returns Declaration
102
+ # Returns Declaration
103
103
  declaration
104
104
  : declaration_specifiers init_declarator_list SEMICOLON {result = make_declaration(val[0][0], val[0][1], val[1])}
105
105
  | declaration_specifiers SEMICOLON {result = make_declaration(val[0][0], val[0][1], NodeArray[])}
106
106
 
107
- ## Returns {Pos, [Symbol]}
107
+ # Returns {Pos, [Symbol]}
108
108
  declaration_specifiers
109
109
  : storage_class_specifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]}
110
110
  | storage_class_specifier {result = [val[0][0], [val[0][1]]]}
@@ -115,17 +115,17 @@ declaration_specifiers
115
115
  | function_specifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]}
116
116
  | function_specifier {result = [val[0][0], [val[0][1]]]}
117
117
 
118
- ## Returns NodeArray[Declarator]
118
+ # Returns NodeArray[Declarator]
119
119
  init_declarator_list
120
120
  : init_declarator {result = NodeArray[val[0]]}
121
121
  | init_declarator_list COMMA init_declarator {result = val[0] << val[2]}
122
122
 
123
- ## Returns Declarator
123
+ # Returns Declarator
124
124
  init_declarator
125
125
  : declarator {result = val[0]}
126
126
  | declarator EQ initializer {val[0].init = val[2]; result = val[0]}
127
127
 
128
- ## Returns [Pos, Symbol]
128
+ # Returns [Pos, Symbol]
129
129
  storage_class_specifier
130
130
  : TYPEDEF {result = [val[0].pos, :typedef ]}
131
131
  | EXTERN {result = [val[0].pos, :extern ]}
@@ -133,7 +133,7 @@ storage_class_specifier
133
133
  | AUTO {result = [val[0].pos, :auto ]}
134
134
  | REGISTER {result = [val[0].pos, :register]}
135
135
 
136
- ## Returns [Pos, Type|Symbol]
136
+ # Returns [Pos, Type|Symbol]
137
137
  type_specifier
138
138
  : VOID {result = [val[0].pos, :void ]}
139
139
  | CHAR {result = [val[0].pos, :char ]}
@@ -151,85 +151,85 @@ type_specifier
151
151
  | enum_specifier {result = [val[0].pos, val[0] ]}
152
152
  | typedef_name {result = [val[0].pos, val[0] ]}
153
153
 
154
- ## Returns Struct|Union
154
+ # Returns Struct|Union
155
155
  struct_or_union_specifier
156
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
157
  | struct_or_union LBRACE struct_declaration_list RBRACE {result = val[0][1].new_at(val[0][0], nil , val[2])}
158
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
159
+ # type names can also be used as struct identifiers
160
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
161
  | struct_or_union typedef_name {result = val[0][1].new_at(val[0][0], val[1].name, nil )}
162
162
 
163
- ## Returns [Pos, Class]
163
+ # Returns [Pos, Class]
164
164
  struct_or_union
165
165
  : STRUCT {result = [val[0].pos, Struct]}
166
166
  | UNION {result = [val[0].pos, Union ]}
167
167
 
168
- ## Returns NodeArray[Declaration]
168
+ # Returns NodeArray[Declaration]
169
169
  struct_declaration_list
170
170
  : struct_declaration {result = NodeArray[val[0]]}
171
171
  | struct_declaration_list struct_declaration {val[0] << val[1]; result = val[0]}
172
172
 
173
- ## Returns Declaration
173
+ # Returns Declaration
174
174
  struct_declaration
175
175
  : specifier_qualifier_list struct_declarator_list SEMICOLON {result = make_declaration(val[0][0], val[0][1], val[1])}
176
176
 
177
- ## Returns {Pos, [Symbol]}
177
+ # Returns {Pos, [Symbol]}
178
178
  specifier_qualifier_list
179
179
  : type_specifier specifier_qualifier_list {val[1][1] << val[0][1]; result = val[1]}
180
180
  | type_specifier {result = [val[0][0], [val[0][1]]]}
181
181
  | type_qualifier specifier_qualifier_list {val[1][1] << val[0][1]; result = val[1]}
182
182
  | type_qualifier {result = [val[0][0], [val[0][1]]]}
183
183
 
184
- ## Returns NodeArray[Declarator]
184
+ # Returns NodeArray[Declarator]
185
185
  struct_declarator_list
186
186
  : struct_declarator {result = NodeArray[val[0]]}
187
187
  | struct_declarator_list COMMA struct_declarator {result = val[0] << val[2]}
188
188
 
189
- ## Returns Declarator
189
+ # Returns Declarator
190
190
  struct_declarator
191
191
  : declarator {result = val[0]}
192
192
  | declarator COLON constant_expression {result = val[0]; val[0].num_bits = val[2]}
193
193
  | COLON constant_expression {result = Declarator.new_at(val[0].pos, :num_bits => val[1])}
194
194
 
195
- ## Returns Enum
195
+ # Returns Enum
196
196
  enum_specifier
197
197
  : ENUM identifier LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, val[1].val, val[3])}
198
198
  | ENUM LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, nil , val[2])}
199
199
  | ENUM identifier LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, val[1].val, val[3])}
200
200
  | ENUM LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, nil , val[2])}
201
201
  | ENUM identifier {result = Enum.new_at(val[0].pos, val[1].val, nil )}
202
- ## type names can also be used as enum names
202
+ # type names can also be used as enum names
203
203
  | ENUM typedef_name LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, val[1].name, val[3])}
204
204
  | ENUM typedef_name LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, val[1].name, val[3])}
205
205
  | ENUM typedef_name {result = Enum.new_at(val[0].pos, val[1].name, nil )}
206
206
 
207
- ## Returns NodeArray[Enumerator]
207
+ # Returns NodeArray[Enumerator]
208
208
  enumerator_list
209
209
  : enumerator {result = NodeArray[val[0]]}
210
210
  | enumerator_list COMMA enumerator {result = val[0] << val[2]}
211
211
 
212
- ## Returns Enumerator
212
+ # Returns Enumerator
213
213
  enumerator
214
214
  : enumeration_constant {result = Enumerator.new_at(val[0].pos, val[0].val, nil )}
215
215
  | enumeration_constant EQ constant_expression {result = Enumerator.new_at(val[0].pos, val[0].val, val[2])}
216
216
 
217
- ## Returns [Pos, Symbol]
217
+ # Returns [Pos, Symbol]
218
218
  type_qualifier
219
219
  : CONST {result = [val[0].pos, :const ]}
220
220
  | RESTRICT {result = [val[0].pos, :restrict]}
221
221
  | VOLATILE {result = [val[0].pos, :volatile]}
222
222
 
223
- ## Returns [Pos, Symbol]
223
+ # Returns [Pos, Symbol]
224
224
  function_specifier
225
225
  : INLINE {result = [val[0].pos, :inline]}
226
226
 
227
- ## Returns Declarator
227
+ # Returns Declarator
228
228
  declarator
229
229
  : pointer direct_declarator {result = add_decl_type(val[1], val[0])}
230
230
  | direct_declarator {result = val[0]}
231
231
 
232
- ## Returns Declarator
232
+ # Returns Declarator
233
233
  direct_declarator
234
234
  : identifier {result = Declarator.new_at(val[0].pos, nil, val[0].val)}
235
235
  | LPAREN declarator RPAREN {result = val[1]}
@@ -246,52 +246,52 @@ direct_declarator
246
246
  | direct_declarator LPAREN identifier_list RPAREN {result = add_decl_type(val[0], Function.new_at(val[0].pos, nil, val[2]))}
247
247
  | direct_declarator LPAREN RPAREN {result = add_decl_type(val[0], Function.new_at(val[0].pos ))}
248
248
 
249
- ## Returns Pointer
249
+ # Returns Pointer
250
250
  pointer
251
251
  : MUL type_qualifier_list {result = add_type_quals(Pointer.new_at(val[0].pos), val[1][1]) }
252
252
  | MUL {result = Pointer.new_at(val[0].pos) }
253
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
254
  | MUL pointer {p = Pointer.new_at(val[0].pos) ; val[1].direct_type = p; result = val[1]}
255
255
 
256
- ## Returns {Pos, [Symbol]}
256
+ # Returns {Pos, [Symbol]}
257
257
  type_qualifier_list
258
258
  : type_qualifier {result = [val[0][0], [val[0][1]]]}
259
259
  | type_qualifier_list type_qualifier {val[0][1] << val[1][1]; result = val[0]}
260
260
 
261
- ## Returns [NodeArray[Parameter], var_args?]
261
+ # Returns [NodeArray[Parameter], var_args?]
262
262
  parameter_type_list
263
263
  : parameter_list {result = [val[0], false]}
264
264
  | parameter_list COMMA ELLIPSIS {result = [val[0], true ]}
265
265
 
266
- ## Returns NodeArray[Parameter]
266
+ # Returns NodeArray[Parameter]
267
267
  parameter_list
268
268
  : parameter_declaration {result = NodeArray[val[0]]}
269
269
  | parameter_list COMMA parameter_declaration {result = val[0] << val[2]}
270
270
 
271
- ## Returns Parameter
271
+ # Returns Parameter
272
272
  parameter_declaration
273
273
  : declaration_specifiers declarator {ind_type = val[1].indirect_type and ind_type.detach
274
274
  result = make_parameter(val[0][0], val[0][1], ind_type, val[1].name)}
275
275
  | declaration_specifiers abstract_declarator {result = make_parameter(val[0][0], val[0][1], val[1] , nil )}
276
276
  | declaration_specifiers {result = make_parameter(val[0][0], val[0][1], nil , nil )}
277
277
 
278
- ## Returns NodeArray[Parameter]
278
+ # Returns NodeArray[Parameter]
279
279
  identifier_list
280
280
  : identifier {result = NodeArray[Parameter.new_at(val[0].pos, nil, val[0].val)]}
281
281
  | identifier_list COMMA identifier {result = val[0] << Parameter.new_at(val[2].pos, nil, val[2].val)}
282
282
 
283
- ## Returns Type
283
+ # Returns Type
284
284
  type_name
285
285
  : specifier_qualifier_list abstract_declarator {val[1].direct_type = make_direct_type(val[0][0], val[0][1]); result = val[1]}
286
286
  | specifier_qualifier_list {result = make_direct_type(val[0][0], val[0][1]) }
287
287
 
288
- ## Returns Type
288
+ # Returns Type
289
289
  abstract_declarator
290
290
  : pointer {result = val[0]}
291
291
  | pointer direct_abstract_declarator {val[1].direct_type = val[0]; result = val[1]}
292
292
  | direct_abstract_declarator {result = val[0]}
293
293
 
294
- ## Returns Type
294
+ # Returns Type
295
295
  direct_abstract_declarator
296
296
  : LPAREN abstract_declarator RPAREN {result = val[1]}
297
297
  | direct_abstract_declarator LBRACKET assignment_expression RBRACKET {val[0].direct_type = Array.new_at(val[0].pos, nil, val[2]); result = val[0]}
@@ -305,49 +305,52 @@ direct_abstract_declarator
305
305
  | LPAREN parameter_type_list RPAREN {result = Function.new_at(val[0].pos, nil, param_list(*val[1]), val[1][1])}
306
306
  | LPAREN RPAREN {result = Function.new_at(val[0].pos )}
307
307
 
308
- ## Returns CustomType
308
+ # Returns CustomType
309
309
  typedef_name
310
310
  #: identifier -- insufficient since we must distinguish between type
311
311
  # names and var names (otherwise we have a conflict)
312
312
  : TYPENAME {result = CustomType.new_at(val[0].pos, val[0].val)}
313
313
 
314
- ## Returns Expression
314
+ # Returns Expression
315
315
  initializer
316
316
  : assignment_expression {result = val[0]}
317
317
  | LBRACE initializer_list RBRACE {result = CompoundLiteral.new_at(val[0].pos, nil, val[1])}
318
318
  | LBRACE initializer_list COMMA RBRACE {result = CompoundLiteral.new_at(val[0].pos, nil, val[1])}
319
319
 
320
- ## Returns NodeArray[MemberInit]
320
+ # Returns NodeArray[MemberInit]
321
321
  initializer_list
322
322
  : designation initializer {result = NodeArray[MemberInit.new_at(val[0][0] , val[0][1], val[1])]}
323
323
  | initializer {result = NodeArray[MemberInit.new_at(val[0].pos, nil , val[0])]}
324
324
  | initializer_list COMMA designation initializer {result = val[0] << MemberInit.new_at(val[2][0] , val[2][1], val[3])}
325
325
  | initializer_list COMMA initializer {result = val[0] << MemberInit.new_at(val[2].pos, nil , val[2])}
326
326
 
327
- ## Returns {Pos, NodeArray[Expression|Token]}
327
+ # Returns {Pos, NodeArray[Expression|Token]}
328
328
  designation
329
329
  : designator_list EQ {result = val[0]}
330
330
 
331
- ## Returns {Pos, NodeArray[Expression|Token]}
331
+ # Returns {Pos, NodeArray[Expression|Token]}
332
332
  designator_list
333
333
  : designator {result = val[0]; val[0][1] = NodeArray[val[0][1]]}
334
334
  | designator_list designator {result = val[0]; val[0][1] << val[1][1]}
335
335
 
336
- ## Returns {Pos, Expression|Member}
336
+ # Returns {Pos, Expression|Member}
337
337
  designator
338
- : LBRACKET constant_expression RBRACKET {result = [val[1].pos, val[1] ]}
338
+ : LBRACKET constant_expression RBRACKET {result = [val[1].pos, val[1] ]}
339
339
  | DOT identifier {result = [val[1].pos, Member.new_at(val[1].pos, val[1].val)]}
340
340
 
341
- ### A.2.1 Expressions
341
+ # A.2.1 Expressions
342
342
 
343
- ## Returns Expression
343
+ # Returns Expression
344
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
- | LPAREN expression RPAREN {result = val[1]}
349
-
350
- ## Returns 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
351
354
  postfix_expression
352
355
  : primary_expression {result = val[0]}
353
356
  | postfix_expression LBRACKET expression RBRACKET {result = Index .new_at(val[0].pos, val[0], val[2])}
@@ -360,17 +363,17 @@ postfix_expression
360
363
  | LPAREN type_name RPAREN LBRACE initializer_list RBRACE {result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])}
361
364
  | LPAREN type_name RPAREN LBRACE initializer_list COMMA RBRACE {result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])}
362
365
 
363
- ## Returns [Expression|Type] -- allow type names here too -- TODO: add an option to disallow this
366
+ # Returns [Expression|Type]
364
367
  argument_expression_list
365
368
  : argument_expression {result = NodeArray[val[0]]}
366
369
  | argument_expression_list COMMA argument_expression {result = val[0] << val[2]}
367
370
 
368
- ## Returns Expression|Type
371
+ # Returns Expression|Type -- EXTENSION: allow type names here too, to support some standard library macros (e.g., va_arg [7.15.1.1])
369
372
  argument_expression
370
373
  : assignment_expression {result = val[0]}
371
374
  | type_name {result = val[0]}
372
375
 
373
- ## Returns Expression
376
+ # Returns Expression
374
377
  unary_expression
375
378
  : postfix_expression {result = val[0]}
376
379
  | INC unary_expression {result = PreInc.new_at(val[0].pos, val[1])}
@@ -379,7 +382,7 @@ unary_expression
379
382
  | SIZEOF unary_expression {result = Sizeof.new_at(val[0].pos, val[1])}
380
383
  | SIZEOF LPAREN type_name RPAREN {result = Sizeof.new_at(val[0].pos, val[2])}
381
384
 
382
- ## Returns [Class, Pos]
385
+ # Returns [Class, Pos]
383
386
  unary_operator
384
387
  : AND {result = [Address , val[0].pos]}
385
388
  | MUL {result = [Dereference, val[0].pos]}
@@ -388,31 +391,31 @@ unary_operator
388
391
  | NOT {result = [BitNot , val[0].pos]}
389
392
  | BANG {result = [Not , val[0].pos]}
390
393
 
391
- ## Returns Expression
394
+ # Returns Expression
392
395
  cast_expression
393
396
  : unary_expression {result = val[0]}
394
397
  | LPAREN type_name RPAREN cast_expression {result = Cast.new_at(val[0].pos, val[1], val[3])}
395
398
 
396
- ## Returns Expression
399
+ # Returns Expression
397
400
  multiplicative_expression
398
401
  : cast_expression {result = val[0]}
399
402
  | multiplicative_expression MUL cast_expression {result = Multiply.new_at(val[0].pos, val[0], val[2])}
400
403
  | multiplicative_expression DIV cast_expression {result = Divide .new_at(val[0].pos, val[0], val[2])}
401
404
  | multiplicative_expression MOD cast_expression {result = Mod .new_at(val[0].pos, val[0], val[2])}
402
405
 
403
- ## Returns Expression
406
+ # Returns Expression
404
407
  additive_expression
405
408
  : multiplicative_expression {result = val[0]}
406
409
  | additive_expression ADD multiplicative_expression {result = Add .new_at(val[0].pos, val[0], val[2])}
407
410
  | additive_expression SUB multiplicative_expression {result = Subtract.new_at(val[0].pos, val[0], val[2])}
408
411
 
409
- ## Returns Expression
412
+ # Returns Expression
410
413
  shift_expression
411
414
  : additive_expression {result = val[0]}
412
415
  | shift_expression LSHIFT additive_expression {result = ShiftLeft .new_at(val[0].pos, val[0], val[2])}
413
416
  | shift_expression RSHIFT additive_expression {result = ShiftRight.new_at(val[0].pos, val[0], val[2])}
414
417
 
415
- ## Returns Expression
418
+ # Returns Expression
416
419
  relational_expression
417
420
  : shift_expression {result = val[0]}
418
421
  | relational_expression LT shift_expression {result = Less.new_at(val[0].pos, val[0], val[2])}
@@ -420,48 +423,48 @@ relational_expression
420
423
  | relational_expression LEQ shift_expression {result = LessOrEqual.new_at(val[0].pos, val[0], val[2])}
421
424
  | relational_expression GEQ shift_expression {result = MoreOrEqual.new_at(val[0].pos, val[0], val[2])}
422
425
 
423
- ## Returns Expression
426
+ # Returns Expression
424
427
  equality_expression
425
428
  : relational_expression {result = val[0]}
426
429
  | equality_expression EQEQ relational_expression {result = Equal .new_at(val[0].pos, val[0], val[2])}
427
430
  | equality_expression NEQ relational_expression {result = NotEqual.new_at(val[0].pos, val[0], val[2])}
428
431
 
429
- ## Returns Expression
432
+ # Returns Expression
430
433
  and_expression
431
434
  : equality_expression {result = val[0]}
432
435
  | and_expression AND equality_expression {result = BitAnd.new_at(val[0].pos, val[0], val[2])}
433
436
 
434
- ## Returns Expression
437
+ # Returns Expression
435
438
  exclusive_or_expression
436
439
  : and_expression {result = val[0]}
437
440
  | exclusive_or_expression XOR and_expression {result = BitXor.new_at(val[0].pos, val[0], val[2])}
438
441
 
439
- ## Returns Expression
442
+ # Returns Expression
440
443
  inclusive_or_expression
441
444
  : exclusive_or_expression {result = val[0]}
442
445
  | inclusive_or_expression OR exclusive_or_expression {result = BitOr.new_at(val[0].pos, val[0], val[2])}
443
446
 
444
- ## Returns Expression
447
+ # Returns Expression
445
448
  logical_and_expression
446
449
  : inclusive_or_expression {result = val[0]}
447
450
  | logical_and_expression ANDAND inclusive_or_expression {result = And.new_at(val[0].pos, val[0], val[2])}
448
451
 
449
- ## Returns Expression
452
+ # Returns Expression
450
453
  logical_or_expression
451
454
  : logical_and_expression {result = val[0]}
452
455
  | logical_or_expression OROR logical_and_expression {result = Or.new_at(val[0].pos, val[0], val[2])}
453
456
 
454
- ## Returns Expression
457
+ # Returns Expression
455
458
  conditional_expression
456
459
  : logical_or_expression {result = val[0]}
457
460
  | logical_or_expression QUESTION expression COLON conditional_expression {result = Conditional.new_at(val[0].pos, val[0], val[2], val[4])}
458
461
 
459
- ## Returns Expression
462
+ # Returns Expression
460
463
  assignment_expression
461
464
  : conditional_expression {result = val[0]}
462
465
  | unary_expression assignment_operator assignment_expression {result = val[1].new_at(val[0].pos, val[0], val[2])}
463
466
 
464
- ## Returns Class
467
+ # Returns Class
465
468
  assignment_operator
466
469
  : EQ {result = Assign}
467
470
  | MULEQ {result = MultiplyAssign}
@@ -475,7 +478,7 @@ assignment_operator
475
478
  | XOREQ {result = BitXorAssign}
476
479
  | OREQ {result = BitOrAssign}
477
480
 
478
- ## Returns Expression
481
+ # Returns Expression
479
482
  expression
480
483
  : assignment_expression {result = val[0]}
481
484
  | expression COMMA assignment_expression {
@@ -497,26 +500,26 @@ expression
497
500
  end
498
501
  }
499
502
 
500
- ## Returns Expression
503
+ # Returns Expression
501
504
  constant_expression
502
505
  : conditional_expression {result = val[0]}
503
506
 
504
- ### A.1.1 -- Lexical elements
505
- ##
506
- ## token
507
- ## : keyword (raw string)
508
- ## | identifier expanded below
509
- ## | constant expanded below
510
- ## | string_literal expanded below
511
- ## | punctuator (raw string)
512
- ##
513
- ## preprocessing-token (skip)
514
-
515
- ## Returns Token
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
516
519
  identifier
517
520
  : ID {result = val[0]}
518
521
 
519
- ## Returns Literal
522
+ # Returns Literal
520
523
  constant
521
524
  : ICON {result = val[0].val; result.pos = val[0].pos}
522
525
  | FCON {result = val[0].val; result.pos = val[0].pos}
@@ -524,28 +527,28 @@ constant
524
527
  # places the `constant' nonterminal appears
525
528
  | CCON {result = val[0].val; result.pos = val[0].pos}
526
529
 
527
- ## Returns Token
530
+ # Returns Token
528
531
  enumeration_constant
529
532
  : ID {result = val[0]}
530
533
 
531
- ## Returns StringLiteral
534
+ # Returns StringLiteral
532
535
  string_literal
533
536
  : SCON {result = val[0].val; result.pos = val[0].pos}
534
537
 
535
538
  ---- inner
536
- ## A.1.9 -- Preprocessing numbers -- skip
537
- ## A.1.8 -- Header names -- skip
539
+ # A.1.9 -- Preprocessing numbers -- skip
540
+ # A.1.8 -- Header names -- skip
538
541
 
539
- ## A.1.7 -- Puncuators -- we don't bother with {##,#,%:,%:%:} since
540
- ## we don't do preprocessing
542
+ # A.1.7 -- Puncuators -- we don't bother with {##,#,%:,%:%:} since
543
+ # we don't do preprocessing
541
544
  @@punctuators = %r'\+\+|-[->]|&&|\|\||\.\.\.|(?:<<|>>|[<>=!*/%+\-&^|])=?|[\[\](){}.~?:;,]'
542
545
  @@digraphs = %r'<[:%]|[:%]>'
543
546
 
544
- ## A.1.6 -- String Literals -- simple for us because we don't decode
545
- ## the string (and indeed accept some illegal strings)
547
+ # A.1.6 -- String Literals -- simple for us because we don't decode
548
+ # the string (and indeed accept some illegal strings)
546
549
  @@string_literal = %r'L?"(?:[^\\]|\\.)*?"'m
547
550
 
548
- ## A.1.5 -- Constants
551
+ # A.1.5 -- Constants
549
552
  @@decimal_floating_constant = %r'(?:(?:\d*\.\d+|\d+\.)(?:e[-+]?\d+)?|\d+e[-+]?\d+)[fl]?'i
550
553
  @@hexadecimal_floating_constant = %r'0x(?:(?:[0-9a-f]*\.[0-9a-f]+|[0-9a-f]+\.)|[0-9a-f]+)p[-+]?\d+[fl]?'i
551
554
 
@@ -553,15 +556,15 @@ string_literal
553
556
  @@floating_constant = %r'#{@@decimal_floating_constant}|#{@@hexadecimal_floating_constant}'
554
557
  @@enumeration_constant = %r'[a-zA-Z_\\][a-zA-Z_\\0-9]*'
555
558
  @@character_constant = %r"L?'(?:[^\\]|\\.)+?'"
556
- ## (note that as with string-literals, we accept some illegal
557
- ## character-constants)
559
+ # (note that as with string-literals, we accept some illegal
560
+ # character-constants)
558
561
 
559
- ## A.1.4 -- Universal character names -- skip
562
+ # A.1.4 -- Universal character names -- skip
560
563
 
561
- ## A.1.3 -- Identifiers -- skip, since an identifier is lexically
562
- ## identical to an enumeration constant
564
+ # A.1.3 -- Identifiers -- skip, since an identifier is lexically
565
+ # identical to an enumeration constant
563
566
 
564
- ## A.1.2 Keywords
567
+ # A.1.2 Keywords
565
568
  keywords = %w'auto break case char const continue default do
566
569
  double else enum extern float for goto if inline int long register
567
570
  restrict return short signed sizeof static struct switch typedef union
@@ -574,13 +577,13 @@ restrict return short signed sizeof static struct switch typedef union
574
577
  @warning_proc = lambda{}
575
578
  @pos = C::Node::Pos.new(nil, 1, 0)
576
579
  end
577
- def initialize_copy x
580
+ def initialize_copy(x)
578
581
  @pos = x.pos.dup
579
582
  @type_names = x.type_names.dup
580
583
  end
581
584
  attr_accessor :pos, :type_names
582
585
 
583
- def parse str
586
+ def parse(str)
584
587
  if str.respond_to? :read
585
588
  str = str.read
586
589
  end
@@ -594,28 +597,47 @@ restrict return short signed sizeof static struct switch typedef union
594
597
  end
595
598
  end
596
599
 
597
- ###
598
- ### Error handler, as used by racc.
599
- ###
600
- def on_error error_token_id, error_value, value_stack
600
+ #
601
+ # Error handler, as used by racc.
602
+ #
603
+ def on_error(error_token_id, error_value, value_stack)
601
604
  if error_value == '$'
602
605
  parse_error @pos, "unexpected EOF"
603
606
  else
604
607
  parse_error(error_value.pos,
605
- "parse error on #{error_token_id.inspect}")
608
+ "parse error on #{token_to_str(error_token_id)} (#{error_value.val})")
606
609
  end
607
610
  end
608
611
 
609
- private
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 # ---------------------------------------------------------
610
632
 
611
633
  class Token
612
634
  attr_accessor :pos, :val
613
- def initialize pos, val
635
+ def initialize(pos, val)
614
636
  @pos = pos
615
637
  @val = val
616
638
  end
617
639
  end
618
- def eat str
640
+ def eat(str)
619
641
  lines = str.split(/\r\n|[\r\n]/, -1)
620
642
  if lines.length == 1
621
643
  @pos.col_num += lines[0].length
@@ -625,21 +647,19 @@ restrict return short signed sizeof static struct switch typedef union
625
647
  end
626
648
  end
627
649
 
628
- private
629
-
630
- #### Helper methods
631
-
632
- ## Make a Declaration from the given specs and declarators.
633
- def make_declaration pos, specs, declarators
650
+ #
651
+ # Make a Declaration from the given specs and declarators.
652
+ #
653
+ def make_declaration(pos, specs, declarators)
634
654
  specs.all?{|x| x.is_a?(Symbol) || x.is_a?(Type)} or raise specs.map{|x| x.class}.inspect
635
655
  decl = Declaration.new_at(pos, nil, declarators)
636
656
 
637
- ## set storage class
657
+ # set storage class
638
658
  storage_classes = specs.find_all do |x|
639
659
  [:typedef, :extern, :static, :auto, :register].include? x
640
660
  end
641
- ## 6.7.1p2: at most, one storage-class specifier may be given in
642
- ## the declaration specifiers in a declaration
661
+ # 6.7.1p2: at most, one storage-class specifier may be given in
662
+ # the declaration specifiers in a declaration
643
663
  storage_classes.length <= 1 or
644
664
  begin
645
665
  if declarators.length == 0
@@ -651,13 +671,13 @@ restrict return short signed sizeof static struct switch typedef union
651
671
  end
652
672
  decl.storage = storage_classes[0]
653
673
 
654
- ## set type (specifiers, qualifiers)
674
+ # set type (specifiers, qualifiers)
655
675
  decl.type = make_direct_type(pos, specs)
656
676
 
657
- ## set function specifiers
677
+ # set function specifiers
658
678
  decl.inline = specs.include?(:inline)
659
679
 
660
- ## look for new type names
680
+ # look for new type names
661
681
  if decl.typedef?
662
682
  decl.declarators.each do |d|
663
683
  if d.name
@@ -669,10 +689,10 @@ restrict return short signed sizeof static struct switch typedef union
669
689
  return decl
670
690
  end
671
691
 
672
- def make_function_def pos, specs, func_declarator, decl_list, defn
692
+ def make_function_def(pos, specs, func_declarator, decl_list, defn)
673
693
  add_decl_type(func_declarator, make_direct_type(pos, specs))
674
694
 
675
- ## get types from decl_list if necessary
695
+ # get types from decl_list if necessary
676
696
  function = func_declarator.indirect_type
677
697
  function.is_a? Function or
678
698
  parse_error pos, "non function type for function `#{func_declarator.name}'"
@@ -705,8 +725,8 @@ restrict return short signed sizeof static struct switch typedef union
705
725
  defn,
706
726
  :no_prototype => !decl_list.nil?)
707
727
 
708
- ## set storage class
709
- ## 6.9.1p4: only extern or static allowed
728
+ # set storage class
729
+ # 6.9.1p4: only extern or static allowed
710
730
  specs.each do |s|
711
731
  [:typedef, :auto, :register].include?(s) and
712
732
  "`#{s}' illegal for function"
@@ -714,22 +734,24 @@ restrict return short signed sizeof static struct switch typedef union
714
734
  storage_classes = specs.find_all do |s|
715
735
  s == :extern || s == :static
716
736
  end
717
- ## 6.7.1p2: at most, one storage-class specifier may be given in
718
- ## the declaration specifiers in a declaration
737
+ # 6.7.1p2: at most, one storage-class specifier may be given in
738
+ # the declaration specifiers in a declaration
719
739
  storage_classes.length <= 1 or
720
740
  "multiple or duplicate storage classes given for `#{func_declarator.name}'"
721
741
  fd.storage = storage_classes[0] if storage_classes[0]
722
742
 
723
- ## set function specifiers
724
- ## 6.7.4p5 'inline' can be repeated
743
+ # set function specifiers
744
+ # 6.7.4p5 'inline' can be repeated
725
745
  fd.inline = specs.include?(:inline)
726
746
 
727
747
  return fd
728
748
  end
729
749
 
730
- ## Make a direct type from the list of type specifiers and type
731
- ## qualifiers.
732
- def make_direct_type pos, specs
750
+ #
751
+ # Make a direct type from the list of type specifiers and type
752
+ # qualifiers.
753
+ #
754
+ def make_direct_type(pos, specs)
733
755
  specs_order = [:signed, :unsigned, :short, :long, :double, :void,
734
756
  :char, :int, :float, :_Bool, :_Complex, :_Imaginary]
735
757
 
@@ -740,8 +762,8 @@ restrict return short signed sizeof static struct switch typedef union
740
762
  (specs_order.index(a)||100) <=> (specs_order.index(b)||100)
741
763
  end
742
764
 
743
- ## set type specifiers
744
- ## 6.7.2p2: the specifier list should be one of these
765
+ # set type specifiers
766
+ # 6.7.2p2: the specifier list should be one of these
745
767
  type =
746
768
  case type_specs
747
769
  when [:void]
@@ -805,8 +827,8 @@ restrict return short signed sizeof static struct switch typedef union
805
827
  end
806
828
  type.pos ||= pos
807
829
 
808
- ## set type qualifiers
809
- ## 6.7.3p4: type qualifiers can be repeated
830
+ # set type qualifiers
831
+ # 6.7.3p4: type qualifiers can be repeated
810
832
  type.const = specs.any?{|x| x.equal? :const }
811
833
  type.restrict = specs.any?{|x| x.equal? :restrict}
812
834
  type.volatile = specs.any?{|x| x.equal? :volatile}
@@ -814,7 +836,7 @@ restrict return short signed sizeof static struct switch typedef union
814
836
  return type
815
837
  end
816
838
 
817
- def make_parameter pos, specs, indirect_type, name
839
+ def make_parameter(pos, specs, indirect_type, name)
818
840
  type = indirect_type
819
841
  if type
820
842
  type.direct_type = make_direct_type(pos, specs)
@@ -829,16 +851,18 @@ restrict return short signed sizeof static struct switch typedef union
829
851
  :register => specs.include?(:register))
830
852
  end
831
853
 
832
- def add_type_quals type, quals
854
+ def add_type_quals(type, quals)
833
855
  type.const = quals.include?(:const )
834
856
  type.restrict = quals.include?(:restrict)
835
857
  type.volatile = quals.include?(:volatile)
836
858
  return type
837
859
  end
838
860
 
839
- ## Add te given type as the "most direct" type to the given
840
- ## declarator. Return the declarator.
841
- def add_decl_type declarator, type
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)
842
866
  if declarator.indirect_type
843
867
  declarator.indirect_type.direct_type = type
844
868
  else
@@ -847,7 +871,7 @@ restrict return short signed sizeof static struct switch typedef union
847
871
  return declarator
848
872
  end
849
873
 
850
- def param_list params, var_args
874
+ def param_list(params, var_args)
851
875
  if params.length == 1 &&
852
876
  params[0].type.is_a?(Void) &&
853
877
  params[0].name.nil?
@@ -859,7 +883,7 @@ restrict return short signed sizeof static struct switch typedef union
859
883
  end
860
884
  end
861
885
 
862
- def parse_error pos, str
886
+ def parse_error(pos, str)
863
887
  raise ParseError, "#{pos}: #{str}"
864
888
  end
865
889
 
@@ -867,11 +891,11 @@ restrict return short signed sizeof static struct switch typedef union
867
891
 
868
892
  require 'set'
869
893
 
870
- #### Error classes
894
+ # Error classes
871
895
  module C
872
896
  class ParseError < StandardError; end
873
897
  end
874
898
 
875
- ### Local variables:
876
- ### mode: ruby
877
- ### end:
899
+ # Local variables:
900
+ # mode: ruby
901
+ # end: