cast 0.0.1 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,340 @@
1
+ /* -*- mode: c -*- */
2
+ /* Given to re2c to generate the lexer `yylex'.
3
+ *
4
+ * Based on c.re in the exmaples distributed with re2c.
5
+ */
6
+ #include <stdio.h>
7
+ #include <string.h>
8
+ #include "cast.h"
9
+
10
+ /*
11
+ * -------------------------------------------------------------------
12
+ * Helpers
13
+ * -------------------------------------------------------------------
14
+ */
15
+
16
+ #define new_func(Foo) \
17
+ VALUE cast_new_##Foo##_at(long pos) { \
18
+ VALUE c##Foo; \
19
+ c##Foo = rb_const_get(cast_mC, rb_intern(#Foo)); \
20
+ return rb_funcall2(c##Foo, rb_intern("new"), 0, NULL); \
21
+ }
22
+ #define set_func(Foo, field) \
23
+ VALUE cast_##Foo##_set_##field(VALUE self, VALUE value) { \
24
+ return rb_funcall2(self, rb_intern(#field "="), 1, &value); \
25
+ }
26
+
27
+ new_func(IntLiteral);
28
+ set_func(IntLiteral, format);
29
+ set_func(IntLiteral, val);
30
+ set_func(IntLiteral, suffix);
31
+
32
+ new_func(FloatLiteral);
33
+ set_func(FloatLiteral, format);
34
+ set_func(FloatLiteral, val);
35
+ set_func(FloatLiteral, exponent);
36
+ set_func(FloatLiteral, suffix);
37
+
38
+ new_func(CharLiteral);
39
+ set_func(CharLiteral, prefix);
40
+ set_func(CharLiteral, val);
41
+
42
+ new_func(StringLiteral);
43
+ set_func(StringLiteral, prefix);
44
+ set_func(StringLiteral, val);
45
+
46
+ /*
47
+ * -------------------------------------------------------------------
48
+ * yylex
49
+ * -------------------------------------------------------------------
50
+ */
51
+ #define BSIZE 8192
52
+
53
+ #define YYLTYPE VALUE
54
+
55
+ #define YYCTYPE char
56
+ #define YYCURSOR cursor
57
+ #define YYLIMIT p->lim
58
+ #define YYMARKER p->ptr
59
+ #define YYFILL(n) {}
60
+
61
+ #define RET(sym) {p->cur = cursor; rb_ary_store(p->token, 0, sym); rb_ary_store(p->token, 1, sym ); return;}
62
+ #define RETVALUE(sym) {p->cur = cursor; rb_ary_store(p->token, 0, sym); rb_ary_store(p->token, 1, value); return;}
63
+
64
+ /* Raise a ParseError. `s' is the format string for the exception
65
+ * message, which must contain exactly one '%s', which is replaced by
66
+ * the string delimited by `b' and `e'.
67
+ */
68
+ static void error1(char *s, char *b, char *e) {
69
+ char *str;
70
+ str = ALLOCA_N(char, e - b + 1);
71
+ memcpy(str, b, e-b);
72
+ str[e-b] = '\0';
73
+ rb_raise(cast_eParseError, s, str);
74
+ }
75
+
76
+ /* `token' is assumed to be a two element array, which is filled in.
77
+ */
78
+ void yylex(VALUE self, cast_Parser *p) {
79
+ char *cursor = p->cur;
80
+ char *cp, *ep;
81
+ VALUE value;
82
+ std:
83
+ p->tok = cursor;
84
+ /*!re2c
85
+ any = [\000-\377];
86
+ O = [0-7];
87
+ D = [0-9];
88
+ H = [a-fA-F0-9];
89
+ N = [1-9];
90
+ L = [a-zA-Z_];
91
+ E = [Ee] [+-]? D+;
92
+ P = [Pp] [+-]? D+;
93
+ FS = [fFlL];
94
+ IS = [uU] ([lL] | "ll" | "LL")? | ([lL] | "ll" | "LL") [uU]?;
95
+ ESC = [\\] ([abfnrtv?'"\\] | O (O O?)? | "x" H+);
96
+ */
97
+ /*!re2c
98
+ "/*" { goto comment; }
99
+ "//" { goto comment2; }
100
+
101
+ "auto" { RET(cast_sym_AUTO); }
102
+ "break" { RET(cast_sym_BREAK); }
103
+ "case" { RET(cast_sym_CASE); }
104
+ "char" { RET(cast_sym_CHAR); }
105
+ "const" { RET(cast_sym_CONST); }
106
+ "continue" { RET(cast_sym_CONTINUE); }
107
+ "default" { RET(cast_sym_DEFAULT); }
108
+ "do" { RET(cast_sym_DO); }
109
+ "double" { RET(cast_sym_DOUBLE); }
110
+ "else" { RET(cast_sym_ELSE); }
111
+ "enum" { RET(cast_sym_ENUM); }
112
+ "extern" { RET(cast_sym_EXTERN); }
113
+ "float" { RET(cast_sym_FLOAT); }
114
+ "for" { RET(cast_sym_FOR); }
115
+ "goto" { RET(cast_sym_GOTO); }
116
+ "if" { RET(cast_sym_IF); }
117
+ "int" { RET(cast_sym_INT); }
118
+ "long" { RET(cast_sym_LONG); }
119
+ "register" { RET(cast_sym_REGISTER); }
120
+ "return" { RET(cast_sym_RETURN); }
121
+ "short" { RET(cast_sym_SHORT); }
122
+ "signed" { RET(cast_sym_SIGNED); }
123
+ "sizeof" { RET(cast_sym_SIZEOF); }
124
+ "static" { RET(cast_sym_STATIC); }
125
+ "struct" { RET(cast_sym_STRUCT); }
126
+ "switch" { RET(cast_sym_SWITCH); }
127
+ "typedef" { RET(cast_sym_TYPEDEF); }
128
+ "union" { RET(cast_sym_UNION); }
129
+ "unsigned" { RET(cast_sym_UNSIGNED); }
130
+ "void" { RET(cast_sym_VOID); }
131
+ "volatile" { RET(cast_sym_VOLATILE); }
132
+ "while" { RET(cast_sym_WHILE); }
133
+ "inline" { RET(cast_sym_INLINE); }
134
+ "restrict" { RET(cast_sym_RESTRICT); }
135
+ "_Bool" { RET(cast_sym_BOOL); }
136
+ "_Complex" { RET(cast_sym_COMPLEX); }
137
+ "_Imaginary" { RET(cast_sym_IMAGINARY); }
138
+
139
+ L (L|D)* {
140
+ value = rb_str_new(p->tok, cursor - p->tok);
141
+ if (rb_funcall2(rb_funcall2(self, rb_intern("type_names"), 0, NULL),
142
+ rb_intern("include?"), 1, &value) == Qtrue) {
143
+ RETVALUE(cast_sym_TYPENAME);
144
+ } else {
145
+ RETVALUE(cast_sym_ID);
146
+ }
147
+ }
148
+
149
+ "0" [xX] H+ IS? {
150
+ value = cast_new_IntLiteral_at(p->lineno);
151
+ cast_IntLiteral_set_format(value, ID2SYM(rb_intern("hex")));
152
+ cast_IntLiteral_set_val(value, LONG2NUM(strtol(p->tok, (char **)&cp, 16)));
153
+ if (cp < cursor)
154
+ cast_IntLiteral_set_suffix(value, rb_str_new(cp, cursor - cp));
155
+ RETVALUE(cast_sym_ICON);
156
+ }
157
+ "0" D+ IS? {
158
+ value = cast_new_IntLiteral_at(p->lineno);
159
+ cast_IntLiteral_set_format(value, ID2SYM(rb_intern("oct")));
160
+ cast_IntLiteral_set_val(value, LONG2NUM(strtol(p->tok, (char **)&cp, 8)));
161
+ if (cp < cursor) {
162
+ if (cp[0] == '8' || cp[0] == '9')
163
+ rb_raise(cast_eParseError, "bad octal digit: %c", cp[0]);
164
+ cast_IntLiteral_set_suffix(value, rb_str_new(cp, cursor - cp));
165
+ }
166
+ RETVALUE(cast_sym_ICON);
167
+ }
168
+ ( "0" | [1-9] D* ) IS? {
169
+ value = cast_new_IntLiteral_at(p->lineno);
170
+ cast_IntLiteral_set_format(value, ID2SYM(rb_intern("dec")));
171
+ cast_IntLiteral_set_val(value, LONG2NUM(strtol(p->tok, (char **)&cp, 10)));
172
+ if (cp < cursor)
173
+ cast_IntLiteral_set_suffix(value, rb_str_new(cp, cursor - cp));
174
+ RETVALUE(cast_sym_ICON);
175
+ }
176
+
177
+ ( D+ E | D* "." D+ E? | D+ "." D* E? ) FS? {
178
+ value = cast_new_FloatLiteral_at(p->lineno);
179
+ cast_FloatLiteral_set_format(value, ID2SYM(rb_intern("dec")));
180
+ cast_FloatLiteral_set_val(value, rb_float_new(strtod(p->tok, (char **)&cp)));
181
+ if (cp < cursor)
182
+ cast_FloatLiteral_set_suffix(value, rb_str_new(cp, cursor - cp));
183
+
184
+ ep = (char *)memchr(p->tok, 'e', cp - p->tok);
185
+ if (!ep)
186
+ ep = (char *)memchr(p->tok, 'E', cp - p->tok);
187
+ if (ep)
188
+ cast_FloatLiteral_set_exponent(value, LONG2NUM(strtod(ep + 1, NULL)));
189
+
190
+ RETVALUE(cast_sym_FCON);
191
+ }
192
+ ( "0" [Xx] (H+ P | H* "." H+ P | H+ "." H* P) ) FS? {
193
+ value = cast_new_FloatLiteral_at(p->lineno);
194
+ cast_FloatLiteral_set_format(value, ID2SYM(rb_intern("hex")));
195
+ cast_FloatLiteral_set_val(value, rb_float_new(strtod(p->tok, (char **)&cp)));
196
+ if (cp < cursor)
197
+ cast_FloatLiteral_set_suffix(value, rb_str_new(cp, cursor - cp));
198
+
199
+ ep = (char *)memchr(p->tok, 'p', cp - p->tok);
200
+ if (!ep)
201
+ ep = (char *)memchr(p->tok, 'P', cp - p->tok);
202
+ if (ep)
203
+ cast_FloatLiteral_set_exponent(value, LONG2NUM(strtod(ep + 1, NULL)));
204
+
205
+ RETVALUE(cast_sym_FCON);
206
+ }
207
+
208
+ L? ['] (ESC|any\[\\'])+ ['] {
209
+ value = cast_new_CharLiteral_at(p->lineno);
210
+ if (p->tok[0] == '\'') {
211
+ cp = p->tok;
212
+ } else {
213
+ cast_CharLiteral_set_prefix(value, rb_str_new(p->tok, 1));
214
+ cp = p->tok + 1;
215
+ }
216
+ cast_CharLiteral_set_val(value, rb_str_new(cp + 1, cursor - cp - 2));
217
+ RETVALUE(cast_sym_CCON);
218
+ }
219
+ L? ["] (ESC|any\[\\"])* ["] {
220
+ value = cast_new_StringLiteral_at(p->lineno);
221
+ if (p->tok[0] == '"') {
222
+ cp = p->tok;
223
+ } else {
224
+ cast_StringLiteral_set_prefix(value, rb_str_new(p->tok, 1));
225
+ cp = p->tok + 1;
226
+ }
227
+ cast_StringLiteral_set_val(value, rb_str_new(cp + 1, cursor - cp - 2));
228
+ RETVALUE(cast_sym_SCON);
229
+ }
230
+
231
+ "..." { RET(cast_sym_ELLIPSIS); }
232
+ ">>=" { RET(cast_sym_RSHIFTEQ); }
233
+ "<<=" { RET(cast_sym_LSHIFTEQ); }
234
+ "+=" { RET(cast_sym_ADDEQ); }
235
+ "-=" { RET(cast_sym_SUBEQ); }
236
+ "*=" { RET(cast_sym_MULEQ); }
237
+ "/=" { RET(cast_sym_DIVEQ); }
238
+ "%=" { RET(cast_sym_MODEQ); }
239
+ "&=" { RET(cast_sym_ANDEQ); }
240
+ "^=" { RET(cast_sym_XOREQ); }
241
+ "|=" { RET(cast_sym_OREQ); }
242
+ ">>" { RET(cast_sym_RSHIFT); }
243
+ "<<" { RET(cast_sym_LSHIFT); }
244
+ "++" { RET(cast_sym_INC); }
245
+ "--" { RET(cast_sym_DEC); }
246
+ "->" { RET(cast_sym_ARROW); }
247
+ "&&" { RET(cast_sym_ANDAND); }
248
+ "||" { RET(cast_sym_OROR); }
249
+ "<=" { RET(cast_sym_LEQ); }
250
+ ">=" { RET(cast_sym_GEQ); }
251
+ "==" { RET(cast_sym_EQEQ); }
252
+ "!=" { RET(cast_sym_NEQ); }
253
+ ";" { RET(cast_sym_SEMICOLON); }
254
+ "{" { RET(cast_sym_LBRACE); }
255
+ "}" { RET(cast_sym_RBRACE); }
256
+ "," { RET(cast_sym_COMMA); }
257
+ ":" { RET(cast_sym_COLON); }
258
+ "=" { RET(cast_sym_EQ); }
259
+ "(" { RET(cast_sym_LPAREN); }
260
+ ")" { RET(cast_sym_RPAREN); }
261
+ "[" { RET(cast_sym_LBRACKET); }
262
+ "]" { RET(cast_sym_RBRACKET); }
263
+ "." { RET(cast_sym_DOT); }
264
+ "&" { RET(cast_sym_AND); }
265
+ "!" { RET(cast_sym_BANG); }
266
+ "~" { RET(cast_sym_NOT); }
267
+ "-" { RET(cast_sym_SUB); }
268
+ "+" { RET(cast_sym_ADD); }
269
+ "*" { RET(cast_sym_MUL); }
270
+ "/" { RET(cast_sym_DIV); }
271
+ "%" { RET(cast_sym_MOD); }
272
+ "<" { RET(cast_sym_LT); }
273
+ ">" { RET(cast_sym_GT); }
274
+ "^" { RET(cast_sym_XOR); }
275
+ "|" { RET(cast_sym_OR); }
276
+ "?" { RET(cast_sym_QUESTION); }
277
+
278
+ "<:" { RET(cast_sym_LBRACKET); }
279
+ "<%" { RET(cast_sym_LBRACE); }
280
+ ":>" { RET(cast_sym_RBRACKET); }
281
+ "%>" { RET(cast_sym_RBRACE); }
282
+
283
+ [ \t\v\f]+ { goto std; }
284
+
285
+ [\000]
286
+ {
287
+ if(cursor == p->eof) RET(Qnil);
288
+ goto std;
289
+ }
290
+
291
+ "\n"
292
+ {
293
+ p->pos = cursor; ++p->lineno;
294
+ goto std;
295
+ }
296
+
297
+ any
298
+ {
299
+ rb_raise(cast_eParseError, "%ld: unexpected character: %c (ASCII %d)\n", p->lineno, *p->tok, (int)*p->tok);
300
+ goto std;
301
+ }
302
+ */
303
+
304
+ comment:
305
+ /*!re2c
306
+ "*" "/" { goto std; }
307
+ "\n"
308
+ {
309
+ p->tok = p->pos = cursor; ++p->lineno;
310
+ goto comment;
311
+ }
312
+
313
+ [\000]
314
+ {
315
+ if (cursor == p->eof)
316
+ rb_raise(cast_eParseError,
317
+ "%ld: unclosed multiline comment",
318
+ p->lineno);
319
+ }
320
+
321
+ any { goto comment; }
322
+ */
323
+
324
+ comment2:
325
+ /*!re2c
326
+ "\n"
327
+ {
328
+ p->tok = p->pos = cursor; ++p->lineno;
329
+ goto std;
330
+ }
331
+
332
+ [\000]
333
+ {
334
+ if (cursor == p->eof) RET(Qnil);
335
+ goto std;
336
+ }
337
+
338
+ any { goto comment2; }
339
+ */
340
+ }
@@ -1,9 +1,11 @@
1
- dir = File.dirname(File.expand_path(__FILE__))
2
-
3
- require "#{dir}/node.rb"
4
- require "#{dir}/node_list.rb"
5
- require "#{dir}/c_nodes.rb"
6
- require "#{dir}/c.tab.rb"
7
- require "#{dir}/parse.rb"
8
- require "#{dir}/to_s.rb"
9
- require "#{dir}/to_debug.rb"
1
+ require "cast/cast"
2
+ require "cast/tempfile"
3
+ require "cast/preprocessor"
4
+ require "cast/node"
5
+ require "cast/node_list"
6
+ require "cast/c_nodes"
7
+ require "cast/c.tab"
8
+ require "cast/parse"
9
+ require "cast/to_s"
10
+ require "cast/inspect"
11
+ require "cast/version"
@@ -0,0 +1,904 @@
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
+ | specifier_qualifier_list SEMICOLON {result = make_declaration(val[0][0], val[0][1], NodeArray[])}
177
+
178
+ # Returns {Pos, [Symbol]}
179
+ specifier_qualifier_list
180
+ : type_specifier specifier_qualifier_list {val[1][1] << val[0][1]; result = val[1]}
181
+ | type_specifier {result = [val[0][0], [val[0][1]]]}
182
+ | type_qualifier specifier_qualifier_list {val[1][1] << val[0][1]; result = val[1]}
183
+ | type_qualifier {result = [val[0][0], [val[0][1]]]}
184
+
185
+ # Returns NodeArray[Declarator]
186
+ struct_declarator_list
187
+ : struct_declarator {result = NodeArray[val[0]]}
188
+ | struct_declarator_list COMMA struct_declarator {result = val[0] << val[2]}
189
+
190
+ # Returns Declarator
191
+ struct_declarator
192
+ : declarator {result = val[0]}
193
+ | declarator COLON constant_expression {result = val[0]; val[0].num_bits = val[2]}
194
+ | COLON constant_expression {result = Declarator.new_at(val[0].pos, :num_bits => val[1])}
195
+
196
+ # Returns Enum
197
+ enum_specifier
198
+ : ENUM identifier LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, val[1].val, val[3])}
199
+ | ENUM LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, nil , val[2])}
200
+ | ENUM identifier LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, val[1].val, val[3])}
201
+ | ENUM LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, nil , val[2])}
202
+ | ENUM identifier {result = Enum.new_at(val[0].pos, val[1].val, nil )}
203
+ # type names can also be used as enum names
204
+ | ENUM typedef_name LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, val[1].name, val[3])}
205
+ | ENUM typedef_name LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, val[1].name, val[3])}
206
+ | ENUM typedef_name {result = Enum.new_at(val[0].pos, val[1].name, nil )}
207
+
208
+ # Returns NodeArray[Enumerator]
209
+ enumerator_list
210
+ : enumerator {result = NodeArray[val[0]]}
211
+ | enumerator_list COMMA enumerator {result = val[0] << val[2]}
212
+
213
+ # Returns Enumerator
214
+ enumerator
215
+ : enumeration_constant {result = Enumerator.new_at(val[0].pos, val[0].val, nil )}
216
+ | enumeration_constant EQ constant_expression {result = Enumerator.new_at(val[0].pos, val[0].val, val[2])}
217
+
218
+ # Returns [Pos, Symbol]
219
+ type_qualifier
220
+ : CONST {result = [val[0].pos, :const ]}
221
+ | RESTRICT {result = [val[0].pos, :restrict]}
222
+ | VOLATILE {result = [val[0].pos, :volatile]}
223
+
224
+ # Returns [Pos, Symbol]
225
+ function_specifier
226
+ : INLINE {result = [val[0].pos, :inline]}
227
+
228
+ # Returns Declarator
229
+ declarator
230
+ : pointer direct_declarator {result = add_decl_type(val[1], val[0])}
231
+ | direct_declarator {result = val[0]}
232
+
233
+ # Returns Declarator
234
+ direct_declarator
235
+ : identifier {result = Declarator.new_at(val[0].pos, nil, val[0].val)}
236
+ | LPAREN declarator RPAREN {result = val[1]}
237
+ | direct_declarator LBRACKET type_qualifier_list assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
238
+ | direct_declarator LBRACKET type_qualifier_list RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
239
+ | direct_declarator LBRACKET assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos, nil, val[2]))}
240
+ | direct_declarator LBRACKET RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))}
241
+ | direct_declarator LBRACKET STATIC type_qualifier_list assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
242
+ | direct_declarator LBRACKET STATIC assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
243
+ | direct_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
244
+ | direct_declarator LBRACKET type_qualifier_list MUL RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
245
+ | direct_declarator LBRACKET MUL RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
246
+ | 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]))}
247
+ | direct_declarator LPAREN identifier_list RPAREN {result = add_decl_type(val[0], Function.new_at(val[0].pos, nil, val[2]))}
248
+ | direct_declarator LPAREN RPAREN {result = add_decl_type(val[0], Function.new_at(val[0].pos ))}
249
+
250
+ # Returns Pointer
251
+ pointer
252
+ : MUL type_qualifier_list {result = add_type_quals(Pointer.new_at(val[0].pos), val[1][1]) }
253
+ | MUL {result = Pointer.new_at(val[0].pos) }
254
+ | 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]}
255
+ | MUL pointer {p = Pointer.new_at(val[0].pos) ; val[1].direct_type = p; result = val[1]}
256
+
257
+ # Returns {Pos, [Symbol]}
258
+ type_qualifier_list
259
+ : type_qualifier {result = [val[0][0], [val[0][1]]]}
260
+ | type_qualifier_list type_qualifier {val[0][1] << val[1][1]; result = val[0]}
261
+
262
+ # Returns [NodeArray[Parameter], var_args?]
263
+ parameter_type_list
264
+ : parameter_list {result = [val[0], false]}
265
+ | parameter_list COMMA ELLIPSIS {result = [val[0], true ]}
266
+
267
+ # Returns NodeArray[Parameter]
268
+ parameter_list
269
+ : parameter_declaration {result = NodeArray[val[0]]}
270
+ | parameter_list COMMA parameter_declaration {result = val[0] << val[2]}
271
+
272
+ # Returns Parameter
273
+ parameter_declaration
274
+ : declaration_specifiers declarator {ind_type = val[1].indirect_type and ind_type.detach
275
+ result = make_parameter(val[0][0], val[0][1], ind_type, val[1].name)}
276
+ | declaration_specifiers abstract_declarator {result = make_parameter(val[0][0], val[0][1], val[1] , nil )}
277
+ | declaration_specifiers {result = make_parameter(val[0][0], val[0][1], nil , nil )}
278
+
279
+ # Returns NodeArray[Parameter]
280
+ identifier_list
281
+ : identifier {result = NodeArray[Parameter.new_at(val[0].pos, nil, val[0].val)]}
282
+ | identifier_list COMMA identifier {result = val[0] << Parameter.new_at(val[2].pos, nil, val[2].val)}
283
+
284
+ # Returns Type
285
+ type_name
286
+ : specifier_qualifier_list abstract_declarator {val[1].direct_type = make_direct_type(val[0][0], val[0][1]); result = val[1]}
287
+ | specifier_qualifier_list {result = make_direct_type(val[0][0], val[0][1]) }
288
+
289
+ # Returns Type
290
+ abstract_declarator
291
+ : pointer {result = val[0]}
292
+ | pointer direct_abstract_declarator {val[1].direct_type = val[0]; result = val[1]}
293
+ | direct_abstract_declarator {result = val[0]}
294
+
295
+ # Returns Type
296
+ direct_abstract_declarator
297
+ : LPAREN abstract_declarator RPAREN {result = val[1]}
298
+ | direct_abstract_declarator LBRACKET assignment_expression RBRACKET {val[0].direct_type = Array.new_at(val[0].pos, nil, val[2]); result = val[0]}
299
+ | direct_abstract_declarator LBRACKET RBRACKET {val[0].direct_type = Array.new_at(val[0].pos, nil, nil ); result = val[0]}
300
+ | LBRACKET assignment_expression RBRACKET {result = Array.new_at(val[0].pos, nil, val[1])}
301
+ | LBRACKET RBRACKET {result = Array.new_at(val[0].pos )}
302
+ | direct_abstract_declarator LBRACKET MUL RBRACKET {val[0].direct_type = Array.new_at(val[0].pos); result = val[0]} # TODO
303
+ | LBRACKET MUL RBRACKET {result = Array.new_at(val[0].pos)} # TODO
304
+ | 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]}
305
+ | direct_abstract_declarator LPAREN RPAREN {val[0].direct_type = Function.new_at(val[0].pos ); result = val[0]}
306
+ | LPAREN parameter_type_list RPAREN {result = Function.new_at(val[0].pos, nil, param_list(*val[1]), val[1][1])}
307
+ | LPAREN RPAREN {result = Function.new_at(val[0].pos )}
308
+
309
+ # Returns CustomType
310
+ typedef_name
311
+ #: identifier -- insufficient since we must distinguish between type
312
+ # names and var names (otherwise we have a conflict)
313
+ : TYPENAME {result = CustomType.new_at(val[0].pos, val[0].val)}
314
+
315
+ # Returns Expression
316
+ initializer
317
+ : assignment_expression {result = val[0]}
318
+ | LBRACE initializer_list RBRACE {result = CompoundLiteral.new_at(val[0].pos, nil, val[1])}
319
+ | LBRACE initializer_list COMMA RBRACE {result = CompoundLiteral.new_at(val[0].pos, nil, val[1])}
320
+
321
+ # Returns NodeArray[MemberInit]
322
+ initializer_list
323
+ : designation initializer {result = NodeArray[MemberInit.new_at(val[0][0] , val[0][1], val[1])]}
324
+ | initializer {result = NodeArray[MemberInit.new_at(val[0].pos, nil , val[0])]}
325
+ | initializer_list COMMA designation initializer {result = val[0] << MemberInit.new_at(val[2][0] , val[2][1], val[3])}
326
+ | initializer_list COMMA initializer {result = val[0] << MemberInit.new_at(val[2].pos, nil , val[2])}
327
+
328
+ # Returns {Pos, NodeArray[Expression|Token]}
329
+ designation
330
+ : designator_list EQ {result = val[0]}
331
+
332
+ # Returns {Pos, NodeArray[Expression|Token]}
333
+ designator_list
334
+ : designator {result = val[0]; val[0][1] = NodeArray[val[0][1]]}
335
+ | designator_list designator {result = val[0]; val[0][1] << val[1][1]}
336
+
337
+ # Returns {Pos, Expression|Member}
338
+ designator
339
+ : LBRACKET constant_expression RBRACKET {result = [val[1].pos, val[1] ]}
340
+ | DOT identifier {result = [val[1].pos, Member.new_at(val[1].pos, val[1].val)]}
341
+
342
+ # A.2.1 Expressions
343
+
344
+ # Returns Expression
345
+ primary_expression
346
+ : identifier {result = Variable.new_at(val[0].pos, val[0].val)}
347
+ | constant {result = val[0]}
348
+ | string_literal {result = val[0]}
349
+ # GCC EXTENSION: allow a compound statement in parentheses as an expression
350
+ | LPAREN expression RPAREN {result = val[1]}
351
+ | LPAREN compound_statement RPAREN {block_expressions_enabled? or parse_error val[0].pos, "compound statement found where expression expected"
352
+ result = BlockExpression.new(val[1]); result.pos = val[0].pos}
353
+
354
+ # Returns Expression
355
+ postfix_expression
356
+ : primary_expression {result = val[0]}
357
+ | postfix_expression LBRACKET expression RBRACKET {result = Index .new_at(val[0].pos, val[0], val[2])}
358
+ | postfix_expression LPAREN argument_expression_list RPAREN {result = Call .new_at(val[0].pos, val[0], val[2] )}
359
+ | postfix_expression LPAREN RPAREN {result = Call .new_at(val[0].pos, val[0], NodeArray[])}
360
+ | postfix_expression DOT identifier {result = Dot .new_at(val[0].pos, val[0], Member.new(val[2].val))}
361
+ | postfix_expression ARROW identifier {result = Arrow .new_at(val[0].pos, val[0], Member.new(val[2].val))}
362
+ | postfix_expression INC {result = PostInc .new_at(val[0].pos, val[0] )}
363
+ | postfix_expression DEC {result = PostDec .new_at(val[0].pos, val[0] )}
364
+ | LPAREN type_name RPAREN LBRACE initializer_list RBRACE {result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])}
365
+ | LPAREN type_name RPAREN LBRACE initializer_list COMMA RBRACE {result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])}
366
+
367
+ # Returns [Expression|Type]
368
+ argument_expression_list
369
+ : argument_expression {result = NodeArray[val[0]]}
370
+ | argument_expression_list COMMA argument_expression {result = val[0] << val[2]}
371
+
372
+ # Returns Expression|Type -- EXTENSION: allow type names here too, to support some standard library macros (e.g., va_arg [7.15.1.1])
373
+ argument_expression
374
+ : assignment_expression {result = val[0]}
375
+ | type_name {result = val[0]}
376
+
377
+ # Returns Expression
378
+ unary_expression
379
+ : postfix_expression {result = val[0]}
380
+ | INC unary_expression {result = PreInc.new_at(val[0].pos, val[1])}
381
+ | DEC unary_expression {result = PreDec.new_at(val[0].pos, val[1])}
382
+ | unary_operator cast_expression {result = val[0][0].new_at(val[0][1], val[1])}
383
+ | SIZEOF unary_expression {result = Sizeof.new_at(val[0].pos, val[1])}
384
+ | SIZEOF LPAREN type_name RPAREN {result = Sizeof.new_at(val[0].pos, val[2])}
385
+
386
+ # Returns [Class, Pos]
387
+ unary_operator
388
+ : AND {result = [Address , val[0].pos]}
389
+ | MUL {result = [Dereference, val[0].pos]}
390
+ | ADD {result = [Positive , val[0].pos]}
391
+ | SUB {result = [Negative , val[0].pos]}
392
+ | NOT {result = [BitNot , val[0].pos]}
393
+ | BANG {result = [Not , val[0].pos]}
394
+
395
+ # Returns Expression
396
+ cast_expression
397
+ : unary_expression {result = val[0]}
398
+ | LPAREN type_name RPAREN cast_expression {result = Cast.new_at(val[0].pos, val[1], val[3])}
399
+
400
+ # Returns Expression
401
+ multiplicative_expression
402
+ : cast_expression {result = val[0]}
403
+ | multiplicative_expression MUL cast_expression {result = Multiply.new_at(val[0].pos, val[0], val[2])}
404
+ | multiplicative_expression DIV cast_expression {result = Divide .new_at(val[0].pos, val[0], val[2])}
405
+ | multiplicative_expression MOD cast_expression {result = Mod .new_at(val[0].pos, val[0], val[2])}
406
+
407
+ # Returns Expression
408
+ additive_expression
409
+ : multiplicative_expression {result = val[0]}
410
+ | additive_expression ADD multiplicative_expression {result = Add .new_at(val[0].pos, val[0], val[2])}
411
+ | additive_expression SUB multiplicative_expression {result = Subtract.new_at(val[0].pos, val[0], val[2])}
412
+
413
+ # Returns Expression
414
+ shift_expression
415
+ : additive_expression {result = val[0]}
416
+ | shift_expression LSHIFT additive_expression {result = ShiftLeft .new_at(val[0].pos, val[0], val[2])}
417
+ | shift_expression RSHIFT additive_expression {result = ShiftRight.new_at(val[0].pos, val[0], val[2])}
418
+
419
+ # Returns Expression
420
+ relational_expression
421
+ : shift_expression {result = val[0]}
422
+ | relational_expression LT shift_expression {result = Less.new_at(val[0].pos, val[0], val[2])}
423
+ | relational_expression GT shift_expression {result = More.new_at(val[0].pos, val[0], val[2])}
424
+ | relational_expression LEQ shift_expression {result = LessOrEqual.new_at(val[0].pos, val[0], val[2])}
425
+ | relational_expression GEQ shift_expression {result = MoreOrEqual.new_at(val[0].pos, val[0], val[2])}
426
+
427
+ # Returns Expression
428
+ equality_expression
429
+ : relational_expression {result = val[0]}
430
+ | equality_expression EQEQ relational_expression {result = Equal .new_at(val[0].pos, val[0], val[2])}
431
+ | equality_expression NEQ relational_expression {result = NotEqual.new_at(val[0].pos, val[0], val[2])}
432
+
433
+ # Returns Expression
434
+ and_expression
435
+ : equality_expression {result = val[0]}
436
+ | and_expression AND equality_expression {result = BitAnd.new_at(val[0].pos, val[0], val[2])}
437
+
438
+ # Returns Expression
439
+ exclusive_or_expression
440
+ : and_expression {result = val[0]}
441
+ | exclusive_or_expression XOR and_expression {result = BitXor.new_at(val[0].pos, val[0], val[2])}
442
+
443
+ # Returns Expression
444
+ inclusive_or_expression
445
+ : exclusive_or_expression {result = val[0]}
446
+ | inclusive_or_expression OR exclusive_or_expression {result = BitOr.new_at(val[0].pos, val[0], val[2])}
447
+
448
+ # Returns Expression
449
+ logical_and_expression
450
+ : inclusive_or_expression {result = val[0]}
451
+ | logical_and_expression ANDAND inclusive_or_expression {result = And.new_at(val[0].pos, val[0], val[2])}
452
+
453
+ # Returns Expression
454
+ logical_or_expression
455
+ : logical_and_expression {result = val[0]}
456
+ | logical_or_expression OROR logical_and_expression {result = Or.new_at(val[0].pos, val[0], val[2])}
457
+
458
+ # Returns Expression
459
+ conditional_expression
460
+ : logical_or_expression {result = val[0]}
461
+ | logical_or_expression QUESTION expression COLON conditional_expression {result = Conditional.new_at(val[0].pos, val[0], val[2], val[4])}
462
+
463
+ # Returns Expression
464
+ assignment_expression
465
+ : conditional_expression {result = val[0]}
466
+ | unary_expression assignment_operator assignment_expression {result = val[1].new_at(val[0].pos, val[0], val[2])}
467
+
468
+ # Returns Class
469
+ assignment_operator
470
+ : EQ {result = Assign}
471
+ | MULEQ {result = MultiplyAssign}
472
+ | DIVEQ {result = DivideAssign}
473
+ | MODEQ {result = ModAssign}
474
+ | ADDEQ {result = AddAssign}
475
+ | SUBEQ {result = SubtractAssign}
476
+ | LSHIFTEQ {result = ShiftLeftAssign}
477
+ | RSHIFTEQ {result = ShiftRightAssign}
478
+ | ANDEQ {result = BitAndAssign}
479
+ | XOREQ {result = BitXorAssign}
480
+ | OREQ {result = BitOrAssign}
481
+
482
+ # Returns Expression
483
+ expression
484
+ : assignment_expression {result = val[0]}
485
+ | expression COMMA assignment_expression {
486
+ if val[0].is_a? Comma
487
+ if val[2].is_a? Comma
488
+ val[0].exprs.push(*val[2].exprs)
489
+ else
490
+ val[0].exprs << val[2]
491
+ end
492
+ result = val[0]
493
+ else
494
+ if val[2].is_a? Comma
495
+ val[2].exprs.unshift(val[0])
496
+ val[2].pos = val[0].pos
497
+ result = val[2]
498
+ else
499
+ result = Comma.new_at(val[0].pos, NodeArray[val[0], val[2]])
500
+ end
501
+ end
502
+ }
503
+
504
+ # Returns Expression
505
+ constant_expression
506
+ : conditional_expression {result = val[0]}
507
+
508
+ # A.1.1 -- Lexical elements
509
+ #
510
+ # token
511
+ # : keyword (raw string)
512
+ # | identifier expanded below
513
+ # | constant expanded below
514
+ # | string_literal expanded below
515
+ # | punctuator (raw string)
516
+ #
517
+ # preprocessing-token (skip)
518
+
519
+ # Returns Token
520
+ identifier
521
+ : ID {result = val[0]}
522
+
523
+ # Returns Literal
524
+ constant
525
+ : ICON {result = val[0].val; result.pos = val[0].pos}
526
+ | FCON {result = val[0].val; result.pos = val[0].pos}
527
+ #| enumeration_constant -- these are parsed as identifiers at all
528
+ # places the `constant' nonterminal appears
529
+ | CCON {result = val[0].val; result.pos = val[0].pos}
530
+
531
+ # Returns Token
532
+ enumeration_constant
533
+ : ID {result = val[0]}
534
+
535
+ # Returns StringLiteral
536
+ # Also handles string literal concatenation (6.4.5.4)
537
+ string_literal
538
+ : string_literal SCON {val[0].val << val[1].val.val; result = val[0]}
539
+ | SCON { result = val[0].val; result.pos = val[0].pos }
540
+
541
+ ---- inner
542
+ # A.1.9 -- Preprocessing numbers -- skip
543
+ # A.1.8 -- Header names -- skip
544
+
545
+ # A.1.7 -- Puncuators -- we don't bother with {##,#,%:,%:%:} since
546
+ # we don't do preprocessing
547
+ @@punctuators = %r'\+\+|-[->]|&&|\|\||\.\.\.|(?:<<|>>|[<>=!*/%+\-&^|])=?|[\[\](){}.~?:;,]'
548
+ @@digraphs = %r'<[:%]|[:%]>'
549
+
550
+ # A.1.6 -- String Literals -- simple for us because we don't decode
551
+ # the string (and indeed accept some illegal strings)
552
+ @@string_literal = %r'L?"(?:[^\\]|\\.)*?"'m
553
+
554
+ # A.1.5 -- Constants
555
+ @@decimal_floating_constant = %r'(?:(?:\d*\.\d+|\d+\.)(?:e[-+]?\d+)?|\d+e[-+]?\d+)[fl]?'i
556
+ @@hexadecimal_floating_constant = %r'0x(?:(?:[0-9a-f]*\.[0-9a-f]+|[0-9a-f]+\.)|[0-9a-f]+)p[-+]?\d+[fl]?'i
557
+
558
+ @@integer_constant = %r'(?:[1-9][0-9]*|0x[0-9a-f]+|0[0-7]*)(?:ul?l?|ll?u?)?'i
559
+ @@floating_constant = %r'#{@@decimal_floating_constant}|#{@@hexadecimal_floating_constant}'
560
+ @@enumeration_constant = %r'[a-zA-Z_\\][a-zA-Z_\\0-9]*'
561
+ @@character_constant = %r"L?'(?:[^\\]|\\.)+?'"
562
+ # (note that as with string-literals, we accept some illegal
563
+ # character-constants)
564
+
565
+ # A.1.4 -- Universal character names -- skip
566
+
567
+ # A.1.3 -- Identifiers -- skip, since an identifier is lexically
568
+ # identical to an enumeration constant
569
+
570
+ # A.1.2 Keywords
571
+ keywords = %w'auto break case char const continue default do
572
+ double else enum extern float for goto if inline int long register
573
+ restrict return short signed sizeof static struct switch typedef union
574
+ unsigned void volatile while _Bool _Complex _Imaginary'
575
+ @@keywords = %r"#{keywords.join('|')}"
576
+
577
+ def initialize
578
+ @type_names = ::Set.new
579
+
580
+ @warning_proc = lambda{}
581
+ @pos = C::Node::Pos.new(nil, 1, 0)
582
+ end
583
+ def initialize_copy(x)
584
+ @pos = x.pos.dup
585
+ @type_names = x.type_names.dup
586
+ end
587
+ attr_accessor :pos, :type_names
588
+
589
+ def parse(str)
590
+ if str.respond_to? :read
591
+ str = str.read
592
+ end
593
+ @str = str
594
+ begin
595
+ prepare_lexer(str)
596
+ return do_parse
597
+ rescue ParseError => e
598
+ e.set_backtrace(caller)
599
+ raise
600
+ end
601
+ end
602
+
603
+ #
604
+ # Error handler, as used by racc.
605
+ #
606
+ def on_error(error_token_id, error_value, value_stack)
607
+ if error_value == '$'
608
+ parse_error @pos, "unexpected EOF"
609
+ else
610
+ parse_error(error_value.pos,
611
+ "parse error on #{token_to_str(error_token_id)} (#{error_value.val})")
612
+ end
613
+ end
614
+
615
+ def self.feature(name)
616
+ attr_writer "#{name}_enabled"
617
+ class_eval <<-EOS
618
+ def enable_#{name}
619
+ @#{name}_enabled = true
620
+ end
621
+ def #{name}_enabled?
622
+ @#{name}_enabled
623
+ end
624
+ EOS
625
+ end
626
+ private_class_method :feature
627
+
628
+ #
629
+ # Allow blocks in parentheses as expressions, as per the gcc
630
+ # extension. [http://rubyurl.com/iB7]
631
+ #
632
+ feature :block_expressions
633
+
634
+ private # ---------------------------------------------------------
635
+
636
+ class Token
637
+ attr_accessor :pos, :val
638
+ def initialize(pos, val)
639
+ @pos = pos
640
+ @val = val
641
+ end
642
+ end
643
+ def eat(str)
644
+ lines = str.split(/\r\n|[\r\n]/, -1)
645
+ if lines.length == 1
646
+ @pos.col_num += lines[0].length
647
+ else
648
+ @pos.line_num += lines.length - 1
649
+ @pos.col_num = lines[-1].length
650
+ end
651
+ end
652
+
653
+ #
654
+ # Make a Declaration from the given specs and declarators.
655
+ #
656
+ def make_declaration(pos, specs, declarators)
657
+ specs.all?{|x| x.is_a?(Symbol) || x.is_a?(Type)} or raise specs.map{|x| x.class}.inspect
658
+ decl = Declaration.new_at(pos, nil, declarators)
659
+
660
+ # set storage class
661
+ storage_classes = specs.find_all do |x|
662
+ [:typedef, :extern, :static, :auto, :register].include? x
663
+ end
664
+ # 6.7.1p2: at most, one storage-class specifier may be given in
665
+ # the declaration specifiers in a declaration
666
+ storage_classes.length <= 1 or
667
+ begin
668
+ if declarators.length == 0
669
+ for_name = ''
670
+ else
671
+ for_name = "for `#{declarators[0].name}'"
672
+ end
673
+ parse_error pos, "multiple or duplicate storage classes given #{for_name}'"
674
+ end
675
+ decl.storage = storage_classes[0]
676
+
677
+ # set type (specifiers, qualifiers)
678
+ decl.type = make_direct_type(pos, specs)
679
+
680
+ # set function specifiers
681
+ decl.inline = specs.include?(:inline)
682
+
683
+ # look for new type names
684
+ if decl.typedef?
685
+ decl.declarators.each do |d|
686
+ if d.name
687
+ @type_names << d.name
688
+ end
689
+ end
690
+ end
691
+
692
+ return decl
693
+ end
694
+
695
+ def make_function_def(pos, specs, func_declarator, decl_list, defn)
696
+ add_decl_type(func_declarator, make_direct_type(pos, specs))
697
+
698
+ # get types from decl_list if necessary
699
+ function = func_declarator.indirect_type
700
+ function.is_a? Function or
701
+ parse_error pos, "non function type for function `#{func_declarator.name}'"
702
+ params = function.params
703
+ if decl_list
704
+ params.all?{|p| p.type.nil?} or
705
+ parse_error pos, "both prototype and declaration list given for `#{func_declarator.name}'"
706
+ decl_list.each do |declaration|
707
+ declaration.declarators.each do |declarator|
708
+ param = params.find{|p| p.name == declarator.name} or
709
+ parse_error pos, "no parameter named #{declarator.name}"
710
+ if declarator.indirect_type
711
+ param.type = declarator.indirect_type
712
+ param.type.direct_type = declaration.type.dup
713
+ else
714
+ param.type = declaration.type.dup
715
+ end
716
+ end
717
+ end
718
+ params.all?{|p| p.type} or
719
+ begin
720
+ s = params.find_all{|p| p.type.nil?}.map{|p| "`#{p.name}'"}.join(' and ')
721
+ parse_error pos, "types missing for parameters #{s}"
722
+ end
723
+ end
724
+
725
+ fd = FunctionDef.new_at(pos,
726
+ function.detach,
727
+ func_declarator.name,
728
+ defn,
729
+ :no_prototype => !decl_list.nil?)
730
+
731
+ # set storage class
732
+ # 6.9.1p4: only extern or static allowed
733
+ specs.each do |s|
734
+ [:typedef, :auto, :register].include?(s) and
735
+ "`#{s}' illegal for function"
736
+ end
737
+ storage_classes = specs.find_all do |s|
738
+ s == :extern || s == :static
739
+ end
740
+ # 6.7.1p2: at most, one storage-class specifier may be given in
741
+ # the declaration specifiers in a declaration
742
+ storage_classes.length <= 1 or
743
+ "multiple or duplicate storage classes given for `#{func_declarator.name}'"
744
+ fd.storage = storage_classes[0] if storage_classes[0]
745
+
746
+ # set function specifiers
747
+ # 6.7.4p5 'inline' can be repeated
748
+ fd.inline = specs.include?(:inline)
749
+
750
+ return fd
751
+ end
752
+
753
+ #
754
+ # Make a direct type from the list of type specifiers and type
755
+ # qualifiers.
756
+ #
757
+ def make_direct_type(pos, specs)
758
+ specs_order = [:signed, :unsigned, :short, :long, :double, :void,
759
+ :char, :int, :float, :_Bool, :_Complex, :_Imaginary]
760
+
761
+ type_specs = specs.find_all do |x|
762
+ specs_order.include?(x) || !x.is_a?(Symbol)
763
+ end
764
+ type_specs.sort! do |a, b|
765
+ (specs_order.index(a)||100) <=> (specs_order.index(b)||100)
766
+ end
767
+
768
+ # set type specifiers
769
+ # 6.7.2p2: the specifier list should be one of these
770
+ type =
771
+ case type_specs
772
+ when [:void]
773
+ Void.new
774
+ when [:char]
775
+ Char.new
776
+ when [:signed, :char]
777
+ Char.new :signed => true
778
+ when [:unsigned, :char]
779
+ Char.new :signed => false
780
+ when [:short], [:signed, :short], [:short, :int],
781
+ [:signed, :short, :int]
782
+ Int.new :longness => -1
783
+ when [:unsigned, :short], [:unsigned, :short, :int]
784
+ Int.new :unsigned => true, :longness => -1
785
+ when [:int], [:signed], [:signed, :int]
786
+ Int.new
787
+ when [:unsigned], [:unsigned, :int]
788
+ Int.new :unsigned => true
789
+ when [:long], [:signed, :long], [:long, :int],
790
+ [:signed, :long, :int]
791
+ Int.new :longness => 1
792
+ when [:unsigned, :long], [:unsigned, :long, :int]
793
+ Int.new :longness => 1, :unsigned => true
794
+ when [:long, :long], [:signed, :long, :long],
795
+ [:long, :long, :int], [:signed, :long, :long, :int]
796
+ Int.new :longness => 2
797
+ when [:unsigned, :long, :long], [:unsigned, :long, :long, :int]
798
+ Int.new :longness => 2, :unsigned => true
799
+ when [:float]
800
+ Float.new
801
+ when [:double]
802
+ Float.new :longness => 1
803
+ when [:long, :double]
804
+ Float.new :longness => 2
805
+ when [:_Bool]
806
+ Bool.new
807
+ when [:float, :_Complex]
808
+ Complex.new
809
+ when [:double, :_Complex]
810
+ Complex.new :longness => 1
811
+ when [:long, :double, :_Complex]
812
+ Complex.new :longness => 2
813
+ when [:float, :_Imaginary]
814
+ Imaginary.new
815
+ when [:double, :_Imaginary]
816
+ Imaginary.new :longness => 1
817
+ when [:long, :double, :_Imaginary]
818
+ Imaginary.new :longness => 2
819
+ else
820
+ if type_specs.length == 1 &&
821
+ [CustomType, Struct, Union, Enum].any?{|c| type_specs[0].is_a? c}
822
+ type_specs[0]
823
+ else
824
+ if type_specs == []
825
+ parse_error pos, "no type specifiers given"
826
+ else
827
+ parse_error pos, "invalid type specifier combination: #{type_specs.join(' ')}"
828
+ end
829
+ end
830
+ end
831
+ type.pos ||= pos
832
+
833
+ # set type qualifiers
834
+ # 6.7.3p4: type qualifiers can be repeated
835
+ type.const = specs.any?{|x| x.equal? :const }
836
+ type.restrict = specs.any?{|x| x.equal? :restrict}
837
+ type.volatile = specs.any?{|x| x.equal? :volatile}
838
+
839
+ return type
840
+ end
841
+
842
+ def make_parameter(pos, specs, indirect_type, name)
843
+ type = indirect_type
844
+ if type
845
+ type.direct_type = make_direct_type(pos, specs)
846
+ else
847
+ type = make_direct_type(pos, specs)
848
+ end
849
+ [:typedef, :extern, :static, :auto, :inline].each do |sym|
850
+ specs.include? sym and
851
+ parse_error pos, "parameter `#{declarator.name}' declared `#{sym}'"
852
+ end
853
+ return Parameter.new_at(pos, type, name,
854
+ :register => specs.include?(:register))
855
+ end
856
+
857
+ def add_type_quals(type, quals)
858
+ type.const = quals.include?(:const )
859
+ type.restrict = quals.include?(:restrict)
860
+ type.volatile = quals.include?(:volatile)
861
+ return type
862
+ end
863
+
864
+ #
865
+ # Add te given type as the "most direct" type to the given
866
+ # declarator. Return the declarator.
867
+ #
868
+ def add_decl_type(declarator, type)
869
+ if declarator.indirect_type
870
+ declarator.indirect_type.direct_type = type
871
+ else
872
+ declarator.indirect_type = type
873
+ end
874
+ return declarator
875
+ end
876
+
877
+ def param_list(params, var_args)
878
+ if params.length == 1 &&
879
+ params[0].type.is_a?(Void) &&
880
+ params[0].name.nil?
881
+ return NodeArray[]
882
+ elsif params.empty?
883
+ return nil
884
+ else
885
+ return params
886
+ end
887
+ end
888
+
889
+ def parse_error(pos, str)
890
+ raise ParseError, "#{pos}: #{str}"
891
+ end
892
+
893
+ ---- header
894
+
895
+ require 'set'
896
+
897
+ # Error classes
898
+ module C
899
+ class ParseError < StandardError; end
900
+ end
901
+
902
+ # Local variables:
903
+ # mode: ruby
904
+ # end: