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*/
62 symbol *sym ; /* symbol table pointer */
63 structdef *sdef; /* structure definition */
64 char yychar[SDCC_NAME_MAX+1];
65 sym_link *lnk ; /* declarator or specifier */
66 int yyint; /* integer value returned */
67 value *val ; /* for integer constant */
68 initList *ilist; /* initial list */
69 char *yyinline; /* inlined assembler code */
70 ast *asts; /* expression tree */
73 %token <yychar> IDENTIFIER TYPE_NAME
74 %token <val> CONSTANT STRING_LITERAL
76 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
78 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
79 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
80 %token <yyint> XOR_ASSIGN OR_ASSIGN
81 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
82 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
83 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
84 %token STRUCT UNION ENUM ELIPSIS RANGE FAR _XDATA _CODE _GENERIC _NEAR _PDATA _IDATA _EEPROM
85 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
87 %token <yyinline> INLINEASM
88 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
89 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
91 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND
93 %type <yyint> Interrupt_storage
94 %type <sym> identifier declarator declarator2 enumerator_list enumerator
95 %type <sym> struct_declarator
96 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
97 %type <sym> declaration init_declarator_list init_declarator
98 %type <sym> declaration_list identifier_list parameter_identifier_list
99 %type <sym> declarator2_using_reentrant while do for
100 %type <lnk> pointer type_specifier_list type_specifier type_name
101 %type <lnk> storage_class_specifier struct_or_union_specifier
102 %type <lnk> declaration_specifiers sfr_reg_bit type_specifier2
103 %type <lnk> using_reentrant using_reentrant_interrupt enum_specifier
104 %type <lnk> abstract_declarator abstract_declarator2 far_near_pointer far_near
105 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
106 %type <sdef> stag opt_stag
107 %type <asts> primary_expr
108 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
109 %type <asts> additive_expr shift_expr relational_expr equality_expr
110 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
111 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
112 %type <asts> expr argument_expr_list function_definition expr_opt
113 %type <asts> statement_list statement labeled_statement compound_statement
114 %type <asts> expression_statement selection_statement iteration_statement
115 %type <asts> jump_statement function_body else_statement string_literal
116 %type <ilist> initializer initializer_list
117 %type <yyint> unary_operator assignment_operator struct_or_union
124 : external_definition
125 | file external_definition
129 : function_definition { blockNo=0;}
132 && IS_FUNC($1->type))
134 /* The only legal storage classes for
135 * a function prototype (declaration)
136 * are extern and static. extern is the
137 * default. Thus, if this function isn't
138 * explicitly marked static, mark it
142 && IS_SPEC($1->etype)
143 && !SPEC_STAT($1->etype))
145 SPEC_EXTR($1->etype) = 1;
149 allocVariables ($1) ;
150 cleanUpLevel (SymbolTab,1);
155 : declarator function_body { /* function type not specified */
156 /* assume it to be 'int' */
157 addDecl($1,0,newIntLink());
158 $$ = createFunction($1,$2);
160 | declaration_specifiers declarator function_body
162 pointerTypes($2->type,copyLinkChain($1));
164 $$ = createFunction($2,$3);
169 : using_reentrant_interrupt
170 | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2,"using_reentrant"); }
173 using_reentrant_interrupt
176 $$->class = SPECIFIER ;
178 SPEC_BANK($$) = (int) floatFromVal($2);
180 | REENTRANT { $$ = newLink ();
181 $$->class = SPECIFIER ;
184 | CRITICAL { $$ = newLink ();
185 $$->class = SPECIFIER ;
188 | NAKED { $$ = newLink ();
189 $$->class = SPECIFIER ;
192 | NONBANKED {$$ = newLink ();
193 $$->class = SPECIFIER ;
194 SPEC_NONBANKED($$) = 1;
195 if (SPEC_BANKED($$)) {
196 werror(W_BANKED_WITH_NONBANKED);
199 | BANKED {$$ = newLink ();
200 $$->class = SPECIFIER ;
202 if (SPEC_NONBANKED($$)) {
203 werror(W_BANKED_WITH_NONBANKED);
206 werror(W_BANKED_WITH_STATIC);
212 $$->class = SPECIFIER ;
220 | declaration_list compound_statement
222 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
228 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
229 | CONSTANT { $$ = newAst_VALUE($1); }
231 | '(' expr ')' { $$ = $2 ; }
235 : STRING_LITERAL { $$ = newAst_VALUE($1); }
240 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
241 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
242 $$->left->funcName = 1;}
243 | postfix_expr '(' argument_expr_list ')'
245 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
247 | postfix_expr '.' identifier
249 $3 = newSymbol($3->name,NestLevel);
251 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
252 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
254 | postfix_expr PTR_OP identifier
256 $3 = newSymbol($3->name,NestLevel);
258 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
260 | postfix_expr INC_OP
261 { $$ = newNode(INC_OP,$1,NULL);}
262 | postfix_expr DEC_OP
263 { $$ = newNode(DEC_OP,$1,NULL); }
268 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
273 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
274 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
275 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
276 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
277 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
291 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
296 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
297 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
298 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
302 : multiplicative_expr
303 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
304 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
309 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
310 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
315 | relational_expr '<' shift_expr {
317 newNode('!',newNode(GE_OP,$1,$3),NULL) :
318 newNode('<', $1,$3));
320 | relational_expr '>' shift_expr {
322 newNode('!',newNode(LE_OP,$1,$3),NULL) :
325 | relational_expr LE_OP shift_expr {
327 newNode('!', newNode('>', $1 , $3 ), NULL) :
328 newNode(LE_OP,$1,$3));
330 | relational_expr GE_OP shift_expr {
332 newNode('!', newNode('<', $1 , $3 ), NULL) :
333 newNode(GE_OP,$1,$3));
339 | equality_expr EQ_OP relational_expr {
341 newNode('!',newNode(NE_OP,$1,$3),NULL) :
342 newNode(EQ_OP,$1,$3));
344 | equality_expr NE_OP relational_expr {
346 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
347 newNode(NE_OP,$1,$3));
353 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
358 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
363 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
368 | logical_and_expr AND_OP inclusive_or_expr
369 { $$ = newNode(AND_OP,$1,$3);}
374 | logical_or_expr OR_OP logical_and_expr
375 { $$ = newNode(OR_OP,$1,$3); }
380 | logical_or_expr '?' logical_or_expr ':' conditional_expr
382 $$ = newNode(':',$3,$5) ;
383 $$ = newNode('?',$1,$$) ;
389 | unary_expr assignment_operator assignment_expr
394 $$ = newNode($2,$1,$3);
397 $$ = newNode('=',$1,newNode('*',copyAst($1),$3));
400 $$ = newNode('=',$1,newNode('/',copyAst($1),$3));
403 $$ = newNode('=',$1,newNode('%',copyAst($1),$3));
406 $$ = newNode('=',$1,newNode('+',copyAst($1),$3));
409 $$ = newNode('=',$1,newNode('-',copyAst($1),$3));
412 $$ = newNode('=',$1,newNode(LEFT_OP,copyAst($1),$3));
415 $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3));
418 $$ = newNode('=',$1,newNode('&',copyAst($1),$3));
421 $$ = newNode('=',$1,newNode('^',copyAst($1),$3));
424 $$ = newNode('=',$1,newNode('|',copyAst($1),$3));
449 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
457 : declaration_specifiers ';' { $$ = NULL ; }
458 | declaration_specifiers init_declarator_list ';'
460 /* add the specifier list to the id */
463 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
464 sym_link *lnk = copyLinkChain($1);
465 /* do the pointer stuff */
466 pointerTypes(sym->type,lnk);
467 addDecl (sym,0,lnk) ;
474 declaration_specifiers
475 : storage_class_specifier { $$ = $1; }
476 | storage_class_specifier declaration_specifiers {
477 /* if the decl $2 is not a specifier */
478 /* find the spec and replace it */
481 while (lnk && !IS_SPEC(lnk->next))
483 lnk->next = mergeSpec($1,lnk->next, yytext);
487 $$ = mergeSpec($1,$2, yytext);
489 | type_specifier { $$ = $1; }
490 | type_specifier declaration_specifiers {
491 /* if the decl $2 is not a specifier */
492 /* find the spec and replace it */
495 while (lnk && !IS_SPEC(lnk->next))
497 lnk->next = mergeSpec($1,lnk->next, yytext);
501 $$ = mergeSpec($1,$2, yytext);
507 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
511 : declarator { $1->ival = NULL ; }
512 | declarator '=' initializer { $1->ival = $3 ; }
516 storage_class_specifier
519 $$->class = SPECIFIER ;
520 SPEC_TYPEDEF($$) = 1 ;
524 $$->class = SPECIFIER ;
529 $$->class = SPECIFIER ;
534 $$->class = SPECIFIER ;
535 SPEC_SCLS($$) = S_AUTO ;
539 $$->class = SPECIFIER ;
540 SPEC_SCLS($$) = S_REGISTER ;
545 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
550 | type_specifier2 AT constant_expr
552 /* add this to the storage class specifier */
553 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
554 /* now get the abs addr from value */
555 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
562 $$->class = SPECIFIER ;
563 SPEC_NOUN($$) = V_CHAR ;
567 $$->class = SPECIFIER ;
568 $$->select.s._short = 1 ;
572 $$->class = SPECIFIER ;
573 SPEC_NOUN($$) = V_INT ;
577 $$->class = SPECIFIER ;
582 $$->class = SPECIFIER ;
583 $$->select.s._signed = 1;
587 $$->class = SPECIFIER ;
592 $$->class = SPECIFIER ;
593 SPEC_NOUN($$) = V_VOID ;
597 $$->class = SPECIFIER ;
602 $$->class = SPECIFIER ;
603 SPEC_VOLATILE($$) = 1 ;
607 SPEC_NOUN($$) = V_FLOAT;
608 $$->class = SPECIFIER ;
612 $$->class = SPECIFIER ;
613 SPEC_SCLS($$) = S_XDATA ;
617 $$->class = SPECIFIER ;
618 SPEC_SCLS($$) = S_CODE ;
622 $$->class = SPECIFIER ;
623 SPEC_SCLS($$) = S_EEPROM ;
627 $$->class = SPECIFIER ;
628 SPEC_SCLS($$) = S_DATA ;
632 $$->class = SPECIFIER ;
633 SPEC_SCLS($$) = S_IDATA ;
637 $$->class = SPECIFIER ;
638 SPEC_SCLS($$) = S_PDATA ;
642 $$->class = SPECIFIER ;
643 SPEC_NOUN($$) = V_BIT ;
644 SPEC_SCLS($$) = S_BIT ;
649 | struct_or_union_specifier
658 sym = findSym(TypedefTab,NULL,$1) ;
659 $$ = p = copyLinkChain(sym->type);
660 SPEC_TYPEDEF(getSpec(p)) = 0;
668 $$->class = SPECIFIER ;
669 SPEC_NOUN($$) = V_SBIT;
670 SPEC_SCLS($$) = S_SBIT;
674 $$->class = SPECIFIER ;
675 SPEC_NOUN($$) = V_CHAR;
676 SPEC_SCLS($$) = S_SFR ;
681 struct_or_union_specifier
682 : struct_or_union opt_stag '{' struct_declaration_list '}'
686 /* Create a structdef */
688 sdef->fields = reverseSyms($4) ; /* link the fields */
689 sdef->size = compStructSize($1,sdef); /* update size of */
691 /* Create the specifier */
693 $$->class = SPECIFIER ;
694 SPEC_NOUN($$) = V_STRUCT;
695 SPEC_STRUCT($$)= sdef ;
697 | struct_or_union stag
700 $$->class = SPECIFIER ;
701 SPEC_NOUN($$) = V_STRUCT;
702 SPEC_STRUCT($$) = $2 ;
707 : STRUCT { $$ = STRUCT ; }
708 | UNION { $$ = UNION ; }
713 | { /* synthesize a name add to structtable */
714 $$ = newStruct(genSymName(NestLevel)) ;
715 $$->level = NestLevel ;
716 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
720 : identifier { /* add name to structure table */
721 $$ = findSymWithBlock (StructTab,$1,currBlockno);
723 $$ = newStruct($1->name) ;
724 $$->level = NestLevel ;
725 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
730 struct_declaration_list
732 | struct_declaration_list struct_declaration
735 /* go to the end of the chain */
736 while (sym->next) sym = sym->next;
744 : type_specifier_list struct_declarator_list ';'
746 /* add this type to all the symbols */
748 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
750 pointerTypes(sym->type,copyLinkChain($1));
752 sym->type = copyLinkChain($1);
753 sym->etype = getSpec(sym->type);
754 /* make sure the type is complete and sane */
755 checkTypeSanity(sym->etype, sym->name);
758 addDecl (sym,0,cloneSpec($1));
764 struct_declarator_list
766 | struct_declarator_list ',' struct_declarator
775 | ':' constant_expr {
776 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
777 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
779 | declarator ':' constant_expr
781 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
786 : ENUM '{' enumerator_list '}' {
788 allocVariables(reverseSyms($3)) ;
789 $$ = copyLinkChain(cenum->type);
791 | ENUM identifier '{' enumerator_list '}' {
794 $2->type = copyLinkChain(cenum->type);
795 $2->etype = getSpec($2->type);
796 /* add this to the enumerator table */
797 if (!(csym=findSym(enumTab,$2,$2->name)) &&
798 (csym && csym->level == $2->level))
799 werror(E_DUPLICATE_TYPEDEF,csym->name);
801 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
803 allocVariables (reverseSyms($4));
804 $$ = copyLinkChain(cenum->type);
805 SPEC_SCLS(getSpec($$)) = 0 ;
810 /* check the enumerator table */
811 if ((csym = findSym(enumTab,$2,$2->name)))
812 $$ = copyLinkChain(csym->type);
815 $$->class = SPECIFIER ;
816 SPEC_NOUN($$) = V_INT ;
819 SPEC_SCLS(getSpec($$)) = 0 ;
825 | enumerator_list ',' {
827 | enumerator_list ',' enumerator {
834 : identifier opt_assign_expr {
835 /* make the symbol one level up */
837 $1->type = copyLinkChain($2->type);
838 $1->etype= getSpec($1->type);
839 SPEC_ENUM($1->etype) = 1;
846 : '=' constant_expr {
849 val = constExprValue($2,TRUE);
854 sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
855 $$ = cenum = constVal(lbuff);
858 sprintf(lbuff,"%d",0);
859 $$ = cenum = constVal(lbuff);
865 : declarator2_using_reentrant { $$ = $1; }
866 | pointer declarator2_using_reentrant
868 addDecl ($2,0,reverseLink($1));
873 declarator2_using_reentrant
874 : declarator2 { $$ = $1 ; }
875 | declarator2 using_reentrant { addDecl ($1,0,$2); }
880 | '(' declarator ')' { $$ = $2; }
881 | declarator2 '[' ']'
886 DCL_TYPE(p) = ARRAY ;
890 | declarator2 '[' constant_expr ']'
895 p = (tval = constExprValue($3,TRUE))->etype;
896 /* if it is not a constant then Error */
897 if ( SPEC_SCLS(p) != S_LITERAL)
898 werror(E_CONST_EXPECTED) ;
901 DCL_TYPE(p) = ARRAY ;
902 DCL_ELEM(p) = (int) floatFromVal(tval) ;
906 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
907 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
910 addDecl ($1,FUNCTION,NULL) ;
912 $1->hasVargs = IS_VARG($4);
913 $1->args = reverseVal($4) ;
915 /* nest level was incremented to take care of the parms */
920 | declarator2 '(' parameter_identifier_list ')'
922 werror(E_OLD_STYLE,$1->name) ;
924 /* assume it returns an int */
925 $1->type = $1->etype = newIntLink();
931 : far_near_pointer { $$ = $1 ;}
932 | far_near_pointer type_specifier_list
937 | far_near_pointer pointer
942 | far_near_pointer type_specifier_list pointer
945 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
946 DCL_PTR_CONST($1) = SPEC_CONST($2);
947 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
948 switch (SPEC_SCLS($2)) {
950 DCL_TYPE($3) = FPOINTER;
953 DCL_TYPE($3) = IPOINTER ;
956 DCL_TYPE($3) = PPOINTER ;
959 DCL_TYPE($3) = POINTER ;
962 DCL_PTR_CONST($3) = 1;
963 DCL_TYPE($3) = CPOINTER ;
965 DCL_TYPE($3) = EEPPOINTER;
968 werror(W_PTR_TYPE_INVALID);
972 werror (W_PTR_TYPE_INVALID);
981 DCL_TYPE($$) = POINTER ;
989 : _XDATA { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; }
990 | _CODE { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ; DCL_PTR_CONST($$) = 1;}
991 | _PDATA { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; }
992 | _IDATA { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; }
993 | _NEAR { $$ = NULL ; }
994 | _GENERIC { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; }
995 | _EEPROM { $$ = newLink() ; DCL_TYPE($$) = EEPPOINTER ;}
996 | { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; }
1001 | type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1004 parameter_identifier_list
1006 | identifier_list ',' ELIPSIS
1011 | identifier_list ',' identifier
1020 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1024 : parameter_declaration
1025 | parameter_list ',' parameter_declaration
1032 parameter_declaration
1033 : type_specifier_list declarator
1036 pointerTypes($2->type,$1);
1038 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1045 $$->etype = getSpec($$->type);
1050 : type_specifier_list { $$ = $1 ;}
1051 | type_specifier_list abstract_declarator
1053 /* go to the end of the list */
1055 pointerTypes($2,$1);
1056 for ( p = $2 ; p->next ; p=p->next);
1063 : pointer { $$ = reverseLink($1); }
1064 | abstract_declarator2
1065 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1068 abstract_declarator2
1069 : '(' abstract_declarator ')' { $$ = $2 ; }
1072 DCL_TYPE($$) = ARRAY ;
1075 | '[' constant_expr ']' {
1078 DCL_TYPE($$) = ARRAY ;
1079 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1081 | abstract_declarator2 '[' ']' {
1083 DCL_TYPE($$) = ARRAY ;
1087 | abstract_declarator2 '[' constant_expr ']'
1091 DCL_TYPE($$) = ARRAY ;
1092 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1095 | '(' ')' { $$ = NULL;}
1096 | '(' parameter_type_list ')' { $$ = NULL;}
1097 | abstract_declarator2 '(' ')'
1098 | abstract_declarator2 '(' parameter_type_list ')'
1102 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1103 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1104 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1109 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1114 | compound_statement
1115 | expression_statement
1116 | selection_statement
1117 | iteration_statement
1120 ast *ex = newNode(INLINEASM,NULL,NULL);
1121 ex->values.inlineasm = Safe_calloc(1,strlen($1)+1);
1122 strcpy(ex->values.inlineasm,$1);
1128 : identifier ':' statement { $$ = createLabel($1,$3); }
1129 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1130 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1133 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1136 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1140 : start_block end_block { $$ = createBlock(NULL,NULL); }
1141 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1143 declaration_list { addSymChain($2); }
1144 end_block { $$ = createBlock($2,NULL) ; }
1146 declaration_list { addSymChain ($2); }
1148 end_block {$$ = createBlock($2,$4) ; }
1149 | error ';' { $$ = NULL ; }
1155 /* if this is typedef declare it immediately */
1156 if ( $1 && IS_TYPEDEF($1->etype)) {
1157 allocVariables ($1);
1164 | declaration_list declaration
1168 /* if this is a typedef */
1169 if ($2 && IS_TYPEDEF($2->etype)) {
1170 allocVariables ($2);
1174 /* get to the end of the previous decl */
1189 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1192 expression_statement
1198 : ELSE statement { $$ = $2 ; }
1204 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1205 | SWITCH '(' expr ')' {
1207 static int swLabel = 0 ;
1209 /* create a node for expression */
1210 ex = newNode(SWITCH,$3,NULL);
1211 STACK_PUSH(swStk,ex); /* save it in the stack */
1212 ex->values.switchVals.swNum = swLabel ;
1214 /* now create the label */
1215 sprintf(lbuff,"_swBrk_%d",swLabel++);
1216 $<sym>$ = newSymbol(lbuff,NestLevel);
1217 /* put label in the break stack */
1218 STACK_PUSH(breakStack,$<sym>$);
1221 /* get back the switch form the stack */
1222 $$ = STACK_POP(swStk) ;
1223 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1224 STACK_POP(breakStack);
1228 while : WHILE { /* create and push the continue , break & body labels */
1229 static int Lblnum = 0 ;
1231 sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1232 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1234 sprintf (lbuff,"_whilebreak_%d",Lblnum);
1235 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1237 sprintf (lbuff,"_whilebody_%d",Lblnum++);
1238 $$ = newSymbol(lbuff,NestLevel);
1241 do : DO { /* create and push the continue , break & body Labels */
1242 static int Lblnum = 0 ;
1245 sprintf(lbuff,"_docontinue_%d",Lblnum);
1246 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1248 sprintf (lbuff,"_dobreak_%d",Lblnum);
1249 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1251 sprintf (lbuff,"_dobody_%d",Lblnum++);
1252 $$ = newSymbol (lbuff,NestLevel);
1254 for : FOR { /* create & push continue, break & body labels */
1255 static int Lblnum = 0 ;
1258 sprintf (lbuff,"_forcontinue_%d",Lblnum);
1259 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1261 sprintf (lbuff,"_forbreak_%d",Lblnum);
1262 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1264 sprintf (lbuff,"_forbody_%d",Lblnum);
1265 $$ = newSymbol(lbuff,NestLevel);
1267 sprintf (lbuff,"_forcond_%d",Lblnum++);
1268 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1272 : while '(' expr ')' statement
1275 $$ = createWhile ( $1, STACK_POP(continueStack),
1276 STACK_POP(breakStack), $3, $5 );
1277 $$->lineno = $1->lineDef ;
1280 | do statement WHILE '(' expr ')' ';'
1283 $$ = createDo ( $1 , STACK_POP(continueStack),
1284 STACK_POP(breakStack), $5, $2);
1285 $$->lineno = $1->lineDef ;
1288 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1292 /* if break or continue statement present
1293 then create a general case loop */
1294 if (STACK_PEEK(continueStack)->isref ||
1295 STACK_PEEK(breakStack)->isref) {
1296 $$ = createFor ($1, STACK_POP(continueStack),
1297 STACK_POP(breakStack) ,
1298 STACK_POP(forStack) ,
1301 $$ = newNode(FOR,$9,NULL);
1302 AST_FOR($$,trueLabel) = $1;
1303 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1304 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1305 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1306 AST_FOR($$,initExpr) = $3;
1307 AST_FOR($$,condExpr) = $5;
1308 AST_FOR($$,loopExpr) = $7;
1321 : GOTO identifier ';' {
1323 $$ = newAst_VALUE(symbolVal($2));
1324 $$ = newNode(GOTO,$$,NULL);
1327 /* make sure continue is in context */
1328 if (STACK_PEEK(continueStack) == NULL) {
1329 werror(E_BREAK_CONTEXT);
1333 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1334 $$ = newNode(GOTO,$$,NULL);
1335 /* mark the continue label as referenced */
1336 STACK_PEEK(continueStack)->isref = 1;
1340 if (STACK_PEEK(breakStack) == NULL) {
1341 werror(E_BREAK_CONTEXT);
1344 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1345 $$ = newNode(GOTO,$$,NULL);
1346 STACK_PEEK(breakStack)->isref = 1;
1349 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1350 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1354 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }