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_using_reentrant 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> using_reentrant using_reentrant_interrupt 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 { blockNo=0;}
134 && IS_FUNC($1->type))
136 /* The only legal storage classes for
137 * a function prototype (declaration)
138 * are extern and static. extern is the
139 * default. Thus, if this function isn't
140 * explicitly marked static, mark it
144 && IS_SPEC($1->etype)
145 && !SPEC_STAT($1->etype))
147 SPEC_EXTR($1->etype) = 1;
151 allocVariables ($1) ;
152 cleanUpLevel (SymbolTab,1);
157 : declarator function_body { /* function type not specified */
158 /* assume it to be 'int' */
159 addDecl($1,0,newIntLink());
160 $$ = createFunction($1,$2);
162 | declaration_specifiers declarator function_body
164 pointerTypes($2->type,copyLinkChain($1));
166 $$ = createFunction($2,$3);
171 : using_reentrant_interrupt
172 | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2,"using_reentrant"); }
175 using_reentrant_interrupt
178 $$->class = SPECIFIER ;
180 SPEC_BANK($$) = (int) floatFromVal($2);
182 | REENTRANT { $$ = newLink ();
183 $$->class = SPECIFIER ;
186 | CRITICAL { $$ = newLink ();
187 $$->class = SPECIFIER ;
190 | NAKED { $$ = newLink ();
191 $$->class = SPECIFIER ;
194 | NONBANKED {$$ = newLink ();
195 $$->class = SPECIFIER ;
196 SPEC_NONBANKED($$) = 1;
197 if (SPEC_BANKED($$)) {
198 werror(W_BANKED_WITH_NONBANKED);
201 | BANKED {$$ = newLink ();
202 $$->class = SPECIFIER ;
204 if (SPEC_NONBANKED($$)) {
205 werror(W_BANKED_WITH_NONBANKED);
208 werror(W_BANKED_WITH_STATIC);
214 $$->class = SPECIFIER ;
222 | declaration_list compound_statement
224 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
230 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
231 | CONSTANT { $$ = newAst_VALUE($1); }
233 | '(' expr ')' { $$ = $2 ; }
237 : STRING_LITERAL { $$ = newAst_VALUE($1); }
242 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
243 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
244 $$->left->funcName = 1;}
245 | postfix_expr '(' argument_expr_list ')'
247 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
249 | postfix_expr '.' identifier
251 $3 = newSymbol($3->name,NestLevel);
253 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
254 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
256 | postfix_expr PTR_OP identifier
258 $3 = newSymbol($3->name,NestLevel);
260 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
262 | postfix_expr INC_OP
263 { $$ = newNode(INC_OP,$1,NULL);}
264 | postfix_expr DEC_OP
265 { $$ = newNode(DEC_OP,$1,NULL); }
270 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
275 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
276 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
277 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
278 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
279 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
293 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
298 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
299 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
300 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
304 : multiplicative_expr
305 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
306 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
311 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
312 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
317 | relational_expr '<' shift_expr {
319 newNode('!',newNode(GE_OP,$1,$3),NULL) :
320 newNode('<', $1,$3));
322 | relational_expr '>' shift_expr {
324 newNode('!',newNode(LE_OP,$1,$3),NULL) :
327 | relational_expr LE_OP shift_expr {
329 newNode('!', newNode('>', $1 , $3 ), NULL) :
330 newNode(LE_OP,$1,$3));
332 | relational_expr GE_OP shift_expr {
334 newNode('!', newNode('<', $1 , $3 ), NULL) :
335 newNode(GE_OP,$1,$3));
341 | equality_expr EQ_OP relational_expr {
343 newNode('!',newNode(NE_OP,$1,$3),NULL) :
344 newNode(EQ_OP,$1,$3));
346 | equality_expr NE_OP relational_expr {
348 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
349 newNode(NE_OP,$1,$3));
355 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
360 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
365 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
370 | logical_and_expr AND_OP inclusive_or_expr
371 { $$ = newNode(AND_OP,$1,$3);}
376 | logical_or_expr OR_OP logical_and_expr
377 { $$ = newNode(OR_OP,$1,$3); }
382 | logical_or_expr '?' logical_or_expr ':' conditional_expr
384 $$ = newNode(':',$3,$5) ;
385 $$ = newNode('?',$1,$$) ;
391 | unary_expr assignment_operator assignment_expr
396 $$ = newNode($2,$1,$3);
399 $$ = newNode('=',$1,newNode('*',copyAst($1),$3));
402 $$ = newNode('=',$1,newNode('/',copyAst($1),$3));
405 $$ = newNode('=',$1,newNode('%',copyAst($1),$3));
408 $$ = newNode('=',$1,newNode('+',copyAst($1),$3));
411 $$ = newNode('=',$1,newNode('-',copyAst($1),$3));
414 $$ = newNode('=',$1,newNode(LEFT_OP,copyAst($1),$3));
417 $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3));
420 $$ = newNode('=',$1,newNode('&',copyAst($1),$3));
423 $$ = newNode('=',$1,newNode('^',copyAst($1),$3));
426 $$ = newNode('=',$1,newNode('|',copyAst($1),$3));
451 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
459 : declaration_specifiers ';' { $$ = NULL ; }
460 | declaration_specifiers init_declarator_list ';'
462 /* add the specifier list to the id */
465 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
466 sym_link *lnk = copyLinkChain($1);
467 /* do the pointer stuff */
468 pointerTypes(sym->type,lnk);
469 addDecl (sym,0,lnk) ;
476 declaration_specifiers
477 : storage_class_specifier { $$ = $1; }
478 | storage_class_specifier declaration_specifiers {
479 /* if the decl $2 is not a specifier */
480 /* find the spec and replace it */
483 while (lnk && !IS_SPEC(lnk->next))
485 lnk->next = mergeSpec($1,lnk->next, yytext);
489 $$ = mergeSpec($1,$2, yytext);
491 | type_specifier { $$ = $1; }
492 | type_specifier declaration_specifiers {
493 /* if the decl $2 is not a specifier */
494 /* find the spec and replace it */
497 while (lnk && !IS_SPEC(lnk->next))
499 lnk->next = mergeSpec($1,lnk->next, yytext);
503 $$ = mergeSpec($1,$2, yytext);
509 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
513 : declarator { $1->ival = NULL ; }
514 | declarator '=' initializer { $1->ival = $3 ; }
518 storage_class_specifier
521 $$->class = SPECIFIER ;
522 SPEC_TYPEDEF($$) = 1 ;
526 $$->class = SPECIFIER ;
531 $$->class = SPECIFIER ;
536 $$->class = SPECIFIER ;
537 SPEC_SCLS($$) = S_AUTO ;
541 $$->class = SPECIFIER ;
542 SPEC_SCLS($$) = S_REGISTER ;
547 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
552 | type_specifier2 AT constant_expr
554 /* add this to the storage class specifier */
555 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
556 /* now get the abs addr from value */
557 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
564 $$->class = SPECIFIER ;
565 SPEC_NOUN($$) = V_CHAR ;
569 $$->class = SPECIFIER ;
570 $$->select.s._short = 1 ;
574 $$->class = SPECIFIER ;
575 SPEC_NOUN($$) = V_INT ;
579 $$->class = SPECIFIER ;
584 $$->class = SPECIFIER ;
585 $$->select.s._signed = 1;
589 $$->class = SPECIFIER ;
594 $$->class = SPECIFIER ;
595 SPEC_NOUN($$) = V_VOID ;
599 $$->class = SPECIFIER ;
604 $$->class = SPECIFIER ;
605 SPEC_VOLATILE($$) = 1 ;
609 SPEC_NOUN($$) = V_FLOAT;
610 $$->class = SPECIFIER ;
614 $$->class = SPECIFIER ;
615 SPEC_SCLS($$) = S_XDATA ;
619 $$->class = SPECIFIER ;
620 SPEC_SCLS($$) = S_CODE ;
624 $$->class = SPECIFIER ;
625 SPEC_SCLS($$) = S_EEPROM ;
629 $$->class = SPECIFIER ;
630 SPEC_SCLS($$) = S_DATA ;
634 $$->class = SPECIFIER ;
635 SPEC_SCLS($$) = S_IDATA ;
639 $$->class = SPECIFIER ;
640 SPEC_SCLS($$) = S_PDATA ;
644 $$->class = SPECIFIER ;
645 SPEC_NOUN($$) = V_BIT ;
646 SPEC_SCLS($$) = S_BIT ;
651 | struct_or_union_specifier
660 sym = findSym(TypedefTab,NULL,$1) ;
661 $$ = p = copyLinkChain(sym->type);
662 SPEC_TYPEDEF(getSpec(p)) = 0;
670 $$->class = SPECIFIER ;
671 SPEC_NOUN($$) = V_SBIT;
672 SPEC_SCLS($$) = S_SBIT;
676 $$->class = SPECIFIER ;
677 SPEC_NOUN($$) = V_CHAR;
678 SPEC_SCLS($$) = S_SFR ;
683 struct_or_union_specifier
684 : struct_or_union opt_stag '{' struct_declaration_list '}'
688 /* Create a structdef */
690 sdef->fields = reverseSyms($4) ; /* link the fields */
691 sdef->size = compStructSize($1,sdef); /* update size of */
693 /* Create the specifier */
695 $$->class = SPECIFIER ;
696 SPEC_NOUN($$) = V_STRUCT;
697 SPEC_STRUCT($$)= sdef ;
699 | struct_or_union stag
702 $$->class = SPECIFIER ;
703 SPEC_NOUN($$) = V_STRUCT;
704 SPEC_STRUCT($$) = $2 ;
709 : STRUCT { $$ = STRUCT ; }
710 | UNION { $$ = UNION ; }
715 | { /* synthesize a name add to structtable */
716 $$ = newStruct(genSymName(NestLevel)) ;
717 $$->level = NestLevel ;
718 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
722 : identifier { /* add name to structure table */
723 $$ = findSymWithBlock (StructTab,$1,currBlockno);
725 $$ = newStruct($1->name) ;
726 $$->level = NestLevel ;
727 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
732 struct_declaration_list
734 | struct_declaration_list struct_declaration
737 /* go to the end of the chain */
738 while (sym->next) sym = sym->next;
746 : type_specifier_list struct_declarator_list ';'
748 /* add this type to all the symbols */
750 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
752 /* make the symbol one level up */
755 pointerTypes(sym->type,copyLinkChain($1));
757 sym->type = copyLinkChain($1);
758 sym->etype = getSpec(sym->type);
761 addDecl (sym,0,cloneSpec($1));
762 /* make sure the type is complete and sane */
763 checkTypeSanity(sym->etype, sym->name);
769 struct_declarator_list
771 | struct_declarator_list ',' struct_declarator
780 | ':' constant_expr {
781 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
782 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
784 | declarator ':' constant_expr
786 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
791 : ENUM '{' enumerator_list '}' {
793 allocVariables(reverseSyms($3)) ;
794 $$ = copyLinkChain(cenum->type);
796 | ENUM identifier '{' enumerator_list '}' {
799 $2->type = copyLinkChain(cenum->type);
800 $2->etype = getSpec($2->type);
801 /* add this to the enumerator table */
802 if (!(csym=findSym(enumTab,$2,$2->name)) &&
803 (csym && csym->level == $2->level))
804 werror(E_DUPLICATE_TYPEDEF,csym->name);
806 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
808 allocVariables (reverseSyms($4));
809 $$ = copyLinkChain(cenum->type);
810 SPEC_SCLS(getSpec($$)) = 0 ;
815 /* check the enumerator table */
816 if ((csym = findSym(enumTab,$2,$2->name)))
817 $$ = copyLinkChain(csym->type);
820 $$->class = SPECIFIER ;
821 SPEC_NOUN($$) = V_INT ;
824 SPEC_SCLS(getSpec($$)) = 0 ;
830 | enumerator_list ',' {
832 | enumerator_list ',' enumerator {
839 : identifier opt_assign_expr {
840 /* make the symbol one level up */
842 $1->type = copyLinkChain($2->type);
843 $1->etype= getSpec($1->type);
844 SPEC_ENUM($1->etype) = 1;
851 : '=' constant_expr {
854 val = constExprValue($2,TRUE);
859 sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
860 $$ = cenum = constVal(lbuff);
863 sprintf(lbuff,"%d",0);
864 $$ = cenum = constVal(lbuff);
870 : declarator2_using_reentrant { $$ = $1; }
871 | pointer declarator2_using_reentrant
873 addDecl ($2,0,reverseLink($1));
878 declarator2_using_reentrant
879 : declarator2 { $$ = $1 ; }
880 | declarator2 using_reentrant { addDecl ($1,0,$2); }
885 | '(' declarator ')' { $$ = $2; }
886 | declarator2 '[' ']'
891 DCL_TYPE(p) = ARRAY ;
895 | declarator2 '[' constant_expr ']'
900 p = (tval = constExprValue($3,TRUE))->etype;
901 /* if it is not a constant then Error */
902 if ( SPEC_SCLS(p) != S_LITERAL)
903 werror(E_CONST_EXPECTED) ;
906 DCL_TYPE(p) = ARRAY ;
907 DCL_ELEM(p) = (int) floatFromVal(tval) ;
911 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
912 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
915 addDecl ($1,FUNCTION,NULL) ;
917 $1->hasVargs = IS_VARG($4);
918 $1->args = reverseVal($4) ;
921 /* nest level was incremented to take care of the parms */
925 // if this was a pointer to a function, remove the symbol args
927 if (IS_PTR($1->type) && IS_FUNC($1->etype)) {
928 cleanUpLevel(SymbolTab,NestLevel+1);
929 /* fprintf (stderr, "Removed parm symbols of %s in line %d\n",
930 $1->name, yylineno); */
935 | declarator2 '(' parameter_identifier_list ')'
937 werror(E_OLD_STYLE,$1->name) ;
939 /* assume it returns an int */
940 $1->type = $1->etype = newIntLink();
946 : unqualified_pointer { $$ = $1 ;}
947 | unqualified_pointer type_specifier_list
952 | unqualified_pointer pointer
956 DCL_TYPE($2)=GPOINTER;
958 | unqualified_pointer type_specifier_list pointer
961 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
962 DCL_PTR_CONST($1) = SPEC_CONST($2);
963 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
964 switch (SPEC_SCLS($2)) {
966 DCL_TYPE($3) = FPOINTER;
969 DCL_TYPE($3) = IPOINTER ;
972 DCL_TYPE($3) = PPOINTER ;
975 DCL_TYPE($3) = POINTER ;
978 DCL_PTR_CONST($3) = 1;
979 DCL_TYPE($3) = CPOINTER ;
982 DCL_TYPE($3) = EEPPOINTER;
985 werror(W_PTR_TYPE_INVALID);
989 werror (W_PTR_TYPE_INVALID);
998 DCL_TYPE($$)=UPOINTER;
1004 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1005 | type_specifier_list type_specifier {
1006 /* if the decl $2 is not a specifier */
1007 /* find the spec and replace it */
1008 if ( !IS_SPEC($2)) {
1009 sym_link *lnk = $2 ;
1010 while (lnk && !IS_SPEC(lnk->next))
1012 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list");
1016 $$ = mergeSpec($1,$2, "type_specifier_list");
1020 parameter_identifier_list
1022 | identifier_list ',' ELIPSIS
1027 | identifier_list ',' identifier
1036 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1040 : parameter_declaration
1041 | parameter_list ',' parameter_declaration
1048 parameter_declaration
1049 : type_specifier_list declarator
1052 pointerTypes($2->type,$1);
1054 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1061 $$->etype = getSpec($$->type);
1066 : type_specifier_list { $$ = $1 ;}
1067 | type_specifier_list abstract_declarator
1069 /* go to the end of the list */
1071 pointerTypes($2,$1);
1072 for ( p = $2 ; p->next ; p=p->next);
1079 : pointer { $$ = reverseLink($1); }
1080 | abstract_declarator2
1081 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1084 abstract_declarator2
1085 : '(' abstract_declarator ')' { $$ = $2 ; }
1088 DCL_TYPE($$) = ARRAY ;
1091 | '[' constant_expr ']' {
1094 DCL_TYPE($$) = ARRAY ;
1095 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1097 | abstract_declarator2 '[' ']' {
1099 DCL_TYPE($$) = ARRAY ;
1103 | abstract_declarator2 '[' constant_expr ']'
1107 DCL_TYPE($$) = ARRAY ;
1108 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1111 | '(' ')' { $$ = NULL;}
1112 | '(' parameter_type_list ')' { $$ = NULL;}
1113 | abstract_declarator2 '(' ')' {
1114 // $1 must be a pointer to a function
1115 sym_link *p=newLink();
1116 DCL_TYPE(p) = FUNCTION;
1119 | abstract_declarator2 '(' parameter_type_list ')' {
1120 if (!IS_VOID($3->type)) {
1121 // this is nonsense, so let's just burp something
1122 werror(E_TOO_FEW_PARMS);
1124 // $1 must be a pointer to a function
1125 sym_link *p=newLink();
1126 DCL_TYPE(p) = FUNCTION;
1132 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1133 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1134 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1139 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1144 | compound_statement
1145 | expression_statement
1146 | selection_statement
1147 | iteration_statement
1150 ast *ex = newNode(INLINEASM,NULL,NULL);
1151 ex->values.inlineasm = malloc(strlen($1)+1);
1152 strcpy(ex->values.inlineasm,$1);
1158 // : identifier ':' statement { $$ = createLabel($1,$3); }
1159 : identifier ':' { $$ = createLabel($1,NULL); }
1160 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1161 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1164 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1167 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1171 : start_block end_block { $$ = createBlock(NULL,NULL); }
1172 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1174 declaration_list { addSymChain($2); }
1175 end_block { $$ = createBlock($2,NULL) ; }
1177 declaration_list { addSymChain ($2); }
1179 end_block {$$ = createBlock($2,$4) ; }
1180 | error ';' { $$ = NULL ; }
1186 /* if this is typedef declare it immediately */
1187 if ( $1 && IS_TYPEDEF($1->etype)) {
1188 allocVariables ($1);
1195 | declaration_list declaration
1199 /* if this is a typedef */
1200 if ($2 && IS_TYPEDEF($2->etype)) {
1201 allocVariables ($2);
1205 /* get to the end of the previous decl */
1220 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1223 expression_statement
1229 : ELSE statement { $$ = $2 ; }
1235 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1236 | SWITCH '(' expr ')' {
1238 static int swLabel = 0 ;
1240 /* create a node for expression */
1241 ex = newNode(SWITCH,$3,NULL);
1242 STACK_PUSH(swStk,ex); /* save it in the stack */
1243 ex->values.switchVals.swNum = swLabel ;
1245 /* now create the label */
1246 sprintf(lbuff,"_swBrk_%d",swLabel++);
1247 $<sym>$ = newSymbol(lbuff,NestLevel);
1248 /* put label in the break stack */
1249 STACK_PUSH(breakStack,$<sym>$);
1252 /* get back the switch form the stack */
1253 $$ = STACK_POP(swStk) ;
1254 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1255 STACK_POP(breakStack);
1259 while : WHILE { /* create and push the continue , break & body labels */
1260 static int Lblnum = 0 ;
1262 sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1263 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1265 sprintf (lbuff,"_whilebreak_%d",Lblnum);
1266 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1268 sprintf (lbuff,"_whilebody_%d",Lblnum++);
1269 $$ = newSymbol(lbuff,NestLevel);
1272 do : DO { /* create and push the continue , break & body Labels */
1273 static int Lblnum = 0 ;
1276 sprintf(lbuff,"_docontinue_%d",Lblnum);
1277 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1279 sprintf (lbuff,"_dobreak_%d",Lblnum);
1280 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1282 sprintf (lbuff,"_dobody_%d",Lblnum++);
1283 $$ = newSymbol (lbuff,NestLevel);
1285 for : FOR { /* create & push continue, break & body labels */
1286 static int Lblnum = 0 ;
1289 sprintf (lbuff,"_forcontinue_%d",Lblnum);
1290 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1292 sprintf (lbuff,"_forbreak_%d",Lblnum);
1293 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1295 sprintf (lbuff,"_forbody_%d",Lblnum);
1296 $$ = newSymbol(lbuff,NestLevel);
1298 sprintf (lbuff,"_forcond_%d",Lblnum++);
1299 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1303 : while '(' expr ')' statement
1306 $$ = createWhile ( $1, STACK_POP(continueStack),
1307 STACK_POP(breakStack), $3, $5 );
1308 $$->lineno = $1->lineDef ;
1311 | do statement WHILE '(' expr ')' ';'
1314 $$ = createDo ( $1 , STACK_POP(continueStack),
1315 STACK_POP(breakStack), $5, $2);
1316 $$->lineno = $1->lineDef ;
1319 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1323 /* if break or continue statement present
1324 then create a general case loop */
1325 if (STACK_PEEK(continueStack)->isref ||
1326 STACK_PEEK(breakStack)->isref) {
1327 $$ = createFor ($1, STACK_POP(continueStack),
1328 STACK_POP(breakStack) ,
1329 STACK_POP(forStack) ,
1332 $$ = newNode(FOR,$9,NULL);
1333 AST_FOR($$,trueLabel) = $1;
1334 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1335 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1336 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1337 AST_FOR($$,initExpr) = $3;
1338 AST_FOR($$,condExpr) = $5;
1339 AST_FOR($$,loopExpr) = $7;
1352 : GOTO identifier ';' {
1354 $$ = newAst_VALUE(symbolVal($2));
1355 $$ = newNode(GOTO,$$,NULL);
1358 /* make sure continue is in context */
1359 if (STACK_PEEK(continueStack) == NULL) {
1360 werror(E_BREAK_CONTEXT);
1364 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1365 $$ = newNode(GOTO,$$,NULL);
1366 /* mark the continue label as referenced */
1367 STACK_PEEK(continueStack)->isref = 1;
1371 if (STACK_PEEK(breakStack) == NULL) {
1372 werror(E_BREAK_CONTEXT);
1375 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1376 $$ = newNode(GOTO,$$,NULL);
1377 STACK_PEEK(breakStack)->isref = 1;
1380 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1381 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1385 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }