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"
37 extern int yyerror (char *);
39 int NestLevel = 0 ; /* current NestLevel */
40 int stackPtr = 1 ; /* stack pointer */
41 int xstackPtr = 0 ; /* xstack pointer */
43 int blockNo = 0 ; /* sequential block number */
48 char lbuff[1024]; /* local buffer */
50 /* break & continue stacks */
51 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
52 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
53 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
54 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
55 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
57 value *cenum = NULL ; /* current enumeration type chain*/
61 symbol *sym ; /* symbol table pointer */
62 structdef *sdef; /* structure definition */
63 char yychar[SDCC_NAME_MAX+1];
64 sym_link *lnk ; /* declarator or specifier */
65 int yyint; /* integer value returned */
66 value *val ; /* for integer constant */
67 initList *ilist; /* initial list */
68 char yyinline[MAX_INLINEASM]; /* inlined assembler code */
69 ast *asts; /* expression tree */
72 %token <yychar> IDENTIFIER TYPE_NAME
73 %token <val> CONSTANT STRING_LITERAL
75 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
77 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
78 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
79 %token <yyint> XOR_ASSIGN OR_ASSIGN
80 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
81 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
82 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
83 %token STRUCT UNION ENUM ELIPSIS RANGE FAR _XDATA _CODE _GENERIC _NEAR _PDATA _IDATA _EEPROM
84 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
85 %token <yyinline> INLINEASM
86 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
87 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
89 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND
91 %type <yyint> Interrupt_storage
92 %type <sym> identifier declarator declarator2 enumerator_list enumerator
93 %type <sym> struct_declarator
94 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
95 %type <sym> declaration init_declarator_list init_declarator
96 %type <sym> declaration_list identifier_list parameter_identifier_list
97 %type <sym> declarator2_using_reentrant while do for
98 %type <lnk> pointer type_specifier_list type_specifier type_name
99 %type <lnk> storage_class_specifier struct_or_union_specifier
100 %type <lnk> declaration_specifiers sfr_reg_bit type_specifier2
101 %type <lnk> using_reentrant using_reentrant_interrupt enum_specifier
102 %type <lnk> abstract_declarator abstract_declarator2 far_near_pointer far_near
103 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
104 %type <sdef> stag opt_stag
105 %type <asts> primary_expr
106 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
107 %type <asts> additive_expr shift_expr relational_expr equality_expr
108 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
109 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
110 %type <asts> expr argument_expr_list function_definition expr_opt
111 %type <asts> statement_list statement labeled_statement compound_statement
112 %type <asts> expression_statement selection_statement iteration_statement
113 %type <asts> jump_statement function_body else_statement string_literal
114 %type <ilist> initializer initializer_list
115 %type <yyint> unary_operator assignment_operator struct_or_union
122 : external_definition
123 | file external_definition
127 : function_definition { blockNo=0;}
130 && IS_FUNC($1->type))
132 /* The only legal storage classes for
133 * a function prototype (declaration)
134 * are extern and static. extern is the
135 * default. Thus, if this function isn't
136 * explicitly marked static, mark it
140 && IS_SPEC($1->etype)
141 && !SPEC_STAT($1->etype))
143 SPEC_EXTR($1->etype) = 1;
147 allocVariables ($1) ;
148 cleanUpLevel (SymbolTab,1);
153 : declarator function_body { /* function type not specified */
154 /* assume it to be 'int' */
155 addDecl($1,0,newIntLink());
156 $$ = createFunction($1,$2);
158 | declaration_specifiers declarator function_body
160 pointerTypes($2->type,copyLinkChain($1));
162 $$ = createFunction($2,$3);
167 : using_reentrant_interrupt
168 | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2); }
171 using_reentrant_interrupt
174 $$->class = SPECIFIER ;
176 SPEC_BANK($$) = (int) floatFromVal($2);
178 | REENTRANT { $$ = newLink ();
179 $$->class = SPECIFIER ;
182 | CRITICAL { $$ = newLink ();
183 $$->class = SPECIFIER ;
186 | NONBANKED {$$ = newLink ();
187 $$->class = SPECIFIER ;
188 SPEC_NONBANKED($$) = 1;
189 if (SPEC_BANKED($$)) {
190 werror(W_BANKED_WITH_NONBANKED);
193 | BANKED {$$ = newLink ();
194 $$->class = SPECIFIER ;
196 if (SPEC_NONBANKED($$)) {
197 werror(W_BANKED_WITH_NONBANKED);
200 werror(W_BANKED_WITH_STATIC);
206 $$->class = SPECIFIER ;
214 | declaration_list compound_statement
216 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
222 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
223 | CONSTANT { $$ = newAst_VALUE($1); }
225 | '(' expr ')' { $$ = $2 ; }
229 : STRING_LITERAL { $$ = newAst_VALUE($1); }
234 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
235 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
236 $$->left->funcName = 1;}
237 | postfix_expr '(' argument_expr_list ')'
239 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
241 | postfix_expr '.' identifier
243 $3 = newSymbol($3->name,NestLevel);
245 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
246 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
248 | postfix_expr PTR_OP identifier
250 $3 = newSymbol($3->name,NestLevel);
252 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
254 | postfix_expr INC_OP
255 { $$ = newNode(INC_OP,$1,NULL);}
256 | postfix_expr DEC_OP
257 { $$ = newNode(DEC_OP,$1,NULL); }
262 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
267 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
268 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
269 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
270 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
271 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
285 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
290 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
291 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
292 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
296 : multiplicative_expr
297 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
298 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
303 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
304 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
309 | relational_expr '<' shift_expr {
311 newNode('!',newNode(GE_OP,$1,$3),NULL) :
312 newNode('<', $1,$3));
314 | relational_expr '>' shift_expr {
316 newNode('!',newNode(LE_OP,$1,$3),NULL) :
319 | relational_expr LE_OP shift_expr {
321 newNode('!', newNode('>', $1 , $3 ), NULL) :
322 newNode(LE_OP,$1,$3));
324 | relational_expr GE_OP shift_expr {
326 newNode('!', newNode('<', $1 , $3 ), NULL) :
327 newNode(GE_OP,$1,$3));
333 | equality_expr EQ_OP relational_expr {
335 newNode('!',newNode(NE_OP,$1,$3),NULL) :
336 newNode(EQ_OP,$1,$3));
338 | equality_expr NE_OP relational_expr {
340 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
341 newNode(NE_OP,$1,$3));
347 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
352 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
357 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
362 | logical_and_expr AND_OP inclusive_or_expr
363 { $$ = newNode(AND_OP,$1,$3);}
368 | logical_or_expr OR_OP logical_and_expr
369 { $$ = newNode(OR_OP,$1,$3); }
374 | logical_or_expr '?' logical_or_expr ':' conditional_expr
376 $$ = newNode(':',$3,$5) ;
377 $$ = newNode('?',$1,$$) ;
383 | unary_expr assignment_operator assignment_expr
388 $$ = newNode($2,$1,$3);
391 $$ = newNode('=',$1,newNode('*',copyAst($1),$3));
394 $$ = newNode('=',$1,newNode('/',copyAst($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(LEFT_OP,copyAst($1),$3));
409 $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3));
412 $$ = newNode('=',$1,newNode('&',copyAst($1),$3));
415 $$ = newNode('=',$1,newNode('^',copyAst($1),$3));
418 $$ = newNode('=',$1,newNode('|',copyAst($1),$3));
443 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
451 : declaration_specifiers ';' { $$ = NULL ; }
452 | declaration_specifiers init_declarator_list ';'
454 /* add the specifier list to the id */
457 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
458 sym_link *lnk = copyLinkChain($1);
459 /* do the pointer stuff */
460 pointerTypes(sym->type,lnk);
461 addDecl (sym,0,lnk) ;
468 declaration_specifiers
469 : storage_class_specifier { $$ = $1; }
470 | storage_class_specifier declaration_specifiers {
471 /* if the decl $2 is not a specifier */
472 /* find the spec and replace it */
475 while (lnk && !IS_SPEC(lnk->next))
477 lnk->next = mergeSpec($1,lnk->next);
481 $$ = mergeSpec($1,$2);
483 | type_specifier { $$ = $1; }
484 | type_specifier declaration_specifiers {
485 /* if the decl $2 is not a specifier */
486 /* find the spec and replace it */
489 while (lnk && !IS_SPEC(lnk->next))
491 lnk->next = mergeSpec($1,lnk->next);
495 $$ = mergeSpec($1,$2);
501 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
505 : declarator { $1->ival = NULL ; }
506 | declarator '=' initializer { $1->ival = $3 ; }
510 storage_class_specifier
513 $$->class = SPECIFIER ;
514 SPEC_TYPEDEF($$) = 1 ;
518 $$->class = SPECIFIER ;
523 $$->class = SPECIFIER ;
528 $$->class = SPECIFIER ;
529 SPEC_SCLS($$) = S_AUTO ;
533 $$->class = SPECIFIER ;
534 SPEC_SCLS($$) = S_REGISTER ;
539 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
544 | type_specifier2 AT constant_expr
546 /* add this to the storage class specifier */
547 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
548 /* now get the abs addr from value */
549 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
556 $$->class = SPECIFIER ;
557 SPEC_NOUN($$) = V_CHAR ;
561 $$->class = SPECIFIER ;
567 $$->class = SPECIFIER ;
568 SPEC_NOUN($$) = V_INT ;
572 $$->class = SPECIFIER ;
578 $$->class = SPECIFIER ;
583 $$->class = SPECIFIER ;
588 $$->class = SPECIFIER ;
589 SPEC_NOUN($$) = V_VOID ;
593 $$->class = SPECIFIER ;
594 SPEC_SCLS($$) = S_CONSTANT ;
599 $$->class = SPECIFIER ;
600 SPEC_VOLATILE($$) = 1 ;
604 SPEC_NOUN($$) = V_FLOAT;
605 $$->class = SPECIFIER ;
609 $$->class = SPECIFIER ;
610 SPEC_SCLS($$) = S_XDATA ;
614 $$->class = SPECIFIER ;
615 SPEC_SCLS($$) = S_CODE ;
619 $$->class = SPECIFIER ;
620 SPEC_SCLS($$) = S_EEPROM ;
624 $$->class = SPECIFIER ;
625 SPEC_SCLS($$) = S_DATA ;
629 $$->class = SPECIFIER ;
630 SPEC_SCLS($$) = S_IDATA ;
634 $$->class = SPECIFIER ;
635 SPEC_SCLS($$) = S_PDATA ;
639 $$->class = SPECIFIER ;
640 SPEC_NOUN($$) = V_BIT ;
641 SPEC_SCLS($$) = S_BIT ;
646 | struct_or_union_specifier
656 sym = findSym(TypedefTab,NULL,$1) ;
657 $$ = p = copyLinkChain(sym->type);
658 SPEC_TYPEDEF(getSpec(p)) = 0;
666 $$->class = SPECIFIER ;
667 SPEC_NOUN($$) = V_SBIT;
668 SPEC_SCLS($$) = S_SBIT;
672 $$->class = SPECIFIER ;
673 SPEC_NOUN($$) = V_CHAR;
674 SPEC_SCLS($$) = S_SFR ;
679 struct_or_union_specifier
680 : struct_or_union opt_stag '{' struct_declaration_list '}'
684 /* Create a structdef */
686 sdef->fields = reverseSyms($4) ; /* link the fields */
687 sdef->size = compStructSize($1,sdef); /* update size of */
689 /* Create the specifier */
691 $$->class = SPECIFIER ;
692 SPEC_NOUN($$) = V_STRUCT;
693 SPEC_STRUCT($$)= sdef ;
695 | struct_or_union stag
698 $$->class = SPECIFIER ;
699 SPEC_NOUN($$) = V_STRUCT;
700 SPEC_STRUCT($$) = $2 ;
705 : STRUCT { $$ = STRUCT ; }
706 | UNION { $$ = UNION ; }
711 | { /* synthesize a name add to structtable */
712 $$ = newStruct(genSymName(NestLevel)) ;
713 $$->level = NestLevel ;
714 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
719 : identifier { /* add name to structure table */
720 $$ = findSymWithBlock (StructTab,$1,currBlockno);
722 $$ = newStruct($1->name) ;
723 $$->level = NestLevel ;
724 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
729 struct_declaration_list
731 | struct_declaration_list struct_declaration
734 /* go to the end of the chain */
735 while (sym->next) sym = sym->next;
743 : type_specifier_list struct_declarator_list ';'
745 /* add this type to all the symbols */
747 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
749 pointerTypes(sym->type,copyLinkChain($1));
751 sym->type = copyLinkChain($1);
752 sym->etype = getSpec(sym->type);
755 addDecl (sym,0,cloneSpec($1));
762 struct_declarator_list
764 | struct_declarator_list ',' struct_declarator
773 | ':' constant_expr {
774 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
775 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
777 | declarator ':' constant_expr
779 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
784 : ENUM '{' enumerator_list '}' {
786 allocVariables(reverseSyms($3)) ;
787 $$ = copyLinkChain(cenum->type);
789 | ENUM identifier '{' enumerator_list '}' {
792 $2->type = copyLinkChain(cenum->type);
793 $2->etype = getSpec($2->type);
794 /* add this to the enumerator table */
795 if (!(csym=findSym(enumTab,$2,$2->name)) &&
796 (csym && csym->level == $2->level))
797 werror(E_DUPLICATE_TYPEDEF,csym->name);
799 addSym ( enumTab,$2,$2->name,$2->level,$2->block);
801 allocVariables (reverseSyms($4));
802 $$ = copyLinkChain(cenum->type);
803 SPEC_SCLS(getSpec($$)) = 0 ;
808 /* check the enumerator table */
809 if ((csym = findSym(enumTab,$2,$2->name)))
810 $$ = copyLinkChain(csym->type);
813 $$->class = SPECIFIER ;
814 SPEC_NOUN($$) = V_INT ;
817 SPEC_SCLS(getSpec($$)) = 0 ;
823 | enumerator_list ',' enumerator {
830 : identifier opt_assign_expr {
831 /* make the symbol one level up */
833 $1->type = copyLinkChain($2->type);
834 $1->etype= getSpec($1->type);
835 SPEC_ENUM($1->etype) = 1;
842 : '=' constant_expr {
845 val = constExprValue($2,TRUE);
850 sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
851 $$ = cenum = constVal(lbuff);
854 sprintf(lbuff,"%d",0);
855 $$ = cenum = constVal(lbuff);
861 : declarator2_using_reentrant { $$ = $1; }
862 | pointer declarator2_using_reentrant
864 addDecl ($2,0,reverseLink($1));
869 declarator2_using_reentrant
870 : declarator2 { $$ = $1 ; }
871 | declarator2 using_reentrant { addDecl ($1,0,$2); }
876 | '(' declarator ')' { $$ = $2; }
877 | declarator2 '[' ']'
882 DCL_TYPE(p) = ARRAY ;
886 | declarator2 '[' constant_expr ']'
891 p = (tval = constExprValue($3,TRUE))->etype;
892 /* if it is not a constant then Error */
893 if ( SPEC_SCLS(p) != S_LITERAL)
894 werror(E_CONST_EXPECTED) ;
897 DCL_TYPE(p) = ARRAY ;
898 DCL_ELEM(p) = (int) floatFromVal(tval) ;
902 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
903 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
906 addDecl ($1,FUNCTION,NULL) ;
908 $1->hasVargs = IS_VARG($4);
909 $1->args = reverseVal($4) ;
911 /* nest level was incremented to take care of the parms */
916 | declarator2 '(' parameter_identifier_list ')'
918 werror(E_OLD_STYLE,$1->name) ;
920 /* assume it returns an it */
921 $1->type = $1->etype = newIntLink();
927 : far_near_pointer { $$ = $1 ;}
928 | far_near_pointer type_specifier_list
933 | far_near_pointer pointer
938 | far_near_pointer type_specifier_list pointer
941 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
942 DCL_PTR_CONST($1) = SPEC_CONST($2);
943 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
944 switch (SPEC_SCLS($2)) {
946 DCL_TYPE($3) = FPOINTER;
949 DCL_TYPE($3) = IPOINTER ;
952 DCL_TYPE($3) = PPOINTER ;
955 DCL_TYPE($3) = POINTER ;
958 DCL_PTR_CONST($3) = 1;
959 DCL_TYPE($3) = CPOINTER ;
961 DCL_TYPE($3) = EEPPOINTER;
964 werror(W_PTR_TYPE_INVALID);
968 werror (W_PTR_TYPE_INVALID);
977 DCL_TYPE($$) = POINTER ;
985 : _XDATA { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; }
986 | _CODE { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ; DCL_PTR_CONST($$) = 1;}
987 | _PDATA { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; }
988 | _IDATA { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; }
989 | _NEAR { $$ = NULL ; }
990 | _GENERIC { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; }
991 | _EEPROM { $$ = newLink() ; DCL_TYPE($$) = EEPPOINTER ;}
992 | { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; }
997 | type_specifier_list type_specifier { $$ = mergeSpec ($1,$2); }
1000 parameter_identifier_list
1002 | identifier_list ',' ELIPSIS
1007 | identifier_list ',' identifier
1016 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1020 : parameter_declaration
1021 | parameter_list ',' parameter_declaration
1028 parameter_declaration
1029 : type_specifier_list declarator
1032 pointerTypes($2->type,$1);
1034 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1041 $$->etype = getSpec($$->type);
1046 : type_specifier_list { $$ = $1 ;}
1047 | type_specifier_list abstract_declarator
1049 /* go to the end of the list */
1051 pointerTypes($2,$1);
1052 for ( p = $2 ; p->next ; p=p->next);
1059 : pointer { $$ = reverseLink($1); }
1060 | abstract_declarator2
1061 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1064 abstract_declarator2
1065 : '(' abstract_declarator ')' { $$ = $2 ; }
1068 DCL_TYPE($$) = ARRAY ;
1071 | '[' constant_expr ']' {
1074 DCL_TYPE($$) = ARRAY ;
1075 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1077 | abstract_declarator2 '[' ']' {
1079 DCL_TYPE($$) = ARRAY ;
1083 | abstract_declarator2 '[' constant_expr ']'
1087 DCL_TYPE($$) = ARRAY ;
1088 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1091 | '(' ')' { $$ = NULL;}
1092 | '(' parameter_type_list ')' { $$ = NULL;}
1093 | abstract_declarator2 '(' ')'
1094 | abstract_declarator2 '(' parameter_type_list ')'
1098 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1099 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1100 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1105 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1110 | compound_statement
1111 | expression_statement
1112 | selection_statement
1113 | iteration_statement
1116 ast *ex = newNode(INLINEASM,NULL,NULL);
1117 ex->values.inlineasm = Safe_calloc(strlen($1)+1);
1118 strcpy(ex->values.inlineasm,$1);
1124 : identifier ':' statement { $$ = createLabel($1,$3); }
1125 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1126 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1129 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1132 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1136 : start_block end_block { $$ = createBlock(NULL,NULL); }
1137 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1139 declaration_list { addSymChain($2); }
1140 end_block { $$ = createBlock($2,NULL) ; }
1142 declaration_list { addSymChain ($2); }
1144 end_block {$$ = createBlock($2,$4) ; }
1145 | error ';' { $$ = NULL ; }
1151 /* if this is typedef declare it immediately */
1152 if ( $1 && IS_TYPEDEF($1->etype)) {
1153 allocVariables ($1);
1160 | declaration_list declaration
1164 /* if this is a typedef */
1165 if ($2 && IS_TYPEDEF($2->etype)) {
1166 allocVariables ($2);
1170 /* get to the end of the previous decl */
1185 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1188 expression_statement
1194 : ELSE statement { $$ = $2 ; }
1200 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1201 | SWITCH '(' expr ')' {
1203 static int swLabel = 0 ;
1205 /* create a node for expression */
1206 ex = newNode(SWITCH,$3,NULL);
1207 STACK_PUSH(swStk,ex); /* save it in the stack */
1208 ex->values.switchVals.swNum = swLabel ;
1210 /* now create the label */
1211 sprintf(lbuff,"_swBrk_%d",swLabel++);
1212 $<sym>$ = newSymbol(lbuff,NestLevel);
1213 /* put label in the break stack */
1214 STACK_PUSH(breakStack,$<sym>$);
1217 /* get back the switch form the stack */
1218 $$ = STACK_POP(swStk) ;
1219 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1220 STACK_POP(breakStack);
1224 while : WHILE { /* create and push the continue , break & body labels */
1225 static int Lblnum = 0 ;
1227 sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1228 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1230 sprintf (lbuff,"_whilebreak_%d",Lblnum);
1231 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1233 sprintf (lbuff,"_whilebody_%d",Lblnum++);
1234 $$ = newSymbol(lbuff,NestLevel);
1237 do : DO { /* create and push the continue , break & body Labels */
1238 static int Lblnum = 0 ;
1241 sprintf(lbuff,"_docontinue_%d",Lblnum);
1242 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1244 sprintf (lbuff,"_dobreak_%d",Lblnum);
1245 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1247 sprintf (lbuff,"_dobody_%d",Lblnum++);
1248 $$ = newSymbol (lbuff,NestLevel);
1250 for : FOR { /* create & push continue, break & body labels */
1251 static int Lblnum = 0 ;
1254 sprintf (lbuff,"_forcontinue_%d",Lblnum);
1255 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1257 sprintf (lbuff,"_forbreak_%d",Lblnum);
1258 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1260 sprintf (lbuff,"_forbody_%d",Lblnum);
1261 $$ = newSymbol(lbuff,NestLevel);
1263 sprintf (lbuff,"_forcond_%d",Lblnum++);
1264 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1268 : while '(' expr ')' statement
1271 $$ = createWhile ( $1, STACK_POP(continueStack),
1272 STACK_POP(breakStack), $3, $5 );
1273 $$->lineno = $1->lineDef ;
1276 | do statement WHILE '(' expr ')' ';'
1279 $$ = createDo ( $1 , STACK_POP(continueStack),
1280 STACK_POP(breakStack), $5, $2);
1281 $$->lineno = $1->lineDef ;
1284 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1288 /* if break or continue statement present
1289 then create a general case loop */
1290 if (STACK_PEEK(continueStack)->isref ||
1291 STACK_PEEK(breakStack)->isref) {
1292 $$ = createFor ($1, STACK_POP(continueStack),
1293 STACK_POP(breakStack) ,
1294 STACK_POP(forStack) ,
1297 $$ = newNode(FOR,$9,NULL);
1298 AST_FOR($$,trueLabel) = $1;
1299 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1300 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1301 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1302 AST_FOR($$,initExpr) = $3;
1303 AST_FOR($$,condExpr) = $5;
1304 AST_FOR($$,loopExpr) = $7;
1317 : GOTO identifier ';' {
1319 $$ = newAst_VALUE(symbolVal($2));
1320 $$ = newNode(GOTO,$$,NULL);
1323 /* make sure continue is in context */
1324 if (STACK_PEEK(continueStack) == NULL) {
1325 werror(E_BREAK_CONTEXT);
1329 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1330 $$ = newNode(GOTO,$$,NULL);
1331 /* mark the continue label as referenced */
1332 STACK_PEEK(continueStack)->isref = 1;
1336 if (STACK_PEEK(breakStack) == NULL) {
1337 werror(E_BREAK_CONTEXT);
1340 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1341 $$ = newNode(GOTO,$$,NULL);
1342 STACK_PEEK(breakStack)->isref = 1;
1345 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1346 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1350 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }