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"
36 extern int yyerror (char *);
38 int NestLevel = 0 ; /* current NestLevel */
39 int stackPtr = 1 ; /* stack pointer */
40 int xstackPtr = 0 ; /* xstack pointer */
42 int blockNo = 0 ; /* sequential block number */
47 char lbuff[1024]; /* local buffer */
49 /* break & continue stacks */
50 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
51 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
52 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
53 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
54 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
56 value *cenum = NULL ; /* current enumeration type chain*/
60 symbol *sym ; /* symbol table pointer */
61 structdef *sdef; /* structure definition */
62 char yychar[SDCC_NAME_MAX+1];
63 link *lnk ; /* declarator or specifier */
64 int yyint; /* integer value returned */
65 value *val ; /* for integer constant */
66 initList *ilist; /* initial list */
67 char yyinline[MAX_INLINEASM]; /* inlined assembler code */
68 ast *asts; /* expression tree */
71 %token <yychar> IDENTIFIER TYPE_NAME
72 %token <val> CONSTANT STRING_LITERAL
74 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
76 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
77 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
78 %token <yyint> XOR_ASSIGN OR_ASSIGN
79 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
80 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
81 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
82 %token STRUCT UNION ENUM ELIPSIS RANGE FAR _XDATA _CODE _GENERIC _NEAR _PDATA _IDATA _EEPROM
83 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
84 %token <yyinline> INLINEASM
85 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
86 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
88 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND
90 %type <yyint> Interrupt_storage
91 %type <sym> identifier declarator declarator2 enumerator_list enumerator
92 %type <sym> struct_declarator
93 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
94 %type <sym> declaration init_declarator_list init_declarator
95 %type <sym> declaration_list identifier_list parameter_identifier_list
96 %type <sym> declarator2_using_reentrant while do for
97 %type <lnk> pointer type_specifier_list type_specifier type_name
98 %type <lnk> storage_class_specifier struct_or_union_specifier
99 %type <lnk> declaration_specifiers sfr_reg_bit type_specifier2
100 %type <lnk> using_reentrant using_reentrant_interrupt enum_specifier
101 %type <lnk> abstract_declarator abstract_declarator2 far_near_pointer far_near
102 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
103 %type <sdef> stag opt_stag
104 %type <asts> primary_expr
105 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
106 %type <asts> additive_expr shift_expr relational_expr equality_expr
107 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
108 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
109 %type <asts> expr argument_expr_list function_definition expr_opt
110 %type <asts> statement_list statement labeled_statement compound_statement
111 %type <asts> expression_statement selection_statement iteration_statement
112 %type <asts> jump_statement function_body else_statement string_literal
113 %type <ilist> initializer initializer_list
114 %type <yyint> unary_operator assignment_operator struct_or_union
121 : external_definition
122 | file external_definition
126 : function_definition { blockNo=0;}
129 allocVariables ($1) ;
130 cleanUpLevel (SymbolTab,1);
135 : declarator function_body { /* function type not specified */
136 /* assume it to be 'int' */
137 addDecl($1,0,newIntLink());
138 $$ = createFunction($1,$2);
140 | declaration_specifiers declarator function_body
142 pointerTypes($2->type,copyLinkChain($1));
144 $$ = createFunction($2,$3);
149 : using_reentrant_interrupt
150 | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2); }
153 using_reentrant_interrupt
156 $$->class = SPECIFIER ;
158 SPEC_BANK($$) = (int) floatFromVal($2);
160 | REENTRANT { $$ = newLink ();
161 $$->class = SPECIFIER ;
164 | CRITICAL { $$ = newLink ();
165 $$->class = SPECIFIER ;
168 | NONBANKED {$$ = newLink ();
169 $$->class = SPECIFIER ;
170 SPEC_NONBANKED($$) = 1;
171 if (SPEC_BANKED($$)) {
172 werror(W_BANKED_WITH_NONBANKED);
175 | BANKED {$$ = newLink ();
176 $$->class = SPECIFIER ;
178 if (SPEC_NONBANKED($$)) {
179 werror(W_BANKED_WITH_NONBANKED);
182 werror(W_BANKED_WITH_STATIC);
188 $$->class = SPECIFIER ;
196 | declaration_list compound_statement
198 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
204 : identifier { $$ = newAst(EX_VALUE,symbolVal($1)); }
205 | CONSTANT { $$ = newAst(EX_VALUE,$1); }
207 | '(' expr ')' { $$ = $2 ; }
211 : STRING_LITERAL { $$ = newAst(EX_VALUE,$1); }
216 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
217 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
218 $$->left->funcName = 1;}
219 | postfix_expr '(' argument_expr_list ')'
221 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
223 | postfix_expr '.' identifier
225 $3 = newSymbol($3->name,NestLevel);
227 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst(EX_VALUE,symbolVal($3)));
228 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
230 | postfix_expr PTR_OP identifier
232 $3 = newSymbol($3->name,NestLevel);
234 $$ = newNode(PTR_OP,$1,newAst(EX_VALUE,symbolVal($3)));
236 | postfix_expr INC_OP
237 { $$ = newNode(INC_OP,$1,NULL);}
238 | postfix_expr DEC_OP
239 { $$ = newNode(DEC_OP,$1,NULL); }
244 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
249 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
250 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
251 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
252 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
253 | SIZEOF '(' type_name ')' { $$ = newAst(EX_VALUE,sizeofOp($3)); }
267 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst(EX_LINK,$2),$4); }
272 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
273 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
274 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
278 : multiplicative_expr
279 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
280 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
285 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
286 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
291 | relational_expr '<' shift_expr {
293 newNode('!',newNode(GE_OP,$1,$3),NULL) :
294 newNode('<', $1,$3));
296 | relational_expr '>' shift_expr {
298 newNode('!',newNode(LE_OP,$1,$3),NULL) :
301 | relational_expr LE_OP shift_expr {
303 newNode('!', newNode('>', $1 , $3 ), NULL) :
304 newNode(LE_OP,$1,$3));
306 | relational_expr GE_OP shift_expr {
308 newNode('!', newNode('<', $1 , $3 ), NULL) :
309 newNode(GE_OP,$1,$3));
315 | equality_expr EQ_OP relational_expr {
317 newNode('!',newNode(NE_OP,$1,$3),NULL) :
318 newNode(EQ_OP,$1,$3));
320 | equality_expr NE_OP relational_expr {
322 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
323 newNode(NE_OP,$1,$3));
329 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
334 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
339 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
344 | logical_and_expr AND_OP inclusive_or_expr
345 { $$ = newNode(AND_OP,$1,$3);}
350 | logical_or_expr OR_OP logical_and_expr
351 { $$ = newNode(OR_OP,$1,$3); }
356 | logical_or_expr '?' logical_or_expr ':' conditional_expr
358 $$ = newNode(':',$3,$5) ;
359 $$ = newNode('?',$1,$$) ;
365 | unary_expr assignment_operator assignment_expr
370 $$ = newNode($2,$1,$3);
373 $$ = newNode('=',$1,newNode('*',copyAst($1),$3));
376 $$ = newNode('=',$1,newNode('/',copyAst($1),$3));
379 $$ = newNode('=',$1,newNode('%',copyAst($1),$3));
382 $$ = newNode('=',$1,newNode('+',copyAst($1),$3));
385 $$ = newNode('=',$1,newNode('-',copyAst($1),$3));
388 $$ = newNode('=',$1,newNode(LEFT_OP,copyAst($1),$3));
391 $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3));
394 $$ = newNode('=',$1,newNode('&',copyAst($1),$3));
397 $$ = newNode('=',$1,newNode('^',copyAst($1),$3));
400 $$ = newNode('=',$1,newNode('|',copyAst($1),$3));
425 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
433 : declaration_specifiers ';' { $$ = NULL ; }
434 | declaration_specifiers init_declarator_list ';'
436 /* add the specifier list to the id */
439 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
440 link *lnk = copyLinkChain($1);
441 /* do the pointer stuff */
442 pointerTypes(sym->type,lnk);
443 addDecl (sym,0,lnk) ;
450 declaration_specifiers
451 : storage_class_specifier { $$ = $1; }
452 | storage_class_specifier declaration_specifiers {
453 /* if the decl $2 is not a specifier */
454 /* find the spec and replace it */
457 while (lnk && !IS_SPEC(lnk->next))
459 lnk->next = mergeSpec($1,lnk->next);
463 $$ = mergeSpec($1,$2);
465 | type_specifier { $$ = $1; }
466 | type_specifier declaration_specifiers {
467 /* if the decl $2 is not a specifier */
468 /* find the spec and replace it */
471 while (lnk && !IS_SPEC(lnk->next))
473 lnk->next = mergeSpec($1,lnk->next);
477 $$ = mergeSpec($1,$2);
483 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
487 : declarator { $1->ival = NULL ; }
488 | declarator '=' initializer { $1->ival = $3 ; }
492 storage_class_specifier
495 $$->class = SPECIFIER ;
496 SPEC_TYPEDEF($$) = 1 ;
500 $$->class = SPECIFIER ;
505 $$->class = SPECIFIER ;
510 $$->class = SPECIFIER ;
511 SPEC_SCLS($$) = S_AUTO ;
515 $$->class = SPECIFIER ;
516 SPEC_SCLS($$) = S_REGISTER ;
521 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
526 | type_specifier2 AT constant_expr
528 /* add this to the storage class specifier */
529 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
530 /* now get the abs addr from value */
531 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
538 $$->class = SPECIFIER ;
539 SPEC_NOUN($$) = V_CHAR ;
543 $$->class = SPECIFIER ;
549 $$->class = SPECIFIER ;
550 SPEC_NOUN($$) = V_INT ;
554 $$->class = SPECIFIER ;
560 $$->class = SPECIFIER ;
565 $$->class = SPECIFIER ;
570 $$->class = SPECIFIER ;
571 SPEC_NOUN($$) = V_VOID ;
575 $$->class = SPECIFIER ;
576 SPEC_SCLS($$) = S_CONSTANT ;
581 $$->class = SPECIFIER ;
582 SPEC_VOLATILE($$) = 1 ;
586 SPEC_NOUN($$) = V_FLOAT;
587 $$->class = SPECIFIER ;
591 $$->class = SPECIFIER ;
592 SPEC_SCLS($$) = S_XDATA ;
596 $$->class = SPECIFIER ;
597 SPEC_SCLS($$) = S_CODE ;
601 $$->class = SPECIFIER ;
602 SPEC_SCLS($$) = S_EEPROM ;
606 $$->class = SPECIFIER ;
607 SPEC_SCLS($$) = S_DATA ;
611 $$->class = SPECIFIER ;
612 SPEC_SCLS($$) = S_IDATA ;
616 $$->class = SPECIFIER ;
617 SPEC_SCLS($$) = S_PDATA ;
621 $$->class = SPECIFIER ;
622 SPEC_NOUN($$) = V_BIT ;
623 SPEC_SCLS($$) = S_BIT ;
628 | struct_or_union_specifier
638 sym = findSym(TypedefTab,NULL,$1) ;
639 $$ = p = copyLinkChain(sym->type);
640 SPEC_TYPEDEF(getSpec(p)) = 0;
648 $$->class = SPECIFIER ;
649 SPEC_NOUN($$) = V_SBIT;
650 SPEC_SCLS($$) = S_SBIT;
654 $$->class = SPECIFIER ;
655 SPEC_NOUN($$) = V_CHAR;
656 SPEC_SCLS($$) = S_SFR ;
661 struct_or_union_specifier
662 : struct_or_union opt_stag '{' struct_declaration_list '}'
666 /* Create a structdef */
668 sdef->fields = reverseSyms($4) ; /* link the fields */
669 sdef->size = compStructSize($1,sdef); /* update size of */
671 /* Create the specifier */
673 $$->class = SPECIFIER ;
674 SPEC_NOUN($$) = V_STRUCT;
675 SPEC_STRUCT($$)= sdef ;
677 | struct_or_union stag
680 $$->class = SPECIFIER ;
681 SPEC_NOUN($$) = V_STRUCT;
682 SPEC_STRUCT($$) = $2 ;
687 : STRUCT { $$ = STRUCT ; }
688 | UNION { $$ = UNION ; }
693 | { /* synthesize a name add to structtable */
694 $$ = newStruct(genSymName(NestLevel)) ;
695 $$->level = NestLevel ;
696 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
701 : identifier { /* add name to structure table */
702 $$ = findSymWithBlock (StructTab,$1,currBlockno);
704 $$ = newStruct($1->name) ;
705 $$->level = NestLevel ;
706 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
711 struct_declaration_list
713 | struct_declaration_list struct_declaration
716 /* go to the end of the chain */
717 while (sym->next) sym = sym->next;
725 : type_specifier_list struct_declarator_list ';'
727 /* add this type to all the symbols */
729 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
731 pointerTypes(sym->type,copyLinkChain($1));
733 sym->type = copyLinkChain($1);
734 sym->etype = getSpec(sym->type);
737 addDecl (sym,0,cloneSpec($1));
744 struct_declarator_list
746 | struct_declarator_list ',' struct_declarator
755 | ':' constant_expr {
756 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
757 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
759 | declarator ':' constant_expr
761 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
766 : ENUM '{' enumerator_list '}' {
768 allocVariables(reverseSyms($3)) ;
769 $$ = copyLinkChain(cenum->type);
771 | ENUM identifier '{' enumerator_list '}' {
774 $2->type = copyLinkChain(cenum->type);
775 $2->etype = getSpec($2->type);
776 /* add this to the enumerator table */
777 if (!(csym=findSym(enumTab,$2,$2->name)) &&
778 (csym && csym->level == $2->level))
779 werror(E_DUPLICATE_TYPEDEF,csym->name);
781 addSym ( enumTab,$2,$2->name,$2->level,$2->block);
783 allocVariables (reverseSyms($4));
784 $$ = copyLinkChain(cenum->type);
785 SPEC_SCLS(getSpec($$)) = 0 ;
790 /* check the enumerator table */
791 if ((csym = findSym(enumTab,$2,$2->name)))
792 $$ = copyLinkChain(csym->type);
795 $$->class = SPECIFIER ;
796 SPEC_NOUN($$) = V_INT ;
799 SPEC_SCLS(getSpec($$)) = 0 ;
805 | enumerator_list ',' enumerator {
812 : identifier opt_assign_expr {
813 /* make the symbol one level up */
815 $1->type = copyLinkChain($2->type);
816 $1->etype= getSpec($1->type);
817 SPEC_ENUM($1->etype) = 1;
824 : '=' constant_expr {
827 val = constExprValue($2,TRUE);
832 sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
833 $$ = cenum = constVal(lbuff);
836 sprintf(lbuff,"%d",0);
837 $$ = cenum = constVal(lbuff);
843 : declarator2_using_reentrant { $$ = $1; }
844 | pointer declarator2_using_reentrant
846 addDecl ($2,0,reverseLink($1));
851 declarator2_using_reentrant
852 : declarator2 { $$ = $1 ; }
853 | declarator2 using_reentrant { addDecl ($1,0,$2); }
858 | '(' declarator ')' { $$ = $2; }
859 | declarator2 '[' ']'
864 DCL_TYPE(p) = ARRAY ;
868 | declarator2 '[' constant_expr ']'
873 p = (tval = constExprValue($3,TRUE))->etype;
874 /* if it is not a constant then Error */
875 if ( SPEC_SCLS(p) != S_LITERAL)
876 werror(E_CONST_EXPECTED) ;
879 DCL_TYPE(p) = ARRAY ;
880 DCL_ELEM(p) = (int) floatFromVal(tval) ;
884 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
885 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
888 addDecl ($1,FUNCTION,NULL) ;
890 $1->hasVargs = IS_VARG($4);
891 $1->args = reverseVal($4) ;
893 /* nest level was incremented to take care of the parms */
898 | declarator2 '(' parameter_identifier_list ')'
900 werror(E_OLD_STYLE,$1->name) ;
902 /* assume it returns an it */
903 $1->type = $1->etype = newIntLink();
909 : far_near_pointer { $$ = $1 ;}
910 | far_near_pointer type_specifier_list
915 | far_near_pointer pointer
920 | far_near_pointer type_specifier_list pointer
923 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
924 DCL_PTR_CONST($1) = SPEC_CONST($2);
925 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
926 switch (SPEC_SCLS($2)) {
928 DCL_TYPE($3) = FPOINTER;
931 DCL_TYPE($3) = IPOINTER ;
934 DCL_TYPE($3) = PPOINTER ;
937 DCL_TYPE($3) = POINTER ;
940 DCL_PTR_CONST($3) = 1;
941 DCL_TYPE($3) = CPOINTER ;
943 DCL_TYPE($3) = EEPPOINTER;
946 werror(W_PTR_TYPE_INVALID);
950 werror (W_PTR_TYPE_INVALID);
959 DCL_TYPE($$) = POINTER ;
967 : _XDATA { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; }
968 | _CODE { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ; DCL_PTR_CONST($$) = 1;}
969 | _PDATA { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; }
970 | _IDATA { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; }
971 | _NEAR { $$ = NULL ; }
972 | _GENERIC { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; }
973 | _EEPROM { $$ = newLink() ; DCL_TYPE($$) = EEPPOINTER ;}
974 | { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; }
979 | type_specifier_list type_specifier { $$ = mergeSpec ($1,$2); }
982 parameter_identifier_list
984 | identifier_list ',' ELIPSIS
989 | identifier_list ',' identifier
998 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1002 : parameter_declaration
1003 | parameter_list ',' parameter_declaration
1010 parameter_declaration
1011 : type_specifier_list declarator
1014 pointerTypes($2->type,$1);
1016 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1023 $$->etype = getSpec($$->type);
1028 : type_specifier_list { $$ = $1 ;}
1029 | type_specifier_list abstract_declarator
1031 /* go to the end of the list */
1033 pointerTypes($2,$1);
1034 for ( p = $2 ; p->next ; p=p->next);
1041 : pointer { $$ = reverseLink($1); }
1042 | abstract_declarator2
1043 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1046 abstract_declarator2
1047 : '(' abstract_declarator ')' { $$ = $2 ; }
1050 DCL_TYPE($$) = ARRAY ;
1053 | '[' constant_expr ']' {
1056 DCL_TYPE($$) = ARRAY ;
1057 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1059 | abstract_declarator2 '[' ']' {
1061 DCL_TYPE($$) = ARRAY ;
1065 | abstract_declarator2 '[' constant_expr ']'
1069 DCL_TYPE($$) = ARRAY ;
1070 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1073 | '(' ')' { $$ = NULL;}
1074 | '(' parameter_type_list ')' { $$ = NULL;}
1075 | abstract_declarator2 '(' ')'
1076 | abstract_declarator2 '(' parameter_type_list ')'
1080 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1081 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1082 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1087 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1092 | compound_statement
1093 | expression_statement
1094 | selection_statement
1095 | iteration_statement
1098 ast *ex = newNode(INLINEASM,NULL,NULL);
1099 ALLOC_ATOMIC(ex->values.inlineasm,strlen($1));
1100 strcpy(ex->values.inlineasm,$1);
1106 : identifier ':' statement { $$ = createLabel($1,$3); }
1107 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1108 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1111 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1114 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1118 : start_block end_block { $$ = createBlock(NULL,NULL); }
1119 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1121 declaration_list { addSymChain($2); }
1122 end_block { $$ = createBlock($2,NULL) ; }
1124 declaration_list { addSymChain ($2); }
1126 end_block {$$ = createBlock($2,$4) ; }
1127 | error ';' { $$ = NULL ; }
1133 /* if this is typedef declare it immediately */
1134 if ( $1 && IS_TYPEDEF($1->etype)) {
1135 allocVariables ($1);
1142 | declaration_list declaration
1146 /* if this is a typedef */
1147 if ($2 && IS_TYPEDEF($2->etype)) {
1148 allocVariables ($2);
1152 /* get to the end of the previous decl */
1167 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1170 expression_statement
1176 : ELSE statement { $$ = $2 ; }
1182 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1183 | SWITCH '(' expr ')' {
1185 static int swLabel = 0 ;
1187 /* create a node for expression */
1188 ex = newNode(SWITCH,$3,NULL);
1189 STACK_PUSH(swStk,ex); /* save it in the stack */
1190 ex->values.switchVals.swNum = swLabel ;
1192 /* now create the label */
1193 sprintf(lbuff,"_swBrk_%d",swLabel++);
1194 $<sym>$ = newSymbol(lbuff,NestLevel);
1195 /* put label in the break stack */
1196 STACK_PUSH(breakStack,$<sym>$);
1199 /* get back the switch form the stack */
1200 $$ = STACK_POP(swStk) ;
1201 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1202 STACK_POP(breakStack);
1206 while : WHILE { /* create and push the continue , break & body labels */
1207 static int Lblnum = 0 ;
1209 sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1210 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1212 sprintf (lbuff,"_whilebreak_%d",Lblnum);
1213 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1215 sprintf (lbuff,"_whilebody_%d",Lblnum++);
1216 $$ = newSymbol(lbuff,NestLevel);
1219 do : DO { /* create and push the continue , break & body Labels */
1220 static int Lblnum = 0 ;
1223 sprintf(lbuff,"_docontinue_%d",Lblnum);
1224 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1226 sprintf (lbuff,"_dobreak_%d",Lblnum);
1227 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1229 sprintf (lbuff,"_dobody_%d",Lblnum++);
1230 $$ = newSymbol (lbuff,NestLevel);
1232 for : FOR { /* create & push continue, break & body labels */
1233 static int Lblnum = 0 ;
1236 sprintf (lbuff,"_forcontinue_%d",Lblnum);
1237 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1239 sprintf (lbuff,"_forbreak_%d",Lblnum);
1240 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1242 sprintf (lbuff,"_forbody_%d",Lblnum);
1243 $$ = newSymbol(lbuff,NestLevel);
1245 sprintf (lbuff,"_forcond_%d",Lblnum++);
1246 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1250 : while '(' expr ')' statement
1253 $$ = createWhile ( $1, STACK_POP(continueStack),
1254 STACK_POP(breakStack), $3, $5 );
1255 $$->lineno = $1->lineDef ;
1258 | do statement WHILE '(' expr ')' ';'
1261 $$ = createDo ( $1 , STACK_POP(continueStack),
1262 STACK_POP(breakStack), $5, $2);
1263 $$->lineno = $1->lineDef ;
1266 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1270 /* if break or continue statement present
1271 then create a general case loop */
1272 if (STACK_PEEK(continueStack)->isref ||
1273 STACK_PEEK(breakStack)->isref) {
1274 $$ = createFor ($1, STACK_POP(continueStack),
1275 STACK_POP(breakStack) ,
1276 STACK_POP(forStack) ,
1279 $$ = newNode(FOR,$9,NULL);
1280 AST_FOR($$,trueLabel) = $1;
1281 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1282 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1283 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1284 AST_FOR($$,initExpr) = $3;
1285 AST_FOR($$,condExpr) = $5;
1286 AST_FOR($$,loopExpr) = $7;
1299 : GOTO identifier ';' {
1301 $$ = newAst(EX_VALUE,symbolVal($2));
1302 $$ = newNode(GOTO,$$,NULL);
1305 /* make sure continue is in context */
1306 if (STACK_PEEK(continueStack) == NULL) {
1307 werror(E_BREAK_CONTEXT);
1311 $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(continueStack)));
1312 $$ = newNode(GOTO,$$,NULL);
1313 /* mark the continue label as referenced */
1314 STACK_PEEK(continueStack)->isref = 1;
1318 if (STACK_PEEK(breakStack) == NULL) {
1319 werror(E_BREAK_CONTEXT);
1322 $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(breakStack)));
1323 $$ = newNode(GOTO,$$,NULL);
1324 STACK_PEEK(breakStack)->isref = 1;
1327 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1328 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1332 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }