Diff of /c99.y [000000] .. [be92a4]  Maximize  Restore

Switch to unified view

a b/c99.y
1
%token IDENTIFIER CONSTANT STRING_LITERAL SIZEOF
2
%token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
3
%token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
4
%token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
5
%token XOR_ASSIGN OR_ASSIGN TYPE_NAME
6
7
%token TYPEDEF EXTERN STATIC AUTO REGISTER INLINE RESTRICT
8
%token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID
9
%token BOOL COMPLEX IMAGINARY
10
%token STRUCT UNION ENUM ELLIPSIS
11
12
%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
13
14
%union { char str[128]; }
15
16
%start translation_unit
17
18
%{
19
/* fifo to store expression strings */
20
#define NULL 0
21
22
#define STMT_SIZE 128
23
#define FIFO_SIZE 20
24
25
static char *s_fifo[FIFO_SIZE][STMT_SIZE];
26
static unsigned int s_fifor, s_fifow;
27
28
void yyerror(char const *s);
29
void push(const char *psz);
30
char *pop(void);
31
32
%}
33
34
%%
35
36
primary_expression
37
    : IDENTIFIER
38
    | CONSTANT
39
    | STRING_LITERAL
40
    | '(' expression ')'
41
    { sprintf($<str>$, "( %s )",$<str>2); }
42
    ;
43
44
postfix_expression
45
    : primary_expression
46
    { sprintf($<str>$, "%s",$<str>1); }
47
    | postfix_expression '[' expression ']'
48
    { sprintf($<str>$, "[%s]",$<str>2); }
49
    | postfix_expression '(' ')'
50
    { sprintf($<str>$, "%s()",$<str>1); }
51
    | postfix_expression '(' argument_expression_list ')'
52
    { sprintf($<str>$, "%s(%s)",$<str>1, $<str>3); }
53
    | postfix_expression '.' IDENTIFIER
54
    { sprintf($<str>$, "%s.%s",$<str>1,$<str>3); }
55
    | postfix_expression PTR_OP IDENTIFIER
56
    { sprintf($<str>$, "%s %s %s",$<str>1, $<str>2, $<str>3);}
57
    | postfix_expression INC_OP
58
    { sprintf($<str>$, "(%s:=%s+1)",$<str>1, $<str>1); }
59
    | postfix_expression DEC_OP
60
    { sprintf($<str>$, "(%s:=%s-1)",$<str>1, $<str>1); }
61
    | '(' type_name ')' '{' initializer_list '}'
62
    | '(' type_name ')' '{' initializer_list ',' '}'
63
    ;
64
65
argument_expression_list
66
    : assignment_expression
67
    | argument_expression_list ',' assignment_expression
68
    { sprintf($<str>$, "%s, %s",$<str>1, $<str>3); }
69
    ;
70
71
unary_expression
72
    : postfix_expression
73
    | INC_OP unary_expression
74
    { sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
75
    | DEC_OP unary_expression
76
    { sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
77
    | unary_operator cast_expression
78
    { sprintf($<str>$, "%s^",$<str>2); }
79
    | SIZEOF unary_expression
80
    { sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
81
    | SIZEOF '(' type_name ')'
82
    { sprintf($<str>$, "%s (%s)",$<str>1, $<str>3); }
83
    ;
84
85
unary_operator
86
    : '&'
87
    | '*'
88
    | '+'
89
    | '-'
90
    | '~'
91
    | '!'
92
    ;
93
94
cast_expression
95
    : unary_expression
96
    | '(' type_name ')' cast_expression
97
    { sprintf($<str>$, "ANY_TO_%s(%s)",$<str>2, $<str>4); }
98
    ;
99
100
multiplicative_expression
101
    : cast_expression
102
    | multiplicative_expression '*' cast_expression
103
    { sprintf($<str>$, "%s * %s",$<str>1, $<str>3); }
104
    | multiplicative_expression '/' cast_expression
105
    { sprintf($<str>$, "%s / %s",$<str>1, $<str>3); }
106
    | multiplicative_expression '%' cast_expression
107
    { sprintf($<str>$, "%s % %s",$<str>1, $<str>3); }
108
    ;
109
110
additive_expression
111
    : multiplicative_expression
112
    | additive_expression '+' multiplicative_expression
113
    { sprintf($<str>$, "%s + %s",$<str>1, $<str>3); }
114
    | additive_expression '-' multiplicative_expression
115
    { sprintf($<str>$, "%s - %s",$<str>1, $<str>3); }
116
    ;
117
118
shift_expression
119
    : additive_expression
120
    | shift_expression LEFT_OP additive_expression
121
    { sprintf($<str>$, "SHL(%s, %s)",$<str>1, $<str>3); }
122
    | shift_expression RIGHT_OP additive_expression
123
    { sprintf($<str>$, "SHR(%s, %s)",$<str>1, $<str>3); }
124
    ;
125
126
relational_expression   : shift_expression
127
    | relational_expression '<' shift_expression
128
    { sprintf($<str>$, "%s < %s",$<str>1, $<str>3); }
129
    | relational_expression '>' shift_expression
130
    { sprintf($<str>$, "%s > %s",$<str>1, $<str>3); }
131
    | relational_expression LE_OP shift_expression
132
    { sprintf($<str>$, "%s <= %s",$<str>1, $<str>3); }
133
    | relational_expression GE_OP shift_expression
134
    { sprintf($<str>$, "%s >= %s",$<str>1, $<str>3); }
135
    ;
136
137
equality_expression
138
    : relational_expression
139
    | equality_expression EQ_OP relational_expression
140
    { sprintf($<str>$, "%s = %s",$<str>1, $<str>3); }
141
    | equality_expression NE_OP relational_expression
142
    { sprintf($<str>$, "%s <> %s",$<str>1, $<str>3); }
143
    ;
144
145
and_expression
146
    : equality_expression
147
    | and_expression '&' equality_expression
148
    { sprintf($<str>$, "%s AND %s",$<str>1, $<str>3); }
149
    ;
150
151
exclusive_or_expression
152
    : and_expression
153
    | exclusive_or_expression '^' and_expression
154
    { sprintf($<str>$, "%s XOR %s",$<str>1, $<str>3); }
155
    ;
156
157
inclusive_or_expression
158
    : exclusive_or_expression
159
    | inclusive_or_expression '|' exclusive_or_expression
160
    { sprintf($<str>$, "%s OR %s",$<str>1, $<str>3); }
161
    ;
162
163
logical_and_expression
164
    : inclusive_or_expression
165
    | logical_and_expression AND_OP inclusive_or_expression
166
    { sprintf($<str>$, "%s AND %s",$<str>1, $<str>3); }
167
    ;
168
169
logical_or_expression
170
    : logical_and_expression
171
    | logical_or_expression OR_OP logical_and_expression
172
    { sprintf($<str>$, "%s OR %s",$<str>1, $<str>3); }
173
    ;
174
175
conditional_expression
176
    : logical_or_expression
177
    | logical_or_expression '?' expression ':' conditional_expression
178
    ;
179
180
assignment_expression
181
    : conditional_expression
182
    | unary_expression assignment_operator assignment_expression
183
    { sprintf($<str>$, "%s %s %s",$<str>1, $<str>2, $<str>3); }
184
    ;
185
186
assignment_operator
187
    : '='
188
    { sprintf($<str>$, ":="); }
189
    | MUL_ASSIGN
190
    | DIV_ASSIGN
191
    | MOD_ASSIGN
192
    | ADD_ASSIGN
193
    | SUB_ASSIGN
194
    | LEFT_ASSIGN
195
    | RIGHT_ASSIGN
196
    | AND_ASSIGN
197
    | XOR_ASSIGN
198
    | OR_ASSIGN
199
    ;
200
201
expression
202
    : assignment_expression
203
    | expression ',' assignment_expression
204
    ;
205
206
constant_expression
207
    : conditional_expression
208
    ;
209
210
declaration
211
    : declaration_specifiers ';'
212
    { sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
213
    | declaration_specifiers init_declarator_list ';'
214
    { char *p; while( (p=pop()) != NULL) { printf(p, $<str>1); strcpy($<str>$, ""); } }
215
    ;
216
217
declaration_specifiers
218
    : storage_class_specifier
219
    | storage_class_specifier declaration_specifiers
220
    { sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
221
    | type_specifier
222
    | type_specifier declaration_specifiers
223
    { sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
224
    | type_qualifier
225
    | type_qualifier declaration_specifiers
226
    { sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
227
    | function_specifier
228
    | function_specifier declaration_specifiers
229
    { sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
230
    ;
231
232
init_declarator_list
233
    : init_declarator
234
    | init_declarator_list ',' init_declarator
235
    { sprintf($<str>$, "%s, %s",$<str>1, $<str>3); }
236
    ;
237
238
init_declarator
239
    : declarator
240
    | declarator '=' initializer
241
    { sprintf($<str>$, "%s = %s",$<str>1, $<str>3); }
242
    ;
243
244
storage_class_specifier
245
    : TYPEDEF
246
    | EXTERN
247
    | STATIC
248
    | AUTO
249
    | REGISTER
250
    ;
251
252
type_specifier
253
    : VOID
254
    | CHAR
255
    | SHORT
256
    | INT
257
    | LONG
258
    | FLOAT
259
    | DOUBLE
260
    | SIGNED
261
    | UNSIGNED
262
    | BOOL
263
    | COMPLEX
264
    | IMAGINARY
265
    | struct_or_union_specifier
266
    | enum_specifier
267
    | TYPE_NAME
268
    ;
269
270
struct_or_union_specifier
271
    : struct_or_union IDENTIFIER '{' struct_declaration_list '}'
272
    | struct_or_union '{' struct_declaration_list '}'
273
    | struct_or_union IDENTIFIER
274
    ;
275
276
struct_or_union
277
    : STRUCT
278
    | UNION
279
    ;
280
281
struct_declaration_list
282
    : struct_declaration
283
    | struct_declaration_list struct_declaration
284
    { sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
285
    ;
286
287
struct_declaration
288
    : specifier_qualifier_list struct_declarator_list ';'
289
    { sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
290
    ;
291
292
specifier_qualifier_list
293
    : type_specifier specifier_qualifier_list
294
    { sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
295
    | type_specifier
296
    | type_qualifier specifier_qualifier_list
297
    { sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
298
    | type_qualifier
299
    ;
300
301
struct_declarator_list
302
    : struct_declarator
303
    | struct_declarator_list ',' struct_declarator
304
    { sprintf($<str>$, "%s, %s",$<str>1, $<str>3); }
305
    ;
306
307
struct_declarator
308
    : declarator
309
    | ':' constant_expression
310
    | declarator ':' constant_expression
311
    ;
312
313
enum_specifier
314
    : ENUM '{' enumerator_list '}'
315
    | ENUM IDENTIFIER '{' enumerator_list '}'
316
    | ENUM '{' enumerator_list ',' '}'
317
    | ENUM IDENTIFIER '{' enumerator_list ',' '}'
318
    | ENUM IDENTIFIER
319
    ;
320
321
enumerator_list
322
    : enumerator
323
    | enumerator_list ',' enumerator
324
    ;
325
326
enumerator
327
    : IDENTIFIER
328
    | IDENTIFIER '=' constant_expression
329
    ;
330
331
type_qualifier
332
    : CONST
333
    | RESTRICT
334
    | VOLATILE
335
    ;
336
337
function_specifier  : INLINE
338
    ;
339
340
declarator
341
    : pointer direct_declarator
342
    { 
343
        sprintf($<str>$, "%s POINTER TO %%s;\n",$<str>2);
344
        push($<str>$);
345
    }
346
    | direct_declarator
347
    {
348
        if (strlen($<str>1) > 0)
349
        {
350
            sprintf($<str>$, "%s %%s;\n",$<str>1);
351
            push($<str>$);
352
        }
353
    }
354
    ;
355
356
direct_declarator
357
    : IDENTIFIER
358
//  { sprintf($<str>$, "%s: %%s;\n",$<str>1); push($<str>$);}
359
    | '(' declarator ')'
360
    | direct_declarator '[' type_qualifier_list assignment_expression ']'
361
    | direct_declarator '[' type_qualifier_list ']'
362
    | direct_declarator '[' assignment_expression ']'
363
    {
364
        sprintf($<str>$, "%s: ARRAY[ %s ] OF %%s;\n",$<str>1, $<str>3);
365
        push($<str>$);
366
        strcpy($<str>$, "");
367
    }
368
    | direct_declarator '[' STATIC type_qualifier_list assignment_expression ']'
369
    | direct_declarator '[' type_qualifier_list STATIC assignment_expression ']'
370
    | direct_declarator '[' type_qualifier_list '*' ']'
371
    | direct_declarator '[' '*' ']'
372
    | direct_declarator '[' ']'
373
    | direct_declarator '(' parameter_type_list ')'
374
    { sprintf($<str>$, "FUNCTION %s:",$<str>1); }
375
    | direct_declarator '(' identifier_list ')'
376
    { sprintf($<str>$, "FUNCTION %s:",$<str>1); }
377
    | direct_declarator '(' ')'
378
    { sprintf($<str>$, "FUNCTION %s:",$<str>1); }
379
    ;
380
381
pointer
382
    : '*'
383
    | '*' type_qualifier_list
384
    | '*' pointer
385
    | '*' type_qualifier_list pointer
386
    ;
387
388
type_qualifier_list
389
    : type_qualifier
390
    | type_qualifier_list type_qualifier
391
    ;
392
393
394
parameter_type_list
395
    : parameter_list
396
    | parameter_list ',' ELLIPSIS
397
    ;
398
399
parameter_list
400
    : parameter_declaration
401
    | parameter_list ',' parameter_declaration
402
    ;
403
404
parameter_declaration
405
    : declaration_specifiers declarator
406
    | declaration_specifiers abstract_declarator
407
    | declaration_specifiers
408
    ;
409
410
identifier_list
411
    : IDENTIFIER
412
    | identifier_list ',' IDENTIFIER
413
    ;
414
415
type_name
416
    : specifier_qualifier_list
417
    | specifier_qualifier_list abstract_declarator
418
    ;
419
420
abstract_declarator
421
    : pointer
422
    | direct_abstract_declarator
423
    | pointer direct_abstract_declarator
424
    ;
425
426
direct_abstract_declarator
427
    : '(' abstract_declarator ')'
428
    | '[' ']'
429
    | '[' assignment_expression ']'
430
    | direct_abstract_declarator '[' ']'
431
    | direct_abstract_declarator '[' assignment_expression ']'
432
    | '[' '*' ']'
433
    | direct_abstract_declarator '[' '*' ']'
434
    | '(' ')'
435
    | '(' parameter_type_list ')'
436
    | direct_abstract_declarator '(' ')'
437
    | direct_abstract_declarator '(' parameter_type_list ')'
438
    ;
439
440
initializer
441
    : assignment_expression
442
    | '{' initializer_list '}'
443
    | '{' initializer_list ',' '}'
444
    ;
445
446
initializer_list
447
    : initializer
448
    | designation initializer
449
    | initializer_list ',' initializer
450
    | initializer_list ',' designation initializer
451
    ;
452
453
designation
454
    : designator_list '='
455
    ;
456
457
designator_list
458
    : designator
459
    | designator_list designator
460
    ;
461
462
designator
463
    : '[' constant_expression ']'
464
    | '.' IDENTIFIER
465
    ;
466
467
statement
468
    : labeled_statement
469
    | compound_statement
470
    | expression_statement
471
    | selection_statement
472
    | iteration_statement
473
    | jump_statement
474
    ;
475
476
labeled_statement
477
    : IDENTIFIER ':' statement
478
    | CASE constant_expression ':' statement
479
    | DEFAULT ':' statement
480
    ;
481
482
compound_statement
483
    : '{' '}'
484
    | '{' block_item_list '}'
485
    ;
486
487
block_item_list
488
    : block_item
489
    | block_item_list block_item
490
    ;
491
492
block_item
493
    : declaration
494
    | statement
495
    { printf("%s\n",$<str>1); }
496
    ;
497
498
expression_statement
499
    : ';'
500
    | expression ';'
501
    { sprintf($<str>$, "%s;",$<str>1); }
502
    ;
503
504
selection_statement
505
    : IF '(' expression ')' statement
506
    | IF '(' expression ')' statement ELSE statement
507
    | SWITCH '(' expression ')' statement
508
    ;
509
510
iteration_statement
511
    : WHILE '(' expression ')' statement
512
    | DO statement WHILE '(' expression ')' ';'
513
    | FOR '(' expression_statement expression_statement ')' statement
514
    | FOR '(' expression_statement expression_statement expression ')' statement
515
    | FOR '(' declaration expression_statement ')' statement
516
    | FOR '(' declaration expression_statement expression ')' statement
517
    ;
518
519
jump_statement
520
    : GOTO IDENTIFIER ';'
521
    | CONTINUE ';'
522
    | BREAK ';'
523
    | RETURN ';'
524
    | RETURN expression ';'
525
    ;
526
527
translation_unit
528
    : external_declaration
529
    | translation_unit external_declaration
530
    ;
531
532
external_declaration
533
    : function_definition
534
    | declaration
535
    ;
536
537
function_definition
538
    : declaration_specifiers declarator declaration_list compound_statement
539
    | declaration_specifiers declarator compound_statement
540
    ;
541
542
declaration_list
543
    : declaration
544
    | declaration_list declaration
545
    { printf("| %s %s\n",$<str>1, $<str>2); }
546
    ;
547
548
549
%%
550
#include <stdio.h>
551
552
extern char yytext[];
553
extern int column;
554
555
void yyerror(char const *s)
556
{
557
    fflush(stdout);
558
    printf("\n%*s\n%*s\n", column, "^", column, s);
559
}
560
561
int main(void)
562
{
563
    yyparse();
564
    return 0;
565
}
566
567
568
/* fifo implementation */
569
void push(const char *psz)
570
{
571
    unsigned int fifow_next = (s_fifow + 1) % FIFO_SIZE; 
572
    if (fifow_next != s_fifor)
573
    {
574
        //s_fifo[s_fifow] = psz;
575
        strcpy(s_fifo[s_fifow], psz);
576
        s_fifow = fifow_next;
577
    }
578
}
579
580
char *pop(void)
581
{
582
    unsigned int fifor_prev;
583
    if (s_fifor != s_fifow)
584
    {
585
        fifor_prev = s_fifor;
586
        s_fifor = (s_fifor + 1) % FIFO_SIZE;
587
        return s_fifo[fifor_prev];
588
    }
589
    return NULL;
590
}
591