Indentation fix, cleanup.
[AROS.git] / tools / cxref / parse.y
blob6e8ac387a73237b863cb171a0486e1d50d602769
1 %{
2 /***************************************
3 $Header$
5 C Cross Referencing & Documentation tool. Version 1.5g.
7 C parser.
8 ******************/ /******************
9 Written by Andrew M. Bishop
11 This file Copyright 1995,96,97,98,99,2000,01,02,03,04 Andrew M. Bishop
12 It may be distributed under the GNU Public License, version 2, or
13 any higher version. See section COPYING of the GNU Public license
14 for conditions under which this file may be redistributed.
15 ***************************************/
17 #include <string.h>
18 #include "parse-yy.h"
19 #include "cxref.h"
20 #include "memory.h"
22 /*+ A structure to hold the information about an object. +*/
23 typedef struct _stack
25 char *name; /*+ The name of the object. +*/
26 char *type; /*+ The type of the object. +*/
27 char *qual; /*+ The type qualifier of the object. +*/
29 stack;
31 #define yylex cxref_yylex
33 static int cxref_yylex(void);
35 static void yyerror(char *s);
37 /*+ When in a header file, some stuff can be skipped over quickly. +*/
38 extern int in_header;
40 /*+ A flag that is set to true when typedef is seen in a statement. +*/
41 int in_typedef=0;
43 /*+ The scope of the function / variable that is being examined. +*/
44 static int scope;
46 /*+ The variable must be LOCAL or EXTERNAL or GLOBAL, so this checks and sets that. +*/
47 #define SCOPE ( scope&(LOCAL|EXTERNAL|EXTERN_H|EXTERN_F) ? scope : scope|GLOBAL )
49 /*+ When in a function or a function definition, the behaviour is different. +*/
50 static int in_function=0,in_funcdef=0,in_funcbody=0;
52 /*+ The parsing stack +*/
53 static stack first={NULL,NULL,NULL}, /*+ first value. +*/
54 *list=NULL, /*+ list of all values. +*/
55 *current=&first; /*+ current values. +*/
57 /*+ The depth of the stack +*/
58 static int depth=0, /*+ currently in use. +*/
59 maxdepth=0; /*+ total malloced. +*/
61 /*+ Declarations that are in the same statement share this comment. +*/
62 static char* common_comment=NULL;
64 /*+ When inside a struct / union / enum definition, this is the depth. +*/
65 static int in_structunion=0;
67 /*+ When inside a struct / union definition, this is the component type. +*/
68 static char *comp_type=NULL;
70 /*+ To solve the problem where a type name is used as an identifier. +*/
71 static int in_type_spec=0;
74 /*++++++++++++++++++++++++++++++++++++++
75 Reset the current level on the stack.
76 ++++++++++++++++++++++++++++++++++++++*/
78 static void reset(void)
80 current->name=NULL;
81 current->type=NULL;
82 current->qual=NULL;
86 /*++++++++++++++++++++++++++++++++++++++
87 Push a level onto the stack.
88 ++++++++++++++++++++++++++++++++++++++*/
90 static void push(void)
92 if(list==NULL)
94 list=(stack*)Malloc(8*sizeof(struct _stack));
95 list[0]=first;
96 maxdepth=8;
98 else if(depth==(maxdepth-1))
100 list=Realloc(list,(maxdepth+8)*sizeof(struct _stack));
101 maxdepth+=8;
104 depth++;
105 current=&list[depth];
107 reset();
111 /*++++++++++++++++++++++++++++++++++++++
112 Pop a level from the stack.
113 ++++++++++++++++++++++++++++++++++++++*/
115 static void pop(void)
117 reset();
119 depth--;
120 current=&list[depth];
124 /*++++++++++++++++++++++++++++++++++++++
125 Reset the Parser, ready for the next file.
126 ++++++++++++++++++++++++++++++++++++++*/
128 void ResetParser(void)
130 in_typedef=0;
131 scope=0;
132 in_function=0;
133 in_funcdef=0;
134 in_funcbody=0;
135 depth=0;
136 maxdepth=0;
137 if(list) Free(list);
138 list=NULL;
139 current=&first;
140 reset();
141 common_comment=NULL;
142 in_structunion=0;
143 comp_type=NULL;
144 in_type_spec=0;
149 /* Expected conflicts: 19 shift/reduce */
151 %token IDENTIFIER TYPE_NAME LITERAL STRING_LITERAL ELLIPSES
152 %token MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
153 %token EQ_OP NE_OP PTR_OP AND_OP OR_OP DEC_OP INC_OP LE_OP GE_OP
154 %token LEFT_SHIFT RIGHT_SHIFT
155 %token SIZEOF
156 %token TYPEDEF EXTERN STATIC AUTO REGISTER CONST VOLATILE VOID INLINE
157 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE
158 %token STRUCT UNION ENUM
159 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
160 %token ASM
162 %start file
166 /*-------------------- Top level --------------------*/
168 file
169 : /* Empty */
170 | program
173 program
174 : top_level_declaration
175 | program top_level_declaration
178 top_level_declaration
179 : declaration
180 { scope=0; reset(); common_comment=NULL; in_typedef=0; GetCurrentComment(); }
181 | function_definition
182 { scope=0; reset(); common_comment=NULL; in_typedef=0; GetCurrentComment(); }
183 | asm_statement /*+ GNU Extension +*/
184 | null_statement
187 /*-------------------- Declarations --------------------*/
189 declaration_list
190 : declaration
191 { scope=0; reset(); common_comment=NULL; in_typedef=0; }
192 | declaration_list declaration
193 { scope=0; reset(); common_comment=NULL; in_typedef=0;
194 $$=$2; }
197 declaration
198 : declaration_specifiers initialized_declarator_list ';'
199 { in_type_spec=0; }
200 | declaration_specifiers ';'
201 { in_type_spec=0; }
204 declaration_specifiers
205 : declaration_specifiers1
206 { if(!in_structunion && !in_typedef && !in_function && !common_comment)
207 {common_comment=CopyString(GetCurrentComment()); SetCurrentComment(common_comment);} }
210 declaration_specifiers1
211 : storage_class_specifier
212 | storage_class_specifier declaration_specifiers1
213 { if($1) $$=ConcatStrings(3,$1," ",$2); else $$=$2; }
214 | type_specifier
215 { if(!current->type) current->type=$1; }
216 | type_specifier declaration_specifiers1
217 { if(!current->type) current->type=$1;
218 $$=ConcatStrings(3,$1," ",$2); }
219 | type_qualifier
220 | type_qualifier declaration_specifiers1
221 { $$=ConcatStrings(3,$1," ",$2); }
224 /* Initialised declarator list */
226 initialized_declarator_list
227 : initialized_declarator
228 | initialized_declarator_list ',' { in_type_spec=1; } initialized_declarator
231 initialized_declarator
232 : initialized_declarator1
234 if((in_function==0 || in_function==3) && !in_funcdef && !in_structunion)
236 char* specific_comment=GetCurrentComment();
237 if(!common_comment) SetCurrentComment(specific_comment); else
238 if(!specific_comment) SetCurrentComment(common_comment); else
239 if(strcmp(common_comment,specific_comment)) SetCurrentComment(ConcatStrings(3,common_comment," ",specific_comment)); else
240 SetCurrentComment(common_comment);
243 if(in_typedef)
245 char* vname=strstr($1,current->name);
246 SeenTypedefName(current->name,vname[strlen(current->name)]=='('?-1:1);
247 if(!in_header)
248 SeenTypedef(current->name,ConcatStrings(3,current->qual,current->type,$1));
249 if(in_function==3)
250 DownScope();
252 else if(in_function==2)
253 SeenFunctionArg(current->name,ConcatStrings(3,current->qual,current->type,$1));
254 else
256 char* vname=strstr($1,current->name);
257 if(vname[strlen(current->name)]!='(' && IsATypeName(current->type)!='f')
259 if((in_funcbody==0 || scope&EXTERN_F) && !in_structunion && !(in_header==GLOBAL && scope&EXTERN_H))
260 SeenVariableDefinition(current->name,ConcatStrings(3,current->qual,current->type,$1),SCOPE);
261 else
262 if(in_funcbody)
263 SeenScopeVariable(current->name);
265 else
267 SeenFunctionProto(current->name,in_funcbody);
268 if(in_function==3)
269 DownScope();
273 if(in_function==3 && !in_structunion) in_function=0;
277 initialized_declarator1
278 : declarator
279 | declarator asm_label /*+ GNU Extension +*/
280 | declarator initializer_part
281 | declarator asm_label initializer_part /* GNU Extension */
284 initializer_part
285 : '=' initializer
288 initializer
289 : assignment_expression
290 | '{' '}'
291 | '{' initializer_list '}'
292 | '{' initializer_list ',' '}'
295 initializer_list
296 : named_initializer
297 | initializer_list ',' named_initializer
300 named_initializer
301 : initializer
302 | component_name ':' initializer
303 | '.' component_name '=' initializer
304 | '[' named_initializer_index ']' initializer
305 | '[' named_initializer_index ']' '=' initializer
308 named_initializer_index
309 : constant_expression
310 | constant_expression ELLIPSES constant_expression
314 /* Abstract declarator */
316 abstract_declarator
317 : pointer
318 | pointer direct_abstract_declarator
319 { $$=ConcatStrings(2,$1,$2); }
320 | direct_abstract_declarator
323 direct_abstract_declarator
324 : '(' abstract_declarator ')'
325 { $$=ConcatStrings(3,$1,$2,$3);
326 { int i=0; while($2[i] && $2[i]=='*') i++; if(!$2[i]) in_type_spec=0; } }
327 | '[' ']'
328 { $$=ConcatStrings(2,$1,$2); }
329 | direct_abstract_declarator '[' ']'
330 { $$=ConcatStrings(3,$1,$2,$3); }
331 | '[' constant_expression ']'
332 { $$=ConcatStrings(3,$1,$2,$3); }
333 | direct_abstract_declarator '[' constant_expression ']'
334 { $$=ConcatStrings(4,$1,$2,$3,$4); }
335 | '(' ')'
336 { $$=ConcatStrings(2,$1,$2); }
337 | direct_abstract_declarator '(' ')'
338 { $$=ConcatStrings(3,$1,$2,$3); }
339 | '(' parameter_type_list ')'
340 { $$=ConcatStrings(3,$1,$2,$3); }
341 | direct_abstract_declarator '(' parameter_type_list ')'
342 { $$=ConcatStrings(4,$1,$2,$3,$4); }
345 /* Declarator */
347 declarator
348 : direct_declarator
349 { in_type_spec=0; }
350 | pointer direct_declarator
351 { in_type_spec=0; $$=ConcatStrings(2,$1,$2); }
354 pointer
355 : '*'
356 | '*' type_qualifier_list
357 { $$=ConcatStrings(3,$1," ",$2); }
358 | '*' pointer
359 { $$=ConcatStrings(2,$1,$2); }
360 | '*' type_qualifier_list pointer
361 { $$=ConcatStrings(4,$1," ",$2,$3); }
364 direct_declarator
365 : simple_declarator
366 | '(' declarator ')'
367 { if($2[0]=='*' && $2[1]==' ') { $2=&$2[1]; $2[0]='*'; }
368 $$=ConcatStrings(4," ",$1,$2,$3);
370 | array_declarator
371 | function_direct_declarator
374 simple_declarator
375 : IDENTIFIER
376 { $$=ConcatStrings(2," ",$1); current->name=$1;
377 if(!current->type) current->type="int";
378 if(in_funcdef==1 && in_function!=3 && !in_structunion) SeenScopeVariable($1); }
381 array_declarator
382 : direct_declarator '[' ']'
383 { $$=ConcatStrings(3,$1,$2,$3); }
384 | direct_declarator '[' { in_type_spec=0; } constant_expression { in_type_spec=1; } ']'
385 { $$=ConcatStrings(4,$1,$2,$4,$6); }
388 /*-------------------- Storage class and types --------------------*/
390 name
391 : IDENTIFIER
394 storage_class_specifier
395 : AUTO
396 { $$=NULL; }
397 | EXTERN
398 { $$=NULL;
399 if(in_funcbody) scope|=EXTERN_F;
400 else if(in_header) scope|=EXTERN_H;
401 else scope|=EXTERNAL; }
402 | REGISTER
403 { $$=NULL; }
404 | STATIC
405 { $$=NULL; scope |= LOCAL; }
406 | TYPEDEF
407 { $$=NULL;
408 in_typedef=1; if(!in_header) SeenTypedef(NULL,NULL);
409 common_comment=CopyString(GetCurrentComment()); }
410 | INLINE /* GNU Extension */
411 { $$=NULL; scope |= INLINED; }
414 type_qualifier_list
415 : type_qualifier
416 | type_qualifier_list type_qualifier
417 { $$=ConcatStrings(3,$1," ",$2); }
420 type_qualifier
421 : CONST
422 { if(!current->type) current->qual=ConcatStrings(3,current->qual,$1," "); }
423 | VOLATILE
424 { if(!current->type) current->qual=ConcatStrings(3,current->qual,$1," "); }
427 /* Types */
429 type_specifier
430 : type_specifier1
431 { in_type_spec=1; }
434 type_specifier1
435 : enumeration_type_specifier
436 | floating_type_specifier
437 | integer_type_specifier
438 | structure_type_specifier
439 | typedef_name
440 | union_type_specifier
441 | void_type_specifier
444 floating_type_specifier
445 : FLOAT
446 | DOUBLE
447 | DOUBLE LONG
448 { $$=ConcatStrings(3,$1," ",$2); }
449 | LONG DOUBLE
450 { $$=ConcatStrings(3,$1," ",$2); }
453 integer_type_specifier
454 : integer_type_specifier_part
455 | integer_type_specifier_part type_qualifier
456 { $$=ConcatStrings(3,$1," ",$2); }
457 | integer_type_specifier integer_type_specifier_part
458 { $$=ConcatStrings(3,$1," ",$2); }
461 integer_type_specifier_part
462 : SIGNED
463 | UNSIGNED
464 | CHAR
465 | SHORT
466 | INT
467 | LONG
470 typedef_name
471 : TYPE_NAME
474 void_type_specifier
475 : VOID
478 type_name
479 : declaration_specifiers
480 { in_type_spec=0; }
481 | declaration_specifiers abstract_declarator
482 { in_type_spec=0; $$=ConcatStrings(2,$1,$2); }
485 /* Enumerated types */
487 enumeration_type_specifier
488 : enumeration_type_definition
489 | enumeration_type_reference
492 enumeration_type_definition
493 : ENUM '{'
494 { push();
495 if(!in_header)
497 if(in_structunion) SeenStructUnionComp($1,in_structunion);
498 else SeenStructUnionStart($1);
500 in_structunion++; }
501 enumeration_definition_list '}'
502 { pop(); in_structunion--;
503 if(!in_structunion && !current->type) current->type=ConcatStrings(2,$1," {...}");
504 if(!in_header && !in_structunion && in_typedef) SeenStructUnionEnd();
505 $$=ConcatStrings(5,$1," ",$2,$4,$5); }
506 | ENUM enumeration_tag '{'
507 { push();
508 if(!in_header)
510 if(in_structunion) SeenStructUnionComp(ConcatStrings(3,$1," ",$2),in_structunion);
511 else SeenStructUnionStart(ConcatStrings(3,$1," ",$2));
513 in_structunion++; }
514 enumeration_definition_list '}'
515 { pop(); in_structunion--;
516 if(!in_structunion && !current->type) current->type=ConcatStrings(3,$1," ",$2);
517 if(!in_header && !in_structunion) SeenStructUnionEnd();
518 $$=ConcatStrings(7,$1," ",$2," ",$3,$5,$6);}
521 enumeration_definition_list
522 : enumeration_definition_list1
523 | enumeration_definition_list1 ',' /* Not ANSI, but common */
526 enumeration_definition_list1
527 : enumeration_constant_definition
528 | enumeration_definition_list1 ',' enumeration_constant_definition
529 { $$=ConcatStrings(3,$1,$2,$3); }
532 enumeration_constant_definition
533 : enumeration_constant
534 { if(!in_header) SeenStructUnionComp($1,in_structunion); }
535 | enumeration_constant '=' assignment_expression /* Should be constant expression */
536 { $$=ConcatStrings(3,$1,$2,$3); if(!in_header) SeenStructUnionComp($1,in_structunion); }
539 enumeration_constant
540 : IDENTIFIER
543 enumeration_type_reference
544 : ENUM enumeration_tag
545 { $$=ConcatStrings(3,$1," ",$2); }
548 enumeration_tag
549 : IDENTIFIER
550 | TYPE_NAME
553 /* Structures */
555 structure_type_specifier
556 : structure_type_definition
557 | structure_type_reference
560 structure_type_definition
561 : STRUCT '{'
562 { push();
563 if(!in_header)
565 if(in_structunion) SeenStructUnionComp($1,in_structunion);
566 else SeenStructUnionStart($1);
568 in_structunion++; }
569 field_list '}'
570 { pop(); in_structunion--;
571 if(!in_structunion && !current->type) current->type=ConcatStrings(2,$1," {...}");
572 if(!in_header && !in_structunion && in_typedef) SeenStructUnionEnd();
573 $$=ConcatStrings(5,$1," ",$2,$4,$5); }
574 | STRUCT structure_tag '{'
575 { push();
576 if(!in_header)
578 if(in_structunion) SeenStructUnionComp(ConcatStrings(3,$1," ",$2),in_structunion);
579 else SeenStructUnionStart(ConcatStrings(3,$1," ",$2));
581 in_structunion++; }
582 field_list '}'
583 { pop(); in_structunion--;
584 if(!in_structunion && !current->type) current->type=ConcatStrings(3,$1," ",$2);
585 if(!in_header && !in_structunion) SeenStructUnionEnd();
586 $$=ConcatStrings(7,$1," ",$2," ",$3,$5,$6);}
589 structure_type_reference
590 : STRUCT structure_tag
591 { $$=ConcatStrings(3,$1," ",$2); }
594 structure_tag
595 : IDENTIFIER
596 | TYPE_NAME
599 /* Unions */
601 union_type_specifier
602 : union_type_definition
603 | union_type_reference
606 union_type_definition
607 : UNION '{'
608 { push();
609 if(!in_header)
611 if(in_structunion) SeenStructUnionComp($1,in_structunion);
612 else SeenStructUnionStart($1);
614 in_structunion++; }
615 field_list '}'
616 { pop(); in_structunion--;
617 if(!in_structunion && !current->type) current->type=ConcatStrings(2,$1," {...}");
618 if(!in_header && !in_structunion && in_typedef) SeenStructUnionEnd();
619 $$=ConcatStrings(5,$1," ",$2,$4,$5); }
620 | UNION union_tag '{'
621 { push();
622 if(!in_header)
624 if(in_structunion) SeenStructUnionComp(ConcatStrings(3,$1," ",$2),in_structunion);
625 else SeenStructUnionStart(ConcatStrings(3,$1," ",$2));
627 in_structunion++; }
628 field_list '}'
629 { pop(); in_structunion--;
630 if(!in_structunion && !current->type) current->type=ConcatStrings(3,$1," ",$2);
631 if(!in_header && !in_structunion) SeenStructUnionEnd();
632 $$=ConcatStrings(7,$1," ",$2," ",$3,$5,$6);}
635 union_type_reference
636 : UNION union_tag
637 { $$=ConcatStrings(3,$1," ",$2); }
640 union_tag
641 : IDENTIFIER
642 | TYPE_NAME
645 /* Struct or Union */
647 field_list
648 : /* empty */
649 | field_list1
652 field_list1
653 : field_list2
654 | field_list1 field_list2
655 { $$=ConcatStrings(2,$1,$2); }
658 field_list2
659 : ';'
660 | structure_type_definition ';'
661 { $$ = ConcatStrings(3, $1, " ", $2);
662 if(!in_header) SeenStructUnionComp($1,in_structunion); }
663 | union_type_definition ';'
664 { $$ = ConcatStrings(3, $1, " ", $2);
665 if(!in_header) SeenStructUnionComp($1,in_structunion); }
666 | component_declaration
669 component_declaration
670 : type_specifier
671 { comp_type=$1; }
672 component_declarator_list ';'
673 { $$=ConcatStrings(3,$1,$3,$4); reset(); in_type_spec=0; }
674 | type_qualifier_list type_specifier
675 { comp_type=ConcatStrings(3,$1," ",$2); }
676 component_declarator_list ';'
677 { $$=ConcatStrings(4,$1,$2,$4,$5); reset(); in_type_spec=0; }
678 | type_specifier type_qualifier_list
679 { comp_type=ConcatStrings(3,$1," ",$2); }
680 component_declarator_list ';'
681 { $$=ConcatStrings(4,$1,$2,$4,$5); reset(); in_type_spec=0; }
684 component_declarator_list
685 : component_declarator
686 { if(!in_header) SeenStructUnionComp(ConcatStrings(2,comp_type,$1),in_structunion); }
687 | component_declarator_list ',' component_declarator
688 { $$=ConcatStrings(3,$1,$2,$3);
689 if(!in_header) SeenStructUnionComp(ConcatStrings(2,comp_type,$3),in_structunion); }
692 component_declarator
693 : simple_component
694 | bit_field
697 simple_component
698 : declarator
699 { if(in_function==2 && !in_structunion) { DownScope(); pop(); in_function=0; } }
702 bit_field
703 : ':' width
704 { $$=ConcatStrings(2,$1,$2); }
705 | declarator ':' width
706 { $$=ConcatStrings(3,$1,$2,$3); }
709 width
710 : assignment_expression /* Should be expression */
713 component_name
714 : IDENTIFIER
715 | TYPE_NAME
718 /*-------------------- Functions --------------------*/
720 /* Function Definition */
722 function_definition
723 : function_specifier
724 { pop(); in_funcbody=1; in_function=0; }
725 compound_statement
726 { in_funcbody=in_function=0; DownScope(); SeenFunctionDefinition(NULL); }
729 function_specifier
730 : function_specifier1
731 { char *func_type,*fname=strstr($1,(current-1)->name),*parenth=strstr($1,"(");
732 if(parenth>fname)
733 {parenth[0]=0;func_type=ConcatStrings(3,(current-1)->qual,(current-1)->type,$1);}
734 else
736 int open=1;
737 char *argbeg=strstr(&parenth[1],"("),*argend;
738 argbeg[1]=0;
739 for(argend=argbeg+2;*argend;argend++)
741 if(*argend=='(') open++;
742 if(*argend==')') open--;
743 if(!open) break;
745 func_type=ConcatStrings(4,(current-1)->qual,(current-1)->type,$1,argend);
747 SeenFunctionDefinition(func_type);
751 function_specifier1
752 : function_declarator
753 | declaration_specifiers function_declarator
754 { $$=ConcatStrings(3,current->qual,current->type,$2); }
755 | function_declarator declaration_list
756 | declaration_specifiers function_declarator declaration_list
757 { $$=ConcatStrings(3,current->qual,current->type,$2); }
760 /* Function Declaration */
762 function_declarator
763 : function_declarator0
764 { if(!in_structunion) { push(); in_function=2; } }
767 function_declarator0
768 : function_direct_declarator
769 | '(' function_direct_declarator ')'
770 | pointer function_direct_declarator
771 { $$=ConcatStrings(2,$1,$2); }
772 | pointer '(' function_direct_declarator ')'
773 { $$=ConcatStrings(2,$1,$3); }
776 function_direct_declarator
777 : function_declarator1 '('
778 { if(!in_structunion)
779 { push(); if(in_function==0) UpScope();
780 if(in_function==0 && !in_funcdef) in_function=1; if(in_function!=3) in_funcdef++; } }
781 function_declarator2 ')'
782 { if(!in_structunion)
783 { pop(); if(in_function!=3) in_funcdef--; if(in_funcdef==0) in_function=3; }
784 $$=ConcatStrings(4,$1,$2,$4,$5); }
787 function_declarator1
788 : direct_declarator
790 if(!in_funcdef && !in_function && !in_funcbody && !in_structunion) SeenFunctionDeclaration(current->name,SCOPE);
791 in_type_spec=0;
795 function_declarator2
796 : /* Empty */
797 { if(in_function==1 && in_funcdef==1 && !in_structunion) SeenFunctionArg("void","void");
798 if(in_structunion) $$=NULL; else $$="void"; }
799 | parameter_type_list
800 | identifier_list
803 identifier_list
804 : IDENTIFIER
805 { if(in_function==1 && in_funcdef==1 && in_funcbody==0 && !in_structunion) { SeenFunctionArg($1,NULL); SeenScopeVariable($1); } }
806 | identifier_list ',' IDENTIFIER
807 { if(in_function==1 && in_funcdef==1 && in_funcbody==0 && !in_structunion) { SeenFunctionArg($3,NULL); SeenScopeVariable($3); }
808 $$=ConcatStrings(3,$1,$2,$3); }
811 parameter_type_list
812 : parameter_list
813 | parameter_list ',' ELLIPSES
814 { if(in_function==1 && in_funcdef==1 && in_funcbody==0 && !in_structunion) SeenFunctionArg($3,$3);
815 $$=ConcatStrings(3,$1,$2,$3); }
818 parameter_list
819 : parameter_declaration
820 { if(in_function==1 && in_funcdef==1 && in_funcbody==0 && !in_structunion) SeenFunctionArg(strcmp("void",$1)?current->name:"void",$1);
821 in_type_spec=0; }
822 | parameter_list ',' parameter_declaration
823 { if(in_function==1 && in_funcdef==1 && in_funcbody==0 && !in_structunion) SeenFunctionArg(current->name,$3);
824 in_type_spec=0; $$=ConcatStrings(3,$1,$2,$3); }
827 parameter_declaration
828 : declaration_specifiers declarator
829 { in_type_spec=0; $$=ConcatStrings(2,$1,$2); }
830 | declaration_specifiers
831 { in_type_spec=0; }
832 | declaration_specifiers abstract_declarator
833 { in_type_spec=0; $$=ConcatStrings(2,$1,$2); }
836 /*-------------------- Statements --------------------*/
838 statement
839 : asm_statement /*+ GNU Extension +*/
840 | compound_statement
841 | conditional_statement
842 | iterative_statement
843 | labeled_statement
844 | switch_statement
845 | break_statement
846 | continue_statement
847 | expression_statement
848 | goto_statement
849 | null_statement
850 | return_statement
853 /* Compound statement */
855 compound_statement
856 : '{'
857 { UpScope(); reset(); }
858 compound_statement_body
859 { DownScope(); }
863 compound_statement_body
864 : /* Empty */
865 | block_item_list
868 block_item_list
869 : block_item
870 | block_item_list block_item
873 block_item
874 : statement
875 | declaration
876 { scope=0; reset(); common_comment=NULL; in_typedef=0; }
879 /* Conditional statements */
881 conditional_statement
882 : if_statement
883 | if_else_statement
886 if_else_statement
887 : IF '(' expression ')' statement ELSE statement
890 if_statement
891 : IF '(' expression ')' statement
894 /* Iterative statements */
896 iterative_statement
897 : do_statement
898 | for_statement
899 | while_statement
902 do_statement
903 : DO statement WHILE '(' expression ')' ';'
906 for_statement
907 : FOR '(' for_expressions ')' statement
910 for_expressions
911 : ';' ';'
912 | expression ';' ';'
913 | ';' expression ';'
914 | ';' ';' expression
915 | ';' expression ';' expression
916 | expression ';' ';' expression
917 | expression ';' expression ';'
918 | expression ';' expression ';' expression
921 while_statement
922 : WHILE '(' expression ')' statement
925 /* Label Statements */
927 labeled_statement /* Allows for no statement following a label. */
928 : case_label ':'
929 | named_label ':'
930 | default_label ':'
933 case_label
934 : CASE constant_expression
935 | CASE constant_expression ELLIPSES constant_expression
938 default_label
939 : DEFAULT
942 named_label
943 : IDENTIFIER
946 /* Switch statement */
948 switch_statement
949 : SWITCH '(' expression ')' statement
952 /* Other Statements */
954 break_statement
955 : BREAK ';'
958 continue_statement
959 : CONTINUE ';'
962 expression_statement
963 : expression ';'
966 goto_statement
967 : GOTO IDENTIFIER ';'
970 null_statement
971 : ';'
974 return_statement
975 : RETURN ';'
976 | RETURN expression ';'
979 /*-------------------- Expressions --------------------*/
981 expression
982 : comma_expression
985 /* Precedence 1 */
987 comma_expression
988 : assignment_expression
989 | comma_expression ',' assignment_expression
990 { $$=ConcatStrings(3,$1,$2,$3); }
993 /* Precedence 2 */
995 assignment_expression
996 : conditional_expression
997 | named_label_address
998 | unary_expression assignment_op assignment_expression
999 | unary_expression assignment_op '{' assignment_expression_list '}'
1001 assignment_op
1002 : '='
1003 | MUL_ASSIGN
1004 | DIV_ASSIGN
1005 | MOD_ASSIGN
1006 | ADD_ASSIGN
1007 | SUB_ASSIGN
1008 | LEFT_ASSIGN
1009 | RIGHT_ASSIGN
1010 | AND_ASSIGN
1011 | XOR_ASSIGN
1012 | OR_ASSIGN
1015 /* Precedence 3 */
1017 conditional_expression
1018 : logical_or_expression
1019 | logical_or_expression '?' expression ':' conditional_expression
1020 { $$=ConcatStrings(5,$1,$2,$3,$4,$5); }
1021 | logical_or_expression '?' ':' conditional_expression /* GNU Extension */
1022 { $$=ConcatStrings(4,$1,$2,$3,$4); }
1025 /* Precedence 4 */
1027 logical_or_expression
1028 : logical_and_expression
1029 | logical_or_expression OR_OP logical_and_expression
1030 { $$=ConcatStrings(3,$1,$2,$3); }
1033 /* Precedence 5 */
1035 logical_and_expression
1036 : bitwise_or_expression
1037 | logical_and_expression AND_OP bitwise_or_expression
1038 { $$=ConcatStrings(3,$1,$2,$3); }
1041 /* Precedence 6 */
1043 bitwise_or_expression
1044 : bitwise_xor_expression
1045 | bitwise_or_expression '|' bitwise_xor_expression
1046 { $$=ConcatStrings(3,$1,$2,$3); }
1049 /* Precedence 7 */
1051 bitwise_xor_expression
1052 : bitwise_and_expression
1053 | bitwise_xor_expression '^' bitwise_and_expression
1054 { $$=ConcatStrings(3,$1,$2,$3); }
1057 /* Precedence 8 */
1059 bitwise_and_expression
1060 : equality_expression
1061 | bitwise_and_expression '&' equality_expression
1062 { $$=ConcatStrings(3,$1,$2,$3); }
1065 /* Precedence 9 */
1067 equality_expression
1068 : relational_expression
1069 | equality_expression equality_op relational_expression
1070 { $$=ConcatStrings(3,$1,$2,$3); }
1072 equality_op
1073 : EQ_OP
1074 | NE_OP
1077 /* Precedence 10 */
1079 relational_expression
1080 : shift_expression
1081 | relational_expression relational_op shift_expression
1082 { $$=ConcatStrings(3,$1,$2,$3); }
1084 relational_op
1085 : '<'
1086 | LE_OP
1087 | '>'
1088 | GE_OP
1091 /* Precedence 11 */
1093 shift_expression
1094 : additive_expression
1095 | shift_expression shift_op additive_expression
1096 { $$=ConcatStrings(3,$1,$2,$3); }
1098 shift_op
1099 : LEFT_SHIFT
1100 | RIGHT_SHIFT
1103 /* Precedence 12 */
1105 additive_expression
1106 : multiplicative_expression
1107 | additive_expression add_op multiplicative_expression
1108 { $$=ConcatStrings(3,$1,$2,$3); }
1110 add_op
1111 : '+'
1112 | '-'
1115 /* Precedence 13 */
1117 multiplicative_expression
1118 : unary_expression
1119 | multiplicative_expression mult_op unary_expression
1120 { $$=ConcatStrings(3,$1,$2,$3); }
1122 mult_op
1123 : '*'
1124 | '/'
1125 | '%'
1128 /* Precedence 14 */
1130 unary_expression
1131 : address_expression
1132 | bitwise_negation_expression
1133 | cast_expression
1134 | indirection_expression
1135 | logical_negation_expression
1136 | predecrement_expression
1137 | preincrement_expression
1138 | sizeof_expression
1139 | unary_minus_expression
1140 | unary_plus_expression
1141 | postfix_expression
1144 address_expression
1145 : '&' unary_expression
1148 bitwise_negation_expression
1149 : '~' unary_expression
1150 { $$=ConcatStrings(2,$1,$2); }
1153 cast_expression
1154 : '(' type_name ')' unary_expression
1155 { $$=ConcatStrings(4,$1,$2,$3,$4); }
1156 | '(' type_name ')' '{' assignment_expression_list '}' /* GNU Extension */
1157 | '(' type_name ')' '{' named_assignment_list '}' /* GNU Extension */
1160 indirection_expression
1161 : '*' unary_expression
1164 logical_negation_expression
1165 : '!' unary_expression
1166 { $$=ConcatStrings(2,$1,$2); }
1169 predecrement_expression
1170 : DEC_OP unary_expression
1173 preincrement_expression
1174 : INC_OP unary_expression
1177 sizeof_expression
1178 : SIZEOF '(' type_name ')'
1179 { $$=ConcatStrings(4,$1,$2,$3,$4); }
1180 | SIZEOF unary_expression
1181 { $$=ConcatStrings(2,$1,$2); }
1184 unary_minus_expression
1185 : '-' unary_expression
1186 { $$=ConcatStrings(2,$1,$2); }
1189 unary_plus_expression
1190 : '+' unary_expression
1191 { $$=ConcatStrings(2,$1,$2); }
1194 /* Precedence 15 */
1196 postfix_expression
1197 : component_selection_expression
1198 | function_call
1199 | function_call_direct
1200 { if(!IsAScopeVariable($1)) SeenFunctionCall($1); }
1201 | postdecrement_expression
1202 | postincrement_expression
1203 | subscript_expression
1204 | primary_expression
1207 component_selection_expression
1208 : direct_component_selection
1209 | indirect_component_selection
1212 direct_component_selection
1213 : postfix_expression '.' component_name
1216 indirect_component_selection
1217 : postfix_expression PTR_OP component_name
1220 function_call
1221 : postfix_expression '(' ')'
1222 | postfix_expression '(' expression_list ')'
1225 function_call_direct
1226 : name '(' ')'
1227 | name '(' expression_list ')'
1230 postdecrement_expression
1231 : postfix_expression DEC_OP
1234 postincrement_expression
1235 : postfix_expression INC_OP
1238 subscript_expression
1239 : postfix_expression '[' expression ']'
1242 primary_expression
1243 : name
1244 { CheckFunctionVariableRef($1,in_funcbody); }
1245 | LITERAL
1246 | string_literal
1247 | parenthesized_expression
1249 string_literal
1250 : STRING_LITERAL
1251 | string_literal STRING_LITERAL
1254 parenthesized_expression
1255 : '(' expression ')'
1256 { $$=ConcatStrings(3,$1,$2,$3); }
1257 | '(' { push(); } compound_statement { pop(); } ')' /* GNU Extension */
1260 /* Other expressions */
1262 constant_expression
1263 : expression
1266 expression_list
1267 : assignment_expression
1268 | expression_list ',' assignment_expression
1271 /*-------------------- GNU Extensions --------------------*/
1273 /* ASM Statements */
1275 asm_statement
1276 : asm_type '(' string_literal ')' ';'
1277 | asm_type '(' string_literal ':' asm_inout_list ')' ';'
1278 | asm_type '(' string_literal ':' asm_inout_list ':' asm_inout_list ')' ';'
1279 | asm_type '(' string_literal ':' asm_inout_list ':' asm_inout_list ':' asm_clobber_list ')' ';'
1282 asm_type
1283 : ASM
1284 | ASM VOLATILE
1285 | VOLATILE ASM
1288 asm_inout_list
1289 : /* Empty */
1290 | asm_inout
1291 | asm_inout_list ',' asm_inout
1294 asm_inout
1295 : string_literal '(' expression ')'
1298 asm_clobber_list
1299 : /* Empty */
1300 | string_literal
1301 | asm_clobber_list ',' string_literal
1304 asm_label
1305 : ASM '(' string_literal ')'
1308 /* Named label address */
1310 named_label_address
1311 : AND_OP named_label
1314 /* Assignment of structure / union */
1316 assignment_expression_list
1317 : assignment_expression_list_item
1318 | assignment_expression_list ',' assignment_expression_list_item
1321 assignment_expression_list_item
1322 : /* Empty */
1323 | assignment_expression
1324 | '{' assignment_expression_list '}'
1327 named_assignment
1328 : component_name ':' assignment_expression
1329 | component_name ':' '{' assignment_expression_list '}'
1330 | '.' component_name '=' assignment_expression
1331 | '.' component_name '=' '{' assignment_expression_list '}'
1334 named_assignment_list
1335 : named_assignment
1336 | named_assignment_list ',' named_assignment
1341 #if YYDEBUG
1343 static int last_yylex[11];
1344 static char *last_yylval[11];
1345 static int count=0,modcount=0;
1347 #endif /* YYDEBUG */
1350 /*++++++++++++++++++++++++++++++++++++++
1351 Stop parsing the current file, due to an error.
1353 char *s The error message to print out.
1354 ++++++++++++++++++++++++++++++++++++++*/
1356 static void yyerror( char *s )
1358 #if YYDEBUG
1359 int i;
1360 #endif
1362 fflush(stdout);
1363 fprintf(stderr,"%s:%d: cxref: %s\n\n",parse_file,parse_line,s);
1365 #if YYDEBUG
1367 fprintf(stderr,"The previous 10, current and next 10 symbols are:\n");
1369 for(i=count>10?count-11:0,modcount=i%11;i<count-1;i++,modcount=i%11)
1370 #ifdef YYBISON
1371 fprintf(stderr,"%3d | %3d : %16s : %s\n",i+1-count,last_yylex[modcount],yytname[YYTRANSLATE(last_yylex[modcount])],last_yylval[modcount]);
1372 #else
1373 fprintf(stderr,"%3d | %3d : %s\n",i+1-count,last_yylex[modcount],last_yylval[modcount]);
1374 #endif
1376 #ifdef YYBISON
1377 fprintf(stderr," 0 | %3d : %16s : %s\n",yychar,yytname[YYTRANSLATE(yychar)],yylval);
1378 #else
1379 fprintf(stderr," 0 | %3d : %s\n",yychar,yylval);
1380 #endif
1382 for(i=0;i<10;i++)
1384 yychar=yylex();
1385 if(!yychar)
1386 {fprintf(stderr,"END OF FILE\n");break;}
1387 #ifdef YYBISON
1388 fprintf(stderr,"%3d | %3d : %16s : %s\n",i+1,yychar,yytname[YYTRANSLATE(yychar)],yylval);
1389 #else
1390 fprintf(stderr,"%3d | %3d : %s\n",i+1,yychar,yylval);
1391 #endif
1394 fprintf(stderr,"\n");
1396 #endif /* YYDEBUG */
1398 /* Finish off the input. */
1400 #undef yylex
1402 if(yychar)
1403 while((yychar=yylex()));
1407 /*++++++++++++++++++++++++++++++++++++++
1408 Call the lexer, the feedback from the parser to the lexer is applied here.
1410 int cxref_yylex Returns the value from the lexer, modified due to parser feedback.
1411 ++++++++++++++++++++++++++++++++++++++*/
1413 static int cxref_yylex(void)
1415 static int last_yyl=0;
1416 int yyl=yylex();
1418 if(yyl==TYPE_NAME)
1419 if(in_type_spec || (in_structunion && last_yyl=='}') || last_yyl==TYPE_NAME ||
1420 last_yyl==CHAR || last_yyl==SHORT || last_yyl==INT || last_yyl==LONG ||
1421 last_yyl==SIGNED || last_yyl==UNSIGNED ||
1422 last_yyl==FLOAT || last_yyl==DOUBLE)
1423 yyl=IDENTIFIER;
1425 last_yyl=yyl;
1427 #if YYDEBUG
1429 last_yylex [modcount]=yyl;
1430 last_yylval[modcount]=yylval;
1432 if(yyl)
1434 count++;
1435 modcount=count%11;
1437 else
1439 count=0;
1440 modcount=0;
1443 #if YYDEBUG == 2
1445 if(yyl)
1446 #ifdef YYBISON
1447 printf("#parse.y# %6d | %16s:%4d | %3d : %16s : %s\n",count,parse_file,parse_line,yyl,yytname[YYTRANSLATE(yyl)],yylval);
1448 #else
1449 printf("#parse.y# %6d | %16s:%4d | %3d : %s\n",count,parse_file,parse_line,yyl,yylval);
1450 #endif /* YYBISON */
1451 else
1452 printf("#parse.y# %6d | %16s:%4d | END OF FILE\n",count,parse_file,parse_line);
1454 fflush(stdout);
1456 #endif /* YYDEBUG==2 */
1458 #endif /* YYDEBUG */
1460 return(yyl);