cast 0.1.0 → 0.2.0
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/.gitignore +8 -0
- data/CHANGELOG +50 -0
- data/Gemfile +2 -0
- data/LICENSE +22 -0
- data/README.markdown +1948 -0
- data/Rakefile +22 -0
- data/cast.gemspec +20 -0
- data/ext/cast.c +6 -0
- data/ext/extconf.rb +1 -1
- data/ext/parser.c +2 -2
- data/ext/yylex.c +2592 -4171
- data/ext/yylex.re +20 -26
- data/lib/cast.rb +11 -16
- data/lib/cast/c.tab.rb +2252 -2231
- data/lib/cast/c.y +185 -161
- data/lib/cast/c_nodes.rb +181 -391
- data/lib/cast/inspect.rb +8 -10
- data/lib/cast/node.rb +362 -365
- data/lib/cast/node_list.rb +156 -165
- data/lib/cast/parse.rb +86 -65
- data/lib/cast/preprocessor.rb +72 -0
- data/lib/cast/tempfile.rb +33 -0
- data/lib/cast/to_s.rb +83 -75
- data/lib/cast/version.rb +11 -0
- data/test/all.rb +5 -0
- data/test/{test_c_nodes.rb → c_nodes_test.rb} +91 -23
- data/test/lexer_test.rb +323 -0
- data/test/{test_node_list.rb → node_list_test.rb} +367 -396
- data/test/{test_node.rb → node_test.rb} +142 -160
- data/test/{test_parse.rb → parse_test.rb} +63 -17
- data/test/{test_parser.rb → parser_test.rb} +62 -22
- data/test/preprocessor_test.rb +87 -0
- data/test/render_test.rb +2086 -0
- data/test/{run.rb → test_helper.rb} +76 -88
- metadata +100 -54
- data/README +0 -6
- data/doc/index.html +0 -2505
- data/ext/cast_ext.c +0 -10
data/lib/cast/c.y
CHANGED
@@ -1,33 +1,33 @@
|
|
1
1
|
class C::Parser
|
2
|
-
|
2
|
+
# shift/reduce conflict on "if (c) if (c) ; else ; else ;"
|
3
3
|
expect 1
|
4
4
|
rule
|
5
5
|
|
6
|
-
|
6
|
+
# A.2.4 External definitions
|
7
7
|
|
8
|
-
|
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
|
-
|
13
|
+
# Returns Declaration|FunctionDef
|
14
14
|
external_declaration
|
15
15
|
: function_definition {result = val[0]}
|
16
16
|
| declaration {result = val[0]}
|
17
17
|
|
18
|
-
|
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
|
-
|
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
|
-
|
28
|
+
# A.2.3 Statements
|
29
29
|
|
30
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
57
|
+
# Returns Declaration|Statement
|
58
58
|
block_item
|
59
59
|
: declaration {result = val[0]}
|
60
60
|
| statement {result = val[0]}
|
61
61
|
|
62
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
100
|
+
# A.2.2 Declarations
|
101
101
|
|
102
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
223
|
+
# Returns [Pos, Symbol]
|
224
224
|
function_specifier
|
225
225
|
: INLINE {result = [val[0].pos, :inline]}
|
226
226
|
|
227
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
327
|
+
# Returns {Pos, NodeArray[Expression|Token]}
|
328
328
|
designation
|
329
329
|
: designator_list EQ {result = val[0]}
|
330
330
|
|
331
|
-
|
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
|
-
|
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
|
-
|
341
|
+
# A.2.1 Expressions
|
342
342
|
|
343
|
-
|
343
|
+
# Returns Expression
|
344
344
|
primary_expression
|
345
|
-
: identifier
|
346
|
-
| constant
|
347
|
-
| string_literal
|
348
|
-
|
349
|
-
|
350
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
503
|
+
# Returns Expression
|
501
504
|
constant_expression
|
502
505
|
: conditional_expression {result = val[0]}
|
503
506
|
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
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
|
-
|
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
|
-
|
530
|
+
# Returns Token
|
528
531
|
enumeration_constant
|
529
532
|
: ID {result = val[0]}
|
530
533
|
|
531
|
-
|
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
|
-
|
537
|
-
|
539
|
+
# A.1.9 -- Preprocessing numbers -- skip
|
540
|
+
# A.1.8 -- Header names -- skip
|
538
541
|
|
539
|
-
|
540
|
-
|
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
|
-
|
545
|
-
|
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
|
-
|
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
|
-
|
557
|
-
|
559
|
+
# (note that as with string-literals, we accept some illegal
|
560
|
+
# character-constants)
|
558
561
|
|
559
|
-
|
562
|
+
# A.1.4 -- Universal character names -- skip
|
560
563
|
|
561
|
-
|
562
|
-
|
564
|
+
# A.1.3 -- Identifiers -- skip, since an identifier is lexically
|
565
|
+
# identical to an enumeration constant
|
563
566
|
|
564
|
-
|
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
|
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
|
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
|
-
|
599
|
-
|
600
|
-
def on_error
|
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.
|
608
|
+
"parse error on #{token_to_str(error_token_id)} (#{error_value.val})")
|
606
609
|
end
|
607
610
|
end
|
608
611
|
|
609
|
-
|
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
|
635
|
+
def initialize(pos, val)
|
614
636
|
@pos = pos
|
615
637
|
@val = val
|
616
638
|
end
|
617
639
|
end
|
618
|
-
def eat
|
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
|
-
|
629
|
-
|
630
|
-
|
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
|
-
|
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
|
-
|
642
|
-
|
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
|
-
|
674
|
+
# set type (specifiers, qualifiers)
|
655
675
|
decl.type = make_direct_type(pos, specs)
|
656
676
|
|
657
|
-
|
677
|
+
# set function specifiers
|
658
678
|
decl.inline = specs.include?(:inline)
|
659
679
|
|
660
|
-
|
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
|
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
|
-
|
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
|
-
|
709
|
-
|
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
|
-
|
718
|
-
|
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
|
-
|
724
|
-
|
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
|
-
|
731
|
-
|
732
|
-
|
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
|
-
|
744
|
-
|
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
|
-
|
809
|
-
|
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
|
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
|
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
|
-
|
840
|
-
|
841
|
-
|
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
|
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
|
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
|
-
|
894
|
+
# Error classes
|
871
895
|
module C
|
872
896
|
class ParseError < StandardError; end
|
873
897
|
end
|
874
898
|
|
875
|
-
|
876
|
-
|
877
|
-
|
899
|
+
# Local variables:
|
900
|
+
# mode: ruby
|
901
|
+
# end:
|