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"
35 extern int yyerror (char *);
37 extern char srcLstFname[];
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 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 | BANKED {$$ = newLink ();
169 $$->class = SPECIFIER ;
175 $$->class = SPECIFIER ;
183 | declaration_list compound_statement
185 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
191 : identifier { $$ = newAst(EX_VALUE,symbolVal($1)); }
192 | CONSTANT { $$ = newAst(EX_VALUE,$1); }
194 | '(' expr ')' { $$ = $2 ; }
198 : STRING_LITERAL { $$ = newAst(EX_VALUE,$1); }
203 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
204 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
205 $$->left->funcName = 1;}
206 | postfix_expr '(' argument_expr_list ')'
208 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
210 | postfix_expr '.' identifier
212 $3 = newSymbol($3->name,NestLevel);
214 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst(EX_VALUE,symbolVal($3)));
215 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
217 | postfix_expr PTR_OP identifier
219 $3 = newSymbol($3->name,NestLevel);
221 $$ = newNode(PTR_OP,$1,newAst(EX_VALUE,symbolVal($3)));
223 | postfix_expr INC_OP
224 { $$ = newNode(INC_OP,$1,NULL);}
225 | postfix_expr DEC_OP
226 { $$ = newNode(DEC_OP,$1,NULL); }
231 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
236 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
237 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
238 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
239 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
240 | SIZEOF '(' type_name ')' { $$ = newAst(EX_VALUE,sizeofOp($3)); }
254 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst(EX_LINK,$2),$4); }
259 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
260 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
261 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
265 : multiplicative_expr
266 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
267 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
272 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
273 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
278 | relational_expr '<' shift_expr { $$ = newNode('<',$1,$3); }
279 | relational_expr '>' shift_expr { $$ = newNode('>',$1,$3); }
280 | relational_expr LE_OP shift_expr {
281 /* $$ = newNode(LE_OP,$1,$3); */
282 /* getting 8051 specific here : will change
283 LE_OP operation to "not greater than" i.e.
284 ( a <= b ) === ( ! ( a > b )) */
286 newNode('>', $1 , $3 ),
289 | relational_expr GE_OP shift_expr {
290 /* $$ = newNode(GE_OP,$1,$3) ; */
291 /* getting 8051 specific here : will change
292 GE_OP operation to "not less than" i.e.
293 ( a >= b ) === ( ! ( a < b )) */
295 newNode('<', $1 , $3 ),
302 | equality_expr EQ_OP relational_expr { $$ = newNode(EQ_OP,$1,$3);}
303 | equality_expr NE_OP relational_expr
305 /* $$ = newNode(NE_OP,$1,$3); */
307 expr1 != expr2 is equivalent to
308 (! expr1 == expr2) */
310 newNode(EQ_OP,$1,$3),
317 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
322 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
327 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
332 | logical_and_expr AND_OP inclusive_or_expr
333 { $$ = newNode(AND_OP,$1,$3);}
338 | logical_or_expr OR_OP logical_and_expr
339 { $$ = newNode(OR_OP,$1,$3); }
344 | logical_or_expr '?' logical_or_expr ':' conditional_expr
346 $$ = newNode(':',$3,$5) ;
347 $$ = newNode('?',$1,$$) ;
353 | unary_expr assignment_operator assignment_expr
358 $$ = newNode($2,$1,$3);
361 $$ = newNode('=',$1,newNode('*',copyAst($1),$3));
364 $$ = newNode('=',$1,newNode('/',copyAst($1),$3));
367 $$ = newNode('=',$1,newNode('+',copyAst($1),$3));
370 $$ = newNode('=',$1,newNode('-',copyAst($1),$3));
373 $$ = newNode('=',$1,newNode(LEFT_OP,copyAst($1),$3));
376 $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3));
379 $$ = newNode('=',$1,newNode('&',copyAst($1),$3));
382 $$ = newNode('=',$1,newNode('^',copyAst($1),$3));
385 $$ = newNode('=',$1,newNode('|',copyAst($1),$3));
410 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
418 : declaration_specifiers ';' { $$ = NULL ; }
419 | declaration_specifiers init_declarator_list ';'
421 /* add the specifier list to the id */
424 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
425 link *lnk = copyLinkChain($1);
426 /* do the pointer stuff */
427 pointerTypes(sym->type,lnk);
428 addDecl (sym,0,lnk) ;
435 declaration_specifiers
436 : storage_class_specifier { $$ = $1; }
437 | storage_class_specifier declaration_specifiers {
438 /* if the decl $2 is not a specifier */
439 /* find the spec and replace it */
442 while (lnk && !IS_SPEC(lnk->next))
444 lnk->next = mergeSpec($1,lnk->next);
448 $$ = mergeSpec($1,$2);
450 | type_specifier { $$ = $1; }
451 | type_specifier declaration_specifiers {
452 /* if the decl $2 is not a specifier */
453 /* find the spec and replace it */
456 while (lnk && !IS_SPEC(lnk->next))
458 lnk->next = mergeSpec($1,lnk->next);
462 $$ = mergeSpec($1,$2);
468 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
472 : declarator { $1->ival = NULL ; }
473 | declarator '=' initializer { $1->ival = $3 ; }
477 storage_class_specifier
480 $$->class = SPECIFIER ;
481 SPEC_TYPEDEF($$) = 1 ;
485 $$->class = SPECIFIER ;
490 $$->class = SPECIFIER ;
495 $$->class = SPECIFIER ;
496 SPEC_SCLS($$) = S_AUTO ;
500 $$->class = SPECIFIER ;
501 SPEC_SCLS($$) = S_REGISTER ;
506 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
511 | type_specifier2 AT CONSTANT
513 /* add this to the storage class specifier */
514 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
515 /* now get the abs addr from value */
516 SPEC_ADDR($1) = (int) floatFromVal ($3) ;
523 $$->class = SPECIFIER ;
524 SPEC_NOUN($$) = V_CHAR ;
528 $$->class = SPECIFIER ;
534 $$->class = SPECIFIER ;
535 SPEC_NOUN($$) = V_INT ;
539 $$->class = SPECIFIER ;
545 $$->class = SPECIFIER ;
550 $$->class = SPECIFIER ;
555 $$->class = SPECIFIER ;
556 SPEC_NOUN($$) = V_VOID ;
560 $$->class = SPECIFIER ;
561 SPEC_SCLS($$) = S_CONSTANT ;
566 $$->class = SPECIFIER ;
567 SPEC_VOLATILE($$) = 1 ;
571 SPEC_NOUN($$) = V_FLOAT;
572 $$->class = SPECIFIER ;
576 $$->class = SPECIFIER ;
577 SPEC_SCLS($$) = S_XDATA ;
581 $$->class = SPECIFIER ;
582 SPEC_SCLS($$) = S_CODE ;
586 $$->class = SPECIFIER ;
587 SPEC_SCLS($$) = S_EEPROM ;
591 $$->class = SPECIFIER ;
592 SPEC_SCLS($$) = S_DATA ;
596 $$->class = SPECIFIER ;
597 SPEC_SCLS($$) = S_IDATA ;
601 $$->class = SPECIFIER ;
602 SPEC_SCLS($$) = S_PDATA ;
606 $$->class = SPECIFIER ;
607 SPEC_NOUN($$) = V_BIT ;
608 SPEC_SCLS($$) = S_BIT ;
613 | struct_or_union_specifier
623 sym = findSym(TypedefTab,NULL,$1) ;
624 $$ = p = copyLinkChain(sym->type);
625 SPEC_TYPEDEF(getSpec(p)) = 0;
633 $$->class = SPECIFIER ;
634 SPEC_NOUN($$) = V_SBIT;
635 SPEC_SCLS($$) = S_SBIT;
639 $$->class = SPECIFIER ;
640 SPEC_NOUN($$) = V_CHAR;
641 SPEC_SCLS($$) = S_SFR ;
646 struct_or_union_specifier
647 : struct_or_union opt_stag '{' struct_declaration_list '}'
651 /* Create a structdef */
653 sdef->fields = reverseSyms($4) ; /* link the fields */
654 sdef->size = compStructSize($1,sdef); /* update size of */
656 /* Create the specifier */
658 $$->class = SPECIFIER ;
659 SPEC_NOUN($$) = V_STRUCT;
660 SPEC_STRUCT($$)= sdef ;
662 | struct_or_union stag
665 $$->class = SPECIFIER ;
666 SPEC_NOUN($$) = V_STRUCT;
667 SPEC_STRUCT($$) = $2 ;
672 : STRUCT { $$ = STRUCT ; }
673 | UNION { $$ = UNION ; }
678 | { /* synthesize a name add to structtable */
679 $$ = newStruct(genSymName(NestLevel)) ;
680 $$->level = NestLevel ;
681 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
686 : identifier { /* add name to structure table */
687 $$ = findSymWithBlock (StructTab,$1,currBlockno);
689 $$ = newStruct($1->name) ;
690 $$->level = NestLevel ;
691 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
696 struct_declaration_list
698 | struct_declaration_list struct_declaration
701 /* go to the end of the chain */
702 while (sym->next) sym = sym->next;
710 : type_specifier_list struct_declarator_list ';'
712 /* add this type to all the symbols */
714 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
716 pointerTypes(sym->type,copyLinkChain($1));
718 sym->type = copyLinkChain($1);
719 sym->etype = getSpec(sym->type);
722 addDecl (sym,0,cloneSpec($1));
729 struct_declarator_list
731 | struct_declarator_list ',' struct_declarator
740 | ':' constant_expr {
741 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
742 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
744 | declarator ':' constant_expr
746 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
751 : ENUM '{' enumerator_list '}' {
753 allocVariables(reverseSyms($3)) ;
754 $$ = copyLinkChain(cenum->type);
756 | ENUM identifier '{' enumerator_list '}' {
759 $2->type = copyLinkChain(cenum->type);
760 $2->etype = getSpec($2->type);
761 /* add this to the enumerator table */
762 if (!(csym=findSym(enumTab,$2,$2->name)) &&
763 (csym && csym->level == $2->level))
764 werror(E_DUPLICATE_TYPEDEF,csym->name);
766 addSym ( enumTab,$2,$2->name,$2->level,$2->block);
768 allocVariables (reverseSyms($4));
769 $$ = copyLinkChain(cenum->type);
770 SPEC_SCLS(getSpec($$)) = 0 ;
775 /* check the enumerator table */
776 if ((csym = findSym(enumTab,$2,$2->name)))
777 $$ = copyLinkChain(csym->type);
780 $$->class = SPECIFIER ;
781 SPEC_NOUN($$) = V_INT ;
784 SPEC_SCLS(getSpec($$)) = 0 ;
790 | enumerator_list ',' enumerator {
797 : identifier opt_assign_expr {
798 /* make the symbol one level up */
800 $1->type = copyLinkChain($2->type);
801 $1->etype= getSpec($1->type);
802 SPEC_ENUM($1->etype) = 1;
809 : '=' constant_expr {
812 val = constExprValue($2,TRUE);
817 sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
818 $$ = cenum = constVal(lbuff);
821 sprintf(lbuff,"%d",0);
822 $$ = cenum = constVal(lbuff);
828 : declarator2_using_reentrant { $$ = $1; }
829 | pointer declarator2_using_reentrant
831 addDecl ($2,0,reverseLink($1));
836 declarator2_using_reentrant
837 : declarator2 { $$ = $1 ; }
838 | declarator2 using_reentrant { addDecl ($1,0,$2); }
843 | '(' declarator ')' { $$ = $2; }
844 | declarator2 '[' ']'
849 DCL_TYPE(p) = ARRAY ;
853 | declarator2 '[' constant_expr ']'
858 p = (tval = constExprValue($3,TRUE))->etype;
859 /* if it is not a constant then Error */
860 if ( SPEC_SCLS(p) != S_LITERAL)
861 werror(E_CONST_EXPECTED) ;
864 DCL_TYPE(p) = ARRAY ;
865 DCL_ELEM(p) = (int) floatFromVal(tval) ;
869 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
870 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
873 addDecl ($1,FUNCTION,NULL) ;
875 $1->hasVargs = IS_VARG($4);
876 $1->args = reverseVal($4) ;
878 /* nest level was incremented to take care of the parms */
883 | declarator2 '(' parameter_identifier_list ')'
885 werror(E_OLD_STYLE,$1->name) ;
887 /* assume it returns an it */
888 $1->type = $1->etype = newIntLink();
894 : far_near_pointer { $$ = $1 ;}
895 | far_near_pointer type_specifier_list
900 | far_near_pointer pointer
905 | far_near_pointer type_specifier_list pointer
908 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
909 DCL_PTR_CONST($1) = SPEC_CONST($2);
910 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
911 switch (SPEC_SCLS($2)) {
913 DCL_TYPE($3) = FPOINTER;
916 DCL_TYPE($3) = IPOINTER ;
919 DCL_TYPE($3) = PPOINTER ;
922 DCL_TYPE($3) = POINTER ;
925 DCL_PTR_CONST($3) = 1;
926 DCL_TYPE($3) = CPOINTER ;
928 DCL_TYPE($3) = EEPPOINTER;
931 werror(W_PTR_TYPE_INVALID);
935 werror (W_PTR_TYPE_INVALID);
944 DCL_TYPE($$) = POINTER ;
952 : _XDATA { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; }
953 | _CODE { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ; DCL_PTR_CONST($$) = 1;}
954 | _PDATA { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; }
955 | _IDATA { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; }
956 | _NEAR { $$ = NULL ; }
957 | _GENERIC { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; }
958 | _EEPROM { $$ = newLink() ; DCL_TYPE($$) = EEPPOINTER ;}
959 | { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; }
964 | type_specifier_list type_specifier { $$ = mergeSpec ($1,$2); }
967 parameter_identifier_list
969 | identifier_list ',' ELIPSIS
974 | identifier_list ',' identifier
983 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
987 : parameter_declaration
988 | parameter_list ',' parameter_declaration
995 parameter_declaration
996 : type_specifier_list declarator
999 pointerTypes($2->type,$1);
1001 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1008 $$->etype = getSpec($$->type);
1013 : type_specifier_list { $$ = $1 ;}
1014 | type_specifier_list abstract_declarator
1016 /* go to the end of the list */
1018 pointerTypes($2,$1);
1019 for ( p = $2 ; p->next ; p=p->next);
1026 : pointer { $$ = reverseLink($1); }
1027 | abstract_declarator2
1028 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1031 abstract_declarator2
1032 : '(' abstract_declarator ')' { $$ = $2 ; }
1035 DCL_TYPE($$) = ARRAY ;
1038 | '[' constant_expr ']' {
1041 DCL_TYPE($$) = ARRAY ;
1042 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1044 | abstract_declarator2 '[' ']' {
1046 DCL_TYPE($$) = ARRAY ;
1050 | abstract_declarator2 '[' constant_expr ']'
1054 DCL_TYPE($$) = ARRAY ;
1055 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1058 | '(' ')' { $$ = NULL;}
1059 | '(' parameter_type_list ')' { $$ = NULL;}
1060 | abstract_declarator2 '(' ')'
1061 | abstract_declarator2 '(' parameter_type_list ')'
1065 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1066 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1067 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1072 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1077 | compound_statement
1078 | expression_statement
1079 | selection_statement
1080 | iteration_statement
1083 ast *ex = newNode(INLINEASM,NULL,NULL);
1084 ALLOC_ATOMIC(ex->values.inlineasm,strlen($1));
1085 strcpy(ex->values.inlineasm,$1);
1091 : identifier ':' statement { $$ = createLabel($1,$3); }
1092 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1093 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1096 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1099 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1103 : start_block end_block { $$ = createBlock(NULL,NULL); }
1104 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1106 declaration_list { addSymChain($2); }
1107 end_block { $$ = createBlock($2,NULL) ; }
1109 declaration_list { addSymChain ($2); }
1111 end_block {$$ = createBlock($2,$4) ; }
1112 | error ';' { $$ = NULL ; }
1118 /* if this is typedef declare it immediately */
1119 if ( $1 && IS_TYPEDEF($1->etype)) {
1120 allocVariables ($1);
1127 | declaration_list declaration
1131 /* if this is a typedef */
1132 if ($2 && IS_TYPEDEF($2->etype)) {
1133 allocVariables ($2);
1137 /* get to the end of the previous decl */
1152 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1155 expression_statement
1161 : ELSE statement { $$ = $2 ; }
1167 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1168 | SWITCH '(' expr ')' {
1170 static int swLabel = 0 ;
1172 /* create a node for expression */
1173 ex = newNode(SWITCH,$3,NULL);
1174 STACK_PUSH(swStk,ex); /* save it in the stack */
1175 ex->values.switchVals.swNum = swLabel ;
1177 /* now create the label */
1178 sprintf(lbuff,"_swBrk_%d",swLabel++);
1179 $<sym>$ = newSymbol(lbuff,NestLevel);
1180 /* put label in the break stack */
1181 STACK_PUSH(breakStack,$<sym>$);
1184 /* get back the switch form the stack */
1185 $$ = STACK_POP(swStk) ;
1186 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1187 STACK_POP(breakStack);
1191 while : WHILE { /* create and push the continue , break & body labels */
1192 static int Lblnum = 0 ;
1194 sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1195 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1197 sprintf (lbuff,"_whilebreak_%d",Lblnum);
1198 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1200 sprintf (lbuff,"_whilebody_%d",Lblnum++);
1201 $$ = newSymbol(lbuff,NestLevel);
1204 do : DO { /* create and push the continue , break & body Labels */
1205 static int Lblnum = 0 ;
1208 sprintf(lbuff,"_docontinue_%d",Lblnum);
1209 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1211 sprintf (lbuff,"_dobreak_%d",Lblnum);
1212 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1214 sprintf (lbuff,"_dobody_%d",Lblnum++);
1215 $$ = newSymbol (lbuff,NestLevel);
1217 for : FOR { /* create & push continue, break & body labels */
1218 static int Lblnum = 0 ;
1221 sprintf (lbuff,"_forcontinue_%d",Lblnum);
1222 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1224 sprintf (lbuff,"_forbreak_%d",Lblnum);
1225 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1227 sprintf (lbuff,"_forbody_%d",Lblnum);
1228 $$ = newSymbol(lbuff,NestLevel);
1230 sprintf (lbuff,"_forcond_%d",Lblnum++);
1231 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1235 : while '(' expr ')' statement
1238 $$ = createWhile ( $1, STACK_POP(continueStack),
1239 STACK_POP(breakStack), $3, $5 );
1240 $$->lineno = $1->lineDef ;
1243 | do statement WHILE '(' expr ')' ';'
1246 $$ = createDo ( $1 , STACK_POP(continueStack),
1247 STACK_POP(breakStack), $5, $2);
1248 $$->lineno = $1->lineDef ;
1251 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1255 /* if break or continue statement present
1256 then create a general case loop */
1257 if (STACK_PEEK(continueStack)->isref ||
1258 STACK_PEEK(breakStack)->isref) {
1259 $$ = createFor ($1, STACK_POP(continueStack),
1260 STACK_POP(breakStack) ,
1261 STACK_POP(forStack) ,
1264 $$ = newNode(FOR,$9,NULL);
1265 AST_FOR($$,trueLabel) = $1;
1266 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1267 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1268 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1269 AST_FOR($$,initExpr) = $3;
1270 AST_FOR($$,condExpr) = $5;
1271 AST_FOR($$,loopExpr) = $7;
1284 : GOTO identifier ';' {
1286 $$ = newAst(EX_VALUE,symbolVal($2));
1287 $$ = newNode(GOTO,$$,NULL);
1290 /* make sure continue is in context */
1291 if (STACK_PEEK(continueStack) == NULL) {
1292 werror(E_BREAK_CONTEXT);
1296 $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(continueStack)));
1297 $$ = newNode(GOTO,$$,NULL);
1298 /* mark the continue label as referenced */
1299 STACK_PEEK(continueStack)->isref = 1;
1303 if (STACK_PEEK(breakStack) == NULL) {
1304 werror(E_BREAK_CONTEXT);
1307 $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(breakStack)));
1308 $$ = newNode(GOTO,$$,NULL);
1309 STACK_PEEK(breakStack)->isref = 1;
1312 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1313 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1317 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }
1321 extern unsigned char *yytext;
1323 extern char *filename;
1324 extern int fatalError;
1326 int yyerror(char *s)
1331 fprintf(stderr,"\n%s(%d) %s: token -> '%s' ; column %d\n",