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"
34 extern int yyerror (char *);
36 extern char srcLstFname[];
37 int NestLevel = 0 ; /* current NestLevel */
38 int stackPtr = 1 ; /* stack pointer */
39 int xstackPtr = 0 ; /* xstack pointer */
41 int blockNo = 0 ; /* sequential block number */
46 char lbuff[1024]; /* local buffer */
48 /* break & continue stacks */
49 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
50 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
51 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
52 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
53 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
55 value *cenum = NULL ; /* current enumeration type chain*/
59 symbol *sym ; /* symbol table pointer */
60 structdef *sdef; /* structure definition */
61 char yychar[SDCC_NAME_MAX+1];
62 link *lnk ; /* declarator or specifier */
63 int yyint; /* integer value returned */
64 value *val ; /* for integer constant */
65 initList *ilist; /* initial list */
66 char yyinline[MAX_INLINEASM]; /* inlined assembler code */
67 ast *asts; /* expression tree */
70 %token <yychar> IDENTIFIER TYPE_NAME
71 %token <val> CONSTANT STRING_LITERAL
73 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
75 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
76 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
77 %token <yyint> XOR_ASSIGN OR_ASSIGN
78 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
79 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL
80 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
81 %token STRUCT UNION ENUM ELIPSIS RANGE FAR _XDATA _CODE _GENERIC _NEAR _PDATA _IDATA _EEPROM
82 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
83 %token <yyinline> INLINEASM
84 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
85 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
87 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND
89 %type <yyint> Interrupt_storage
90 %type <sym> identifier declarator declarator2 enumerator_list enumerator
91 %type <sym> struct_declarator
92 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
93 %type <sym> declaration init_declarator_list init_declarator
94 %type <sym> declaration_list identifier_list parameter_identifier_list
95 %type <sym> declarator2_using_reentrant while do for
96 %type <lnk> pointer type_specifier_list type_specifier type_name
97 %type <lnk> storage_class_specifier struct_or_union_specifier
98 %type <lnk> declaration_specifiers sfr_reg_bit type_specifier2
99 %type <lnk> using_reentrant using_reentrant_interrupt enum_specifier
100 %type <lnk> abstract_declarator abstract_declarator2 far_near_pointer far_near
101 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
102 %type <sdef> stag opt_stag
103 %type <asts> primary_expr
104 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
105 %type <asts> additive_expr shift_expr relational_expr equality_expr
106 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
107 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
108 %type <asts> expr argument_expr_list function_definition expr_opt
109 %type <asts> statement_list statement labeled_statement compound_statement
110 %type <asts> expression_statement selection_statement iteration_statement
111 %type <asts> jump_statement function_body else_statement string_literal
112 %type <ilist> initializer initializer_list
113 %type <yyint> unary_operator assignment_operator struct_or_union
120 : external_definition
121 | file external_definition
125 : function_definition { blockNo=0;}
128 allocVariables ($1) ;
129 cleanUpLevel (SymbolTab,1);
134 : declarator function_body { /* function type not specified */
135 /* assume it to be 'int' */
136 addDecl($1,0,newIntLink());
137 $$ = createFunction($1,$2);
139 | declaration_specifiers declarator function_body
141 pointerTypes($2->type,copyLinkChain($1));
143 $$ = createFunction($2,$3);
148 : using_reentrant_interrupt
149 | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2); }
152 using_reentrant_interrupt
155 $$->class = SPECIFIER ;
157 SPEC_BANK($$) = (int) floatFromVal($2);
159 | REENTRANT { $$ = newLink ();
160 $$->class = SPECIFIER ;
163 | CRITICAL { $$ = newLink ();
164 $$->class = SPECIFIER ;
170 $$->class = SPECIFIER ;
178 | declaration_list compound_statement
180 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
186 : identifier { $$ = newAst(EX_VALUE,symbolVal($1)); }
187 | CONSTANT { $$ = newAst(EX_VALUE,$1); }
189 | '(' expr ')' { $$ = $2 ; }
193 : STRING_LITERAL { $$ = newAst(EX_VALUE,$1); }
198 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
199 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
200 $$->left->funcName = 1;}
201 | postfix_expr '(' argument_expr_list ')'
203 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
205 | postfix_expr '.' identifier
207 $3 = newSymbol($3->name,NestLevel);
209 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst(EX_VALUE,symbolVal($3)));
210 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
212 | postfix_expr PTR_OP identifier
214 $3 = newSymbol($3->name,NestLevel);
216 $$ = newNode(PTR_OP,$1,newAst(EX_VALUE,symbolVal($3)));
218 | postfix_expr INC_OP
219 { $$ = newNode(INC_OP,$1,NULL);}
220 | postfix_expr DEC_OP
221 { $$ = newNode(DEC_OP,$1,NULL); }
226 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
231 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
232 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
233 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
234 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
235 | SIZEOF '(' type_name ')' { $$ = newAst(EX_VALUE,sizeofOp($3)); }
249 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst(EX_LINK,$2),$4); }
254 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
255 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
256 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
260 : multiplicative_expr
261 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
262 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
267 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
268 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
273 | relational_expr '<' shift_expr { $$ = newNode('<',$1,$3); }
274 | relational_expr '>' shift_expr { $$ = newNode('>',$1,$3); }
275 | relational_expr LE_OP shift_expr {
276 /* $$ = newNode(LE_OP,$1,$3); */
277 /* getting 8051 specific here : will change
278 LE_OP operation to "not greater than" i.e.
279 ( a <= b ) === ( ! ( a > b )) */
281 newNode('>', $1 , $3 ),
284 | relational_expr GE_OP shift_expr {
285 /* $$ = newNode(GE_OP,$1,$3) ; */
286 /* getting 8051 specific here : will change
287 GE_OP operation to "not less than" i.e.
288 ( a >= b ) === ( ! ( a < b )) */
290 newNode('<', $1 , $3 ),
297 | equality_expr EQ_OP relational_expr { $$ = newNode(EQ_OP,$1,$3);}
298 | equality_expr NE_OP relational_expr
300 /* $$ = newNode(NE_OP,$1,$3); */
302 expr1 != expr2 is equivalent to
303 (! expr1 == expr2) */
305 newNode(EQ_OP,$1,$3),
312 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
317 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
322 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
327 | logical_and_expr AND_OP inclusive_or_expr
328 { $$ = newNode(AND_OP,$1,$3);}
333 | logical_or_expr OR_OP logical_and_expr
334 { $$ = newNode(OR_OP,$1,$3); }
339 | logical_or_expr '?' logical_or_expr ':' conditional_expr
341 $$ = newNode(':',$3,$5) ;
342 $$ = newNode('?',$1,$$) ;
348 | unary_expr assignment_operator assignment_expr
353 $$ = newNode($2,$1,$3);
356 $$ = newNode('=',$1,newNode('*',copyAst($1),$3));
359 $$ = newNode('=',$1,newNode('/',copyAst($1),$3));
362 $$ = newNode('=',$1,newNode('+',copyAst($1),$3));
365 $$ = newNode('=',$1,newNode('-',copyAst($1),$3));
368 $$ = newNode('=',$1,newNode(LEFT_OP,copyAst($1),$3));
371 $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3));
374 $$ = newNode('=',$1,newNode('&',copyAst($1),$3));
377 $$ = newNode('=',$1,newNode('^',copyAst($1),$3));
380 $$ = newNode('=',$1,newNode('|',copyAst($1),$3));
405 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
413 : declaration_specifiers ';' { $$ = NULL ; }
414 | declaration_specifiers init_declarator_list ';'
416 /* add the specifier list to the id */
419 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
420 link *lnk = copyLinkChain($1);
421 /* do the pointer stuff */
422 pointerTypes(sym->type,lnk);
423 addDecl (sym,0,lnk) ;
430 declaration_specifiers
431 : storage_class_specifier { $$ = $1; }
432 | storage_class_specifier declaration_specifiers {
433 /* if the decl $2 is not a specifier */
434 /* find the spec and replace it */
437 while (lnk && !IS_SPEC(lnk->next))
439 lnk->next = mergeSpec($1,lnk->next);
443 $$ = mergeSpec($1,$2);
445 | type_specifier { $$ = $1; }
446 | type_specifier declaration_specifiers {
447 /* if the decl $2 is not a specifier */
448 /* find the spec and replace it */
451 while (lnk && !IS_SPEC(lnk->next))
453 lnk->next = mergeSpec($1,lnk->next);
457 $$ = mergeSpec($1,$2);
463 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
467 : declarator { $1->ival = NULL ; }
468 | declarator '=' initializer { $1->ival = $3 ; }
472 storage_class_specifier
475 $$->class = SPECIFIER ;
476 SPEC_TYPEDEF($$) = 1 ;
480 $$->class = SPECIFIER ;
485 $$->class = SPECIFIER ;
490 $$->class = SPECIFIER ;
491 SPEC_SCLS($$) = S_AUTO ;
495 $$->class = SPECIFIER ;
496 SPEC_SCLS($$) = S_REGISTER ;
501 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
506 | type_specifier2 AT CONSTANT
508 /* add this to the storage class specifier */
509 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
510 /* now get the abs addr from value */
511 SPEC_ADDR($1) = (int) floatFromVal ($3) ;
518 $$->class = SPECIFIER ;
519 SPEC_NOUN($$) = V_CHAR ;
523 $$->class = SPECIFIER ;
529 $$->class = SPECIFIER ;
530 SPEC_NOUN($$) = V_INT ;
534 $$->class = SPECIFIER ;
540 $$->class = SPECIFIER ;
545 $$->class = SPECIFIER ;
550 $$->class = SPECIFIER ;
551 SPEC_NOUN($$) = V_VOID ;
555 $$->class = SPECIFIER ;
556 SPEC_SCLS($$) = S_CONSTANT ;
561 $$->class = SPECIFIER ;
562 SPEC_VOLATILE($$) = 1 ;
566 SPEC_NOUN($$) = V_FLOAT;
567 $$->class = SPECIFIER ;
571 $$->class = SPECIFIER ;
572 SPEC_SCLS($$) = S_XDATA ;
576 $$->class = SPECIFIER ;
577 SPEC_SCLS($$) = S_CODE ;
581 $$->class = SPECIFIER ;
582 SPEC_SCLS($$) = S_EEPROM ;
586 $$->class = SPECIFIER ;
587 SPEC_SCLS($$) = S_DATA ;
591 $$->class = SPECIFIER ;
592 SPEC_SCLS($$) = S_IDATA ;
596 $$->class = SPECIFIER ;
597 SPEC_SCLS($$) = S_PDATA ;
601 $$->class = SPECIFIER ;
602 SPEC_NOUN($$) = V_BIT ;
603 SPEC_SCLS($$) = S_BIT ;
608 | struct_or_union_specifier
618 sym = findSym(TypedefTab,NULL,$1) ;
619 $$ = p = copyLinkChain(sym->type);
620 SPEC_TYPEDEF(getSpec(p)) = 0;
628 $$->class = SPECIFIER ;
629 SPEC_NOUN($$) = V_SBIT;
630 SPEC_SCLS($$) = S_SBIT;
634 $$->class = SPECIFIER ;
635 SPEC_NOUN($$) = V_CHAR;
636 SPEC_SCLS($$) = S_SFR ;
641 struct_or_union_specifier
642 : struct_or_union opt_stag '{' struct_declaration_list '}'
646 /* Create a structdef */
648 sdef->fields = reverseSyms($4) ; /* link the fields */
649 sdef->size = compStructSize($1,sdef); /* update size of */
651 /* Create the specifier */
653 $$->class = SPECIFIER ;
654 SPEC_NOUN($$) = V_STRUCT;
655 SPEC_STRUCT($$)= sdef ;
657 | struct_or_union stag
660 $$->class = SPECIFIER ;
661 SPEC_NOUN($$) = V_STRUCT;
662 SPEC_STRUCT($$) = $2 ;
667 : STRUCT { $$ = STRUCT ; }
668 | UNION { $$ = UNION ; }
673 | { /* synthesize a name add to structtable */
674 $$ = newStruct(genSymName(NestLevel)) ;
675 $$->level = NestLevel ;
676 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
681 : identifier { /* add name to structure table */
682 $$ = findSymWithBlock (StructTab,$1,currBlockno);
684 $$ = newStruct($1->name) ;
685 $$->level = NestLevel ;
686 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
691 struct_declaration_list
693 | struct_declaration_list struct_declaration
696 /* go to the end of the chain */
697 while (sym->next) sym = sym->next;
705 : type_specifier_list struct_declarator_list ';'
707 /* add this type to all the symbols */
709 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
711 pointerTypes(sym->type,copyLinkChain($1));
713 sym->type = copyLinkChain($1);
714 sym->etype = getSpec(sym->type);
717 addDecl (sym,0,cloneSpec($1));
724 struct_declarator_list
726 | struct_declarator_list ',' struct_declarator
735 | ':' constant_expr {
736 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
737 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
739 | declarator ':' constant_expr
741 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
746 : ENUM '{' enumerator_list '}' {
748 allocVariables(reverseSyms($3)) ;
749 $$ = copyLinkChain(cenum->type);
751 | ENUM identifier '{' enumerator_list '}' {
754 $2->type = copyLinkChain(cenum->type);
755 $2->etype = getSpec($2->type);
756 /* add this to the enumerator table */
757 if (!(csym=findSym(enumTab,$2,$2->name)) &&
758 (csym && csym->level == $2->level))
759 werror(E_DUPLICATE_TYPEDEF,csym->name);
761 addSym ( enumTab,$2,$2->name,$2->level,$2->block);
763 allocVariables (reverseSyms($4));
764 $$ = copyLinkChain(cenum->type);
765 SPEC_SCLS(getSpec($$)) = 0 ;
770 /* check the enumerator table */
771 if ((csym = findSym(enumTab,$2,$2->name)))
772 $$ = copyLinkChain(csym->type);
775 $$->class = SPECIFIER ;
776 SPEC_NOUN($$) = V_INT ;
779 SPEC_SCLS(getSpec($$)) = 0 ;
785 | enumerator_list ',' enumerator {
792 : identifier opt_assign_expr {
793 /* make the symbol one level up */
795 $1->type = copyLinkChain($2->type);
796 $1->etype= getSpec($1->type);
797 SPEC_ENUM($1->etype) = 1;
804 : '=' constant_expr {
807 val = constExprValue($2,TRUE);
812 sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
813 $$ = cenum = constVal(lbuff);
816 sprintf(lbuff,"%d",0);
817 $$ = cenum = constVal(lbuff);
823 : declarator2_using_reentrant { $$ = $1; }
824 | pointer declarator2_using_reentrant
826 addDecl ($2,0,reverseLink($1));
831 declarator2_using_reentrant
832 : declarator2 { $$ = $1 ; }
833 | declarator2 using_reentrant { addDecl ($1,0,$2); }
838 | '(' declarator ')' { $$ = $2; }
839 | declarator2 '[' ']'
844 DCL_TYPE(p) = ARRAY ;
848 | declarator2 '[' constant_expr ']'
853 p = (tval = constExprValue($3,TRUE))->etype;
854 /* if it is not a constant then Error */
855 if ( SPEC_SCLS(p) != S_LITERAL)
856 werror(E_CONST_EXPECTED) ;
859 DCL_TYPE(p) = ARRAY ;
860 DCL_ELEM(p) = (int) floatFromVal(tval) ;
864 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
865 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
868 addDecl ($1,FUNCTION,NULL) ;
870 $1->hasVargs = IS_VARG($4);
871 $1->args = reverseVal($4) ;
873 /* nest level was incremented to take care of the parms */
878 | declarator2 '(' parameter_identifier_list ')'
880 werror(E_OLD_STYLE,$1->name) ;
882 /* assume it returns an it */
883 $1->type = $1->etype = newIntLink();
889 : far_near_pointer { $$ = $1 ;}
890 | far_near_pointer type_specifier_list
895 | far_near_pointer pointer
900 | far_near_pointer type_specifier_list pointer
903 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
904 DCL_PTR_CONST($1) = SPEC_CONST($2);
905 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
906 switch (SPEC_SCLS($2)) {
908 DCL_TYPE($3) = FPOINTER;
911 DCL_TYPE($3) = IPOINTER ;
914 DCL_TYPE($3) = PPOINTER ;
917 DCL_TYPE($3) = POINTER ;
920 DCL_PTR_CONST($3) = 1;
921 DCL_TYPE($3) = CPOINTER ;
923 DCL_TYPE($3) = EEPPOINTER;
926 werror(W_PTR_TYPE_INVALID);
930 werror (W_PTR_TYPE_INVALID);
939 DCL_TYPE($$) = POINTER ;
947 : _XDATA { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; }
948 | _CODE { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ; DCL_PTR_CONST($$) = 1;}
949 | _PDATA { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; }
950 | _IDATA { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; }
951 | _NEAR { $$ = NULL ; }
952 | _GENERIC { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; }
953 | _EEPROM { $$ = newLink() ; DCL_TYPE($$) = EEPPOINTER ;}
954 | { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; }
959 | type_specifier_list type_specifier { $$ = mergeSpec ($1,$2); }
962 parameter_identifier_list
964 | identifier_list ',' ELIPSIS
969 | identifier_list ',' identifier
978 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
982 : parameter_declaration
983 | parameter_list ',' parameter_declaration
990 parameter_declaration
991 : type_specifier_list declarator
994 pointerTypes($2->type,$1);
996 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1003 $$->etype = getSpec($$->type);
1008 : type_specifier_list { $$ = $1 ;}
1009 | type_specifier_list abstract_declarator
1011 /* go to the end of the list */
1013 pointerTypes($2,$1);
1014 for ( p = $2 ; p->next ; p=p->next);
1021 : pointer { $$ = reverseLink($1); }
1022 | abstract_declarator2
1023 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1026 abstract_declarator2
1027 : '(' abstract_declarator ')' { $$ = $2 ; }
1030 DCL_TYPE($$) = ARRAY ;
1033 | '[' constant_expr ']' {
1036 DCL_TYPE($$) = ARRAY ;
1037 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1039 | abstract_declarator2 '[' ']' {
1041 DCL_TYPE($$) = ARRAY ;
1045 | abstract_declarator2 '[' constant_expr ']'
1049 DCL_TYPE($$) = ARRAY ;
1050 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1053 | '(' ')' { $$ = NULL;}
1054 | '(' parameter_type_list ')' { $$ = NULL;}
1055 | abstract_declarator2 '(' ')'
1056 | abstract_declarator2 '(' parameter_type_list ')'
1060 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1061 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1062 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1067 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1072 | compound_statement
1073 | expression_statement
1074 | selection_statement
1075 | iteration_statement
1078 ast *ex = newNode(INLINEASM,NULL,NULL);
1079 ALLOC_ATOMIC(ex->values.inlineasm,strlen($1));
1080 strcpy(ex->values.inlineasm,$1);
1086 : identifier ':' statement { $$ = createLabel($1,$3); }
1087 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1088 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1091 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1094 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1098 : start_block end_block { $$ = createBlock(NULL,NULL); }
1099 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1101 declaration_list { addSymChain($2); }
1102 end_block { $$ = createBlock($2,NULL) ; }
1104 declaration_list { addSymChain ($2); }
1106 end_block {$$ = createBlock($2,$4) ; }
1107 | error ';' { $$ = NULL ; }
1113 /* if this is typedef declare it immediately */
1114 if ( $1 && IS_TYPEDEF($1->etype)) {
1115 allocVariables ($1);
1122 | declaration_list declaration
1126 /* if this is a typedef */
1127 if ($2 && IS_TYPEDEF($2->etype)) {
1128 allocVariables ($2);
1132 /* get to the end of the previous decl */
1147 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1150 expression_statement
1156 : ELSE statement { $$ = $2 ; }
1162 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1163 | SWITCH '(' expr ')' {
1165 static int swLabel = 0 ;
1167 /* create a node for expression */
1168 ex = newNode(SWITCH,$3,NULL);
1169 STACK_PUSH(swStk,ex); /* save it in the stack */
1170 ex->values.switchVals.swNum = swLabel ;
1172 /* now create the label */
1173 sprintf(lbuff,"_swBrk_%d",swLabel++);
1174 $<sym>$ = newSymbol(lbuff,NestLevel);
1175 /* put label in the break stack */
1176 STACK_PUSH(breakStack,$<sym>$);
1179 /* get back the switch form the stack */
1180 $$ = STACK_POP(swStk) ;
1181 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1182 STACK_POP(breakStack);
1186 while : WHILE { /* create and push the continue , break & body labels */
1187 static int Lblnum = 0 ;
1189 sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1190 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1192 sprintf (lbuff,"_whilebreak_%d",Lblnum);
1193 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1195 sprintf (lbuff,"_whilebody_%d",Lblnum++);
1196 $$ = newSymbol(lbuff,NestLevel);
1199 do : DO { /* create and push the continue , break & body Labels */
1200 static int Lblnum = 0 ;
1203 sprintf(lbuff,"_docontinue_%d",Lblnum);
1204 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1206 sprintf (lbuff,"_dobreak_%d",Lblnum);
1207 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1209 sprintf (lbuff,"_dobody_%d",Lblnum++);
1210 $$ = newSymbol (lbuff,NestLevel);
1212 for : FOR { /* create & push continue, break & body labels */
1213 static int Lblnum = 0 ;
1216 sprintf (lbuff,"_forcontinue_%d",Lblnum);
1217 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1219 sprintf (lbuff,"_forbreak_%d",Lblnum);
1220 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1222 sprintf (lbuff,"_forbody_%d",Lblnum);
1223 $$ = newSymbol(lbuff,NestLevel);
1225 sprintf (lbuff,"_forcond_%d",Lblnum++);
1226 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1230 : while '(' expr ')' statement
1233 $$ = createWhile ( $1, STACK_POP(continueStack),
1234 STACK_POP(breakStack), $3, $5 );
1235 $$->lineno = $1->lineDef ;
1238 | do statement WHILE '(' expr ')' ';'
1241 $$ = createDo ( $1 , STACK_POP(continueStack),
1242 STACK_POP(breakStack), $5, $2);
1243 $$->lineno = $1->lineDef ;
1246 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1250 /* if break or continue statement present
1251 then create a general case loop */
1252 if (STACK_PEEK(continueStack)->isref ||
1253 STACK_PEEK(breakStack)->isref) {
1254 $$ = createFor ($1, STACK_POP(continueStack),
1255 STACK_POP(breakStack) ,
1256 STACK_POP(forStack) ,
1259 $$ = newNode(FOR,$9,NULL);
1260 AST_FOR($$,trueLabel) = $1;
1261 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1262 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1263 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1264 AST_FOR($$,initExpr) = $3;
1265 AST_FOR($$,condExpr) = $5;
1266 AST_FOR($$,loopExpr) = $7;
1279 : GOTO identifier ';' {
1281 $$ = newAst(EX_VALUE,symbolVal($2));
1282 $$ = newNode(GOTO,$$,NULL);
1285 /* make sure continue is in context */
1286 if (STACK_PEEK(continueStack) == NULL) {
1287 werror(E_BREAK_CONTEXT);
1291 $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(continueStack)));
1292 $$ = newNode(GOTO,$$,NULL);
1293 /* mark the continue label as referenced */
1294 STACK_PEEK(continueStack)->isref = 1;
1298 if (STACK_PEEK(breakStack) == NULL) {
1299 werror(E_BREAK_CONTEXT);
1302 $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(breakStack)));
1303 $$ = newNode(GOTO,$$,NULL);
1304 STACK_PEEK(breakStack)->isref = 1;
1307 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1308 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1312 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }
1316 extern unsigned char *yytext;
1318 extern char *filename;
1319 extern int fatalError;
1321 int yyerror(char *s)
1326 fprintf(stderr,"\n%s(%d) %s: token -> '%s' ; column %d\n",