1 /*-----------------------------------------------------------------------
3 SDCC.y - parser definition file for sdcc :
4 Written By : Sandeep Dutta . sandeep.dutta@usa.net (1997)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
28 #include "SDCCglobl.h"
30 #include "SDCChasht.h"
38 extern int yyerror (char *);
40 int NestLevel = 0 ; /* current NestLevel */
41 int stackPtr = 1 ; /* stack pointer */
42 int xstackPtr = 0 ; /* xstack pointer */
44 int blockNo = 0 ; /* sequential block number */
49 char lbuff[1024]; /* local buffer */
51 /* break & continue stacks */
52 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
53 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
54 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
55 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
56 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
58 value *cenum = NULL ; /* current enumeration type chain*/
64 symbol *sym ; /* symbol table pointer */
65 structdef *sdef; /* structure definition */
66 char yychar[SDCC_NAME_MAX+1];
67 sym_link *lnk ; /* declarator or specifier */
68 int yyint; /* integer value returned */
69 value *val ; /* for integer constant */
70 initList *ilist; /* initial list */
71 char *yyinline; /* inlined assembler code */
72 ast *asts; /* expression tree */
75 %token <yychar> IDENTIFIER TYPE_NAME
76 %token <val> CONSTANT STRING_LITERAL
78 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
80 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
81 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
82 %token <yyint> XOR_ASSIGN OR_ASSIGN
83 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
84 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
85 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
86 %token STRUCT UNION ENUM ELIPSIS RANGE FAR
87 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
89 %token <yyinline> INLINEASM
90 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
91 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
93 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
95 %type <yyint> Interrupt_storage
96 %type <sym> identifier declarator declarator2 enumerator_list enumerator
97 %type <sym> struct_declarator
98 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
99 %type <sym> declaration init_declarator_list init_declarator
100 %type <sym> declaration_list identifier_list parameter_identifier_list
101 %type <sym> declarator2_function_attributes while do for
102 %type <lnk> pointer type_specifier_list type_specifier type_name
103 %type <lnk> storage_class_specifier struct_or_union_specifier
104 %type <lnk> declaration_specifiers sfr_reg_bit type_specifier2
105 %type <lnk> function_attribute function_attributes enum_specifier
106 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
107 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
108 %type <sdef> stag opt_stag
109 %type <asts> primary_expr
110 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
111 %type <asts> additive_expr shift_expr relational_expr equality_expr
112 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
113 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
114 %type <asts> expr argument_expr_list function_definition expr_opt
115 %type <asts> statement_list statement labeled_statement compound_statement
116 %type <asts> expression_statement selection_statement iteration_statement
117 %type <asts> jump_statement function_body else_statement string_literal
118 %type <ilist> initializer initializer_list
119 %type <yyint> unary_operator assignment_operator struct_or_union
126 : external_definition
127 | file external_definition
131 : function_definition {
136 && IS_FUNC($1->type))
138 /* The only legal storage classes for
139 * a function prototype (declaration)
140 * are extern and static. extern is the
141 * default. Thus, if this function isn't
142 * explicitly marked static, mark it
146 && IS_SPEC($1->etype)
147 && !SPEC_STAT($1->etype))
149 SPEC_EXTR($1->etype) = 1;
153 allocVariables ($1) ;
154 cleanUpLevel (SymbolTab,1);
159 : declarator function_body { /* function type not specified */
160 /* assume it to be 'int' */
161 addDecl($1,0,newIntLink());
162 $$ = createFunction($1,$2);
164 | declaration_specifiers declarator function_body
166 pointerTypes($2->type,copyLinkChain($1));
168 $$ = createFunction($2,$3);
173 : function_attributes
174 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
180 $$->class = SPECIFIER ;
181 FUNC_REGBANK($$) = (int) floatFromVal($2);
183 | REENTRANT { $$ = newLink ();
184 $$->class = SPECIFIER ;
187 | CRITICAL { $$ = newLink ();
188 $$->class = SPECIFIER ;
189 FUNC_ISCRITICAL($$) = 1;
191 | NAKED { $$ = newLink ();
192 $$->class = SPECIFIER ;
195 | NONBANKED {$$ = newLink ();
196 $$->class = SPECIFIER ;
197 FUNC_NONBANKED($$) = 1;
198 if (FUNC_BANKED($$)) {
199 werror(W_BANKED_WITH_NONBANKED);
202 | BANKED {$$ = newLink ();
203 $$->class = SPECIFIER ;
205 if (FUNC_NONBANKED($$)) {
206 werror(W_BANKED_WITH_NONBANKED);
209 werror(W_BANKED_WITH_STATIC);
215 $$->class = SPECIFIER ;
216 FUNC_INTNO($$) = $1 ;
223 | declaration_list compound_statement
225 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
231 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
232 | CONSTANT { $$ = newAst_VALUE($1); }
234 | '(' expr ')' { $$ = $2 ; }
238 : STRING_LITERAL { $$ = newAst_VALUE($1); }
243 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
244 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
245 $$->left->funcName = 1;}
246 | postfix_expr '(' argument_expr_list ')'
248 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
250 | postfix_expr '.' identifier
252 $3 = newSymbol($3->name,NestLevel);
254 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
255 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
257 | postfix_expr PTR_OP identifier
259 $3 = newSymbol($3->name,NestLevel);
261 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
263 | postfix_expr INC_OP
264 { $$ = newNode(INC_OP,$1,NULL);}
265 | postfix_expr DEC_OP
266 { $$ = newNode(DEC_OP,$1,NULL); }
271 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
276 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
277 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
278 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
279 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
280 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
281 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
295 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
300 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
301 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
302 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
306 : multiplicative_expr
307 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
308 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
313 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
314 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
319 | relational_expr '<' shift_expr {
321 newNode('!',newNode(GE_OP,$1,$3),NULL) :
322 newNode('<', $1,$3));
324 | relational_expr '>' shift_expr {
326 newNode('!',newNode(LE_OP,$1,$3),NULL) :
329 | relational_expr LE_OP shift_expr {
331 newNode('!', newNode('>', $1 , $3 ), NULL) :
332 newNode(LE_OP,$1,$3));
334 | relational_expr GE_OP shift_expr {
336 newNode('!', newNode('<', $1 , $3 ), NULL) :
337 newNode(GE_OP,$1,$3));
343 | equality_expr EQ_OP relational_expr {
345 newNode('!',newNode(NE_OP,$1,$3),NULL) :
346 newNode(EQ_OP,$1,$3));
348 | equality_expr NE_OP relational_expr {
350 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
351 newNode(NE_OP,$1,$3));
357 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
362 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
367 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
372 | logical_and_expr AND_OP inclusive_or_expr
373 { $$ = newNode(AND_OP,$1,$3);}
378 | logical_or_expr OR_OP logical_and_expr
379 { $$ = newNode(OR_OP,$1,$3); }
384 | logical_or_expr '?' logical_or_expr ':' conditional_expr
386 $$ = newNode(':',$3,$5) ;
387 $$ = newNode('?',$1,$$) ;
393 | unary_expr assignment_operator assignment_expr
398 $$ = newNode($2,$1,$3);
401 $$ = newNode('=',$1,newNode('*',copyAst($1),$3));
404 $$ = newNode('=',$1,newNode('/',copyAst($1),$3));
407 $$ = newNode('=',$1,newNode('%',copyAst($1),$3));
410 $$ = newNode('=',$1,newNode('+',copyAst($1),$3));
413 $$ = newNode('=',$1,newNode('-',copyAst($1),$3));
416 $$ = newNode('=',$1,newNode(LEFT_OP,copyAst($1),$3));
419 $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3));
422 $$ = newNode('=',$1,newNode('&',copyAst($1),$3));
425 $$ = newNode('=',$1,newNode('^',copyAst($1),$3));
428 $$ = newNode('=',$1,newNode('|',copyAst($1),$3));
453 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
461 : declaration_specifiers ';' { $$ = NULL ; }
462 | declaration_specifiers init_declarator_list ';'
464 /* add the specifier list to the id */
467 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
468 sym_link *lnk = copyLinkChain($1);
469 /* do the pointer stuff */
470 pointerTypes(sym->type,lnk);
471 addDecl (sym,0,lnk) ;
478 declaration_specifiers
479 : storage_class_specifier { $$ = $1; }
480 | storage_class_specifier declaration_specifiers {
481 /* if the decl $2 is not a specifier */
482 /* find the spec and replace it */
485 while (lnk && !IS_SPEC(lnk->next))
487 lnk->next = mergeSpec($1,lnk->next, yytext);
491 $$ = mergeSpec($1,$2, yytext);
493 | type_specifier { $$ = $1; }
494 | type_specifier declaration_specifiers {
495 /* if the decl $2 is not a specifier */
496 /* find the spec and replace it */
499 while (lnk && !IS_SPEC(lnk->next))
501 lnk->next = mergeSpec($1,lnk->next, yytext);
505 $$ = mergeSpec($1,$2, yytext);
511 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
515 : declarator { $1->ival = NULL ; }
516 | declarator '=' initializer { $1->ival = $3 ; }
520 storage_class_specifier
523 $$->class = SPECIFIER ;
524 SPEC_TYPEDEF($$) = 1 ;
528 $$->class = SPECIFIER ;
533 $$->class = SPECIFIER ;
538 $$->class = SPECIFIER ;
539 SPEC_SCLS($$) = S_AUTO ;
543 $$->class = SPECIFIER ;
544 SPEC_SCLS($$) = S_REGISTER ;
549 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
554 | type_specifier2 AT constant_expr
556 /* add this to the storage class specifier */
557 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
558 /* now get the abs addr from value */
559 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
566 $$->class = SPECIFIER ;
567 SPEC_NOUN($$) = V_CHAR ;
571 $$->class = SPECIFIER ;
572 $$->select.s._short = 1 ;
576 $$->class = SPECIFIER ;
577 SPEC_NOUN($$) = V_INT ;
581 $$->class = SPECIFIER ;
586 $$->class = SPECIFIER ;
587 $$->select.s._signed = 1;
591 $$->class = SPECIFIER ;
596 $$->class = SPECIFIER ;
597 SPEC_NOUN($$) = V_VOID ;
601 $$->class = SPECIFIER ;
606 $$->class = SPECIFIER ;
607 SPEC_VOLATILE($$) = 1 ;
611 SPEC_NOUN($$) = V_FLOAT;
612 $$->class = SPECIFIER ;
616 $$->class = SPECIFIER ;
617 SPEC_SCLS($$) = S_XDATA ;
621 $$->class = SPECIFIER ;
622 SPEC_SCLS($$) = S_CODE ;
626 $$->class = SPECIFIER ;
627 SPEC_SCLS($$) = S_EEPROM ;
631 $$->class = SPECIFIER ;
632 SPEC_SCLS($$) = S_DATA ;
636 $$->class = SPECIFIER ;
637 SPEC_SCLS($$) = S_IDATA ;
641 $$->class = SPECIFIER ;
642 SPEC_SCLS($$) = S_PDATA ;
646 $$->class = SPECIFIER ;
647 SPEC_NOUN($$) = V_BIT ;
648 SPEC_SCLS($$) = S_BIT ;
653 | struct_or_union_specifier
662 sym = findSym(TypedefTab,NULL,$1) ;
663 $$ = p = copyLinkChain(sym->type);
664 SPEC_TYPEDEF(getSpec(p)) = 0;
672 $$->class = SPECIFIER ;
673 SPEC_NOUN($$) = V_SBIT;
674 SPEC_SCLS($$) = S_SBIT;
678 $$->class = SPECIFIER ;
679 SPEC_NOUN($$) = V_CHAR;
680 SPEC_SCLS($$) = S_SFR ;
685 struct_or_union_specifier
686 : struct_or_union opt_stag '{' struct_declaration_list '}'
690 /* Create a structdef */
692 sdef->fields = reverseSyms($4) ; /* link the fields */
693 sdef->size = compStructSize($1,sdef); /* update size of */
695 /* Create the specifier */
697 $$->class = SPECIFIER ;
698 SPEC_NOUN($$) = V_STRUCT;
699 SPEC_STRUCT($$)= sdef ;
701 | struct_or_union stag
704 $$->class = SPECIFIER ;
705 SPEC_NOUN($$) = V_STRUCT;
706 SPEC_STRUCT($$) = $2 ;
711 : STRUCT { $$ = STRUCT ; }
712 | UNION { $$ = UNION ; }
717 | { /* synthesize a name add to structtable */
718 $$ = newStruct(genSymName(NestLevel)) ;
719 $$->level = NestLevel ;
720 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
724 : identifier { /* add name to structure table */
725 $$ = findSymWithBlock (StructTab,$1,currBlockno);
727 $$ = newStruct($1->name) ;
728 $$->level = NestLevel ;
729 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
734 struct_declaration_list
736 | struct_declaration_list struct_declaration
739 /* go to the end of the chain */
740 while (sym->next) sym = sym->next;
748 : type_specifier_list struct_declarator_list ';'
750 /* add this type to all the symbols */
752 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
754 /* make the symbol one level up */
757 pointerTypes(sym->type,copyLinkChain($1));
759 sym->type = copyLinkChain($1);
760 sym->etype = getSpec(sym->type);
763 addDecl (sym,0,cloneSpec($1));
764 /* make sure the type is complete and sane */
765 checkTypeSanity(sym->etype, sym->name);
771 struct_declarator_list
773 | struct_declarator_list ',' struct_declarator
782 | ':' constant_expr {
783 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
784 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
786 | declarator ':' constant_expr
788 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
793 : ENUM '{' enumerator_list '}' {
795 //allocVariables(reverseSyms($3)) ;
796 $$ = copyLinkChain(cenum->type);
798 | ENUM identifier '{' enumerator_list '}' {
801 $2->type = copyLinkChain(cenum->type);
802 $2->etype = getSpec($2->type);
803 /* add this to the enumerator table */
804 if (!(csym=findSym(enumTab,$2,$2->name)) &&
805 (csym && csym->level == $2->level))
806 werror(E_DUPLICATE_TYPEDEF,csym->name);
808 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
810 //allocVariables (reverseSyms($4));
811 $$ = copyLinkChain(cenum->type);
812 SPEC_SCLS(getSpec($$)) = 0 ;
817 /* check the enumerator table */
818 if ((csym = findSym(enumTab,$2,$2->name)))
819 $$ = copyLinkChain(csym->type);
822 $$->class = SPECIFIER ;
823 SPEC_NOUN($$) = V_INT ;
826 SPEC_SCLS(getSpec($$)) = 0 ;
832 | enumerator_list ',' {
834 | enumerator_list ',' enumerator {
841 : identifier opt_assign_expr
843 /* make the symbol one level up */
845 $1->type = copyLinkChain($2->type);
846 $1->etype= getSpec($1->type);
847 SPEC_ENUM($1->etype) = 1;
849 // do this now, so we can use it for the next enums in the list
855 : '=' constant_expr {
858 val = constExprValue($2,TRUE);
863 sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
864 $$ = cenum = constVal(lbuff);
867 sprintf(lbuff,"%d",0);
868 $$ = cenum = constVal(lbuff);
874 : declarator2_function_attributes { $$ = $1; }
875 | pointer declarator2_function_attributes
877 addDecl ($2,0,reverseLink($1));
882 declarator2_function_attributes
883 : declarator2 { $$ = $1 ; }
884 | declarator2 function_attribute {
885 // copy the functionAttributes (not the args and hasVargs !!)
886 sym_link *funcType=$1->etype;
887 struct value *args=FUNC_ARGS(funcType);
888 unsigned hasVargs=FUNC_HASVARARGS(funcType);
890 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
891 sizeof($2->funcAttrs));
893 FUNC_ARGS(funcType)=args;
894 FUNC_HASVARARGS(funcType)=hasVargs;
897 memset (&$2->funcAttrs, 0,
898 sizeof($2->funcAttrs));
906 | '(' declarator ')' { $$ = $2; }
907 | declarator2 '[' ']'
912 DCL_TYPE(p) = ARRAY ;
916 | declarator2 '[' constant_expr ']'
921 p = (tval = constExprValue($3,TRUE))->etype;
922 /* if it is not a constant then Error */
923 if ( SPEC_SCLS(p) != S_LITERAL)
924 werror(E_CONST_EXPECTED) ;
927 DCL_TYPE(p) = ARRAY ;
928 DCL_ELEM(p) = (int) floatFromVal(tval) ;
932 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
933 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
936 addDecl ($1,FUNCTION,NULL) ;
938 FUNC_HASVARARGS($1->type) = IS_VARG($4);
939 FUNC_ARGS($1->type) = reverseVal($4);
941 /* nest level was incremented to take care of the parms */
945 // if this was a pointer (to a function)
946 if (IS_PTR($1->type)) {
947 // move the args and hasVargs to the function
948 FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
949 FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
950 memset (&$1->type->funcAttrs, 0,
951 sizeof($1->type->funcAttrs));
952 // remove the symbol args (if any)
953 cleanUpLevel(SymbolTab,NestLevel+1);
958 | declarator2 '(' parameter_identifier_list ')'
960 werror(E_OLD_STYLE,$1->name) ;
962 /* assume it returns an int */
963 $1->type = $1->etype = newIntLink();
969 : unqualified_pointer { $$ = $1 ;}
970 | unqualified_pointer type_specifier_list
975 | unqualified_pointer pointer
979 DCL_TYPE($2)=GPOINTER;
981 | unqualified_pointer type_specifier_list pointer
984 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
985 DCL_PTR_CONST($1) = SPEC_CONST($2);
986 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
987 switch (SPEC_SCLS($2)) {
989 DCL_TYPE($3) = FPOINTER;
992 DCL_TYPE($3) = IPOINTER ;
995 DCL_TYPE($3) = PPOINTER ;
998 DCL_TYPE($3) = POINTER ;
1001 DCL_PTR_CONST($3) = 1;
1002 DCL_TYPE($3) = CPOINTER ;
1005 DCL_TYPE($3) = EEPPOINTER;
1008 // this could be just "constant"
1009 // werror(W_PTR_TYPE_INVALID);
1013 werror (W_PTR_TYPE_INVALID);
1022 DCL_TYPE($$)=UPOINTER;
1028 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1029 | type_specifier_list type_specifier {
1030 /* if the decl $2 is not a specifier */
1031 /* find the spec and replace it */
1032 if ( !IS_SPEC($2)) {
1033 sym_link *lnk = $2 ;
1034 while (lnk && !IS_SPEC(lnk->next))
1036 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list");
1040 $$ = mergeSpec($1,$2, "type_specifier_list");
1044 parameter_identifier_list
1046 | identifier_list ',' ELIPSIS
1051 | identifier_list ',' identifier
1060 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1064 : parameter_declaration
1065 | parameter_list ',' parameter_declaration
1072 parameter_declaration
1073 : type_specifier_list declarator
1076 pointerTypes($2->type,$1);
1078 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1085 $$->etype = getSpec($$->type);
1090 : type_specifier_list { $$ = $1 ;}
1091 | type_specifier_list abstract_declarator
1093 /* go to the end of the list */
1095 pointerTypes($2,$1);
1096 for ( p = $2 ; p->next ; p=p->next);
1103 : pointer { $$ = reverseLink($1); }
1104 | abstract_declarator2
1105 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1108 abstract_declarator2
1109 : '(' abstract_declarator ')' { $$ = $2 ; }
1112 DCL_TYPE($$) = ARRAY ;
1115 | '[' constant_expr ']' {
1118 DCL_TYPE($$) = ARRAY ;
1119 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1121 | abstract_declarator2 '[' ']' {
1123 DCL_TYPE($$) = ARRAY ;
1127 | abstract_declarator2 '[' constant_expr ']'
1131 DCL_TYPE($$) = ARRAY ;
1132 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1135 | '(' ')' { $$ = NULL;}
1136 | '(' parameter_type_list ')' { $$ = NULL;}
1137 | abstract_declarator2 '(' ')' {
1138 // $1 must be a pointer to a function
1139 sym_link *p=newLink();
1140 DCL_TYPE(p) = FUNCTION;
1143 | abstract_declarator2 '(' parameter_type_list ')' {
1144 if (!IS_VOID($3->type)) {
1145 // this is nonsense, so let's just burp something
1146 werror(E_TOO_FEW_PARMS);
1148 // $1 must be a pointer to a function
1149 sym_link *p=newLink();
1150 DCL_TYPE(p) = FUNCTION;
1156 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1157 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1158 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1163 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1168 | compound_statement
1169 | expression_statement
1170 | selection_statement
1171 | iteration_statement
1174 ast *ex = newNode(INLINEASM,NULL,NULL);
1175 ex->values.inlineasm = malloc(strlen($1)+1);
1176 strcpy(ex->values.inlineasm,$1);
1182 // : identifier ':' statement { $$ = createLabel($1,$3); }
1183 : identifier ':' { $$ = createLabel($1,NULL); }
1184 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1185 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1188 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1191 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1195 : start_block end_block { $$ = createBlock(NULL,NULL); }
1196 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1198 declaration_list { addSymChain($2); }
1199 end_block { $$ = createBlock($2,NULL) ; }
1201 declaration_list { addSymChain ($2); }
1203 end_block {$$ = createBlock($2,$4) ; }
1204 | error ';' { $$ = NULL ; }
1210 /* if this is typedef declare it immediately */
1211 if ( $1 && IS_TYPEDEF($1->etype)) {
1212 allocVariables ($1);
1219 | declaration_list declaration
1223 /* if this is a typedef */
1224 if ($2 && IS_TYPEDEF($2->etype)) {
1225 allocVariables ($2);
1229 /* get to the end of the previous decl */
1244 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1247 expression_statement
1253 : ELSE statement { $$ = $2 ; }
1259 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1260 | SWITCH '(' expr ')' {
1262 static int swLabel = 0 ;
1264 /* create a node for expression */
1265 ex = newNode(SWITCH,$3,NULL);
1266 STACK_PUSH(swStk,ex); /* save it in the stack */
1267 ex->values.switchVals.swNum = swLabel ;
1269 /* now create the label */
1270 sprintf(lbuff,"_swBrk_%d",swLabel++);
1271 $<sym>$ = newSymbol(lbuff,NestLevel);
1272 /* put label in the break stack */
1273 STACK_PUSH(breakStack,$<sym>$);
1276 /* get back the switch form the stack */
1277 $$ = STACK_POP(swStk) ;
1278 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1279 STACK_POP(breakStack);
1283 while : WHILE { /* create and push the continue , break & body labels */
1284 static int Lblnum = 0 ;
1286 sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1287 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1289 sprintf (lbuff,"_whilebreak_%d",Lblnum);
1290 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1292 sprintf (lbuff,"_whilebody_%d",Lblnum++);
1293 $$ = newSymbol(lbuff,NestLevel);
1296 do : DO { /* create and push the continue , break & body Labels */
1297 static int Lblnum = 0 ;
1300 sprintf(lbuff,"_docontinue_%d",Lblnum);
1301 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1303 sprintf (lbuff,"_dobreak_%d",Lblnum);
1304 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1306 sprintf (lbuff,"_dobody_%d",Lblnum++);
1307 $$ = newSymbol (lbuff,NestLevel);
1309 for : FOR { /* create & push continue, break & body labels */
1310 static int Lblnum = 0 ;
1313 sprintf (lbuff,"_forcontinue_%d",Lblnum);
1314 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1316 sprintf (lbuff,"_forbreak_%d",Lblnum);
1317 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1319 sprintf (lbuff,"_forbody_%d",Lblnum);
1320 $$ = newSymbol(lbuff,NestLevel);
1322 sprintf (lbuff,"_forcond_%d",Lblnum++);
1323 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1327 : while '(' expr ')' statement
1330 $$ = createWhile ( $1, STACK_POP(continueStack),
1331 STACK_POP(breakStack), $3, $5 );
1332 $$->lineno = $1->lineDef ;
1335 | do statement WHILE '(' expr ')' ';'
1338 $$ = createDo ( $1 , STACK_POP(continueStack),
1339 STACK_POP(breakStack), $5, $2);
1340 $$->lineno = $1->lineDef ;
1343 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1347 /* if break or continue statement present
1348 then create a general case loop */
1349 if (STACK_PEEK(continueStack)->isref ||
1350 STACK_PEEK(breakStack)->isref) {
1351 $$ = createFor ($1, STACK_POP(continueStack),
1352 STACK_POP(breakStack) ,
1353 STACK_POP(forStack) ,
1356 $$ = newNode(FOR,$9,NULL);
1357 AST_FOR($$,trueLabel) = $1;
1358 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1359 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1360 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1361 AST_FOR($$,initExpr) = $3;
1362 AST_FOR($$,condExpr) = $5;
1363 AST_FOR($$,loopExpr) = $7;
1376 : GOTO identifier ';' {
1378 $$ = newAst_VALUE(symbolVal($2));
1379 $$ = newNode(GOTO,$$,NULL);
1382 /* make sure continue is in context */
1383 if (STACK_PEEK(continueStack) == NULL) {
1384 werror(E_BREAK_CONTEXT);
1388 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1389 $$ = newNode(GOTO,$$,NULL);
1390 /* mark the continue label as referenced */
1391 STACK_PEEK(continueStack)->isref = 1;
1395 if (STACK_PEEK(breakStack) == NULL) {
1396 werror(E_BREAK_CONTEXT);
1399 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1400 $$ = newNode(GOTO,$$,NULL);
1401 STACK_PEEK(breakStack)->isref = 1;
1404 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1405 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1409 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }