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
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 ;
171 $$->class = SPECIFIER ;
179 | declaration_list compound_statement
181 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
187 : identifier { $$ = newAst(EX_VALUE,symbolVal($1)); }
188 | CONSTANT { $$ = newAst(EX_VALUE,$1); }
190 | '(' expr ')' { $$ = $2 ; }
194 : STRING_LITERAL { $$ = newAst(EX_VALUE,$1); }
199 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
200 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
201 $$->left->funcName = 1;}
202 | postfix_expr '(' argument_expr_list ')'
204 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
206 | postfix_expr '.' identifier
208 $3 = newSymbol($3->name,NestLevel);
210 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst(EX_VALUE,symbolVal($3)));
211 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
213 | postfix_expr PTR_OP identifier
215 $3 = newSymbol($3->name,NestLevel);
217 $$ = newNode(PTR_OP,$1,newAst(EX_VALUE,symbolVal($3)));
219 | postfix_expr INC_OP
220 { $$ = newNode(INC_OP,$1,NULL);}
221 | postfix_expr DEC_OP
222 { $$ = newNode(DEC_OP,$1,NULL); }
227 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
232 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
233 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
234 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
235 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
236 | SIZEOF '(' type_name ')' { $$ = newAst(EX_VALUE,sizeofOp($3)); }
250 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst(EX_LINK,$2),$4); }
255 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
256 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
257 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
261 : multiplicative_expr
262 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
263 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
268 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
269 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
274 | relational_expr '<' shift_expr { $$ = newNode('<',$1,$3); }
275 | relational_expr '>' shift_expr { $$ = newNode('>',$1,$3); }
276 | relational_expr LE_OP shift_expr {
277 /* $$ = newNode(LE_OP,$1,$3); */
278 /* getting 8051 specific here : will change
279 LE_OP operation to "not greater than" i.e.
280 ( a <= b ) === ( ! ( a > b )) */
282 newNode('>', $1 , $3 ),
285 | relational_expr GE_OP shift_expr {
286 /* $$ = newNode(GE_OP,$1,$3) ; */
287 /* getting 8051 specific here : will change
288 GE_OP operation to "not less than" i.e.
289 ( a >= b ) === ( ! ( a < b )) */
291 newNode('<', $1 , $3 ),
298 | equality_expr EQ_OP relational_expr { $$ = newNode(EQ_OP,$1,$3);}
299 | equality_expr NE_OP relational_expr
301 /* $$ = newNode(NE_OP,$1,$3); */
303 expr1 != expr2 is equivalent to
304 (! expr1 == expr2) */
306 newNode(EQ_OP,$1,$3),
313 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
318 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
323 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
328 | logical_and_expr AND_OP inclusive_or_expr
329 { $$ = newNode(AND_OP,$1,$3);}
334 | logical_or_expr OR_OP logical_and_expr
335 { $$ = newNode(OR_OP,$1,$3); }
340 | logical_or_expr '?' logical_or_expr ':' conditional_expr
342 $$ = newNode(':',$3,$5) ;
343 $$ = newNode('?',$1,$$) ;
349 | unary_expr assignment_operator assignment_expr
354 $$ = newNode($2,$1,$3);
357 $$ = newNode('=',$1,newNode('*',copyAst($1),$3));
360 $$ = newNode('=',$1,newNode('/',copyAst($1),$3));
363 $$ = newNode('=',$1,newNode('+',copyAst($1),$3));
366 $$ = newNode('=',$1,newNode('-',copyAst($1),$3));
369 $$ = newNode('=',$1,newNode(LEFT_OP,copyAst($1),$3));
372 $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3));
375 $$ = newNode('=',$1,newNode('&',copyAst($1),$3));
378 $$ = newNode('=',$1,newNode('^',copyAst($1),$3));
381 $$ = newNode('=',$1,newNode('|',copyAst($1),$3));
406 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
414 : declaration_specifiers ';' { $$ = NULL ; }
415 | declaration_specifiers init_declarator_list ';'
417 /* add the specifier list to the id */
420 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
421 link *lnk = copyLinkChain($1);
422 /* do the pointer stuff */
423 pointerTypes(sym->type,lnk);
424 addDecl (sym,0,lnk) ;
431 declaration_specifiers
432 : storage_class_specifier { $$ = $1; }
433 | storage_class_specifier declaration_specifiers {
434 /* if the decl $2 is not a specifier */
435 /* find the spec and replace it */
438 while (lnk && !IS_SPEC(lnk->next))
440 lnk->next = mergeSpec($1,lnk->next);
444 $$ = mergeSpec($1,$2);
446 | type_specifier { $$ = $1; }
447 | type_specifier declaration_specifiers {
448 /* if the decl $2 is not a specifier */
449 /* find the spec and replace it */
452 while (lnk && !IS_SPEC(lnk->next))
454 lnk->next = mergeSpec($1,lnk->next);
458 $$ = mergeSpec($1,$2);
464 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
468 : declarator { $1->ival = NULL ; }
469 | declarator '=' initializer { $1->ival = $3 ; }
473 storage_class_specifier
476 $$->class = SPECIFIER ;
477 SPEC_TYPEDEF($$) = 1 ;
481 $$->class = SPECIFIER ;
486 $$->class = SPECIFIER ;
491 $$->class = SPECIFIER ;
492 SPEC_SCLS($$) = S_AUTO ;
496 $$->class = SPECIFIER ;
497 SPEC_SCLS($$) = S_REGISTER ;
502 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
507 | type_specifier2 AT CONSTANT
509 /* add this to the storage class specifier */
510 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
511 /* now get the abs addr from value */
512 SPEC_ADDR($1) = (int) floatFromVal ($3) ;
519 $$->class = SPECIFIER ;
520 SPEC_NOUN($$) = V_CHAR ;
524 $$->class = SPECIFIER ;
530 $$->class = SPECIFIER ;
531 SPEC_NOUN($$) = V_INT ;
535 $$->class = SPECIFIER ;
541 $$->class = SPECIFIER ;
546 $$->class = SPECIFIER ;
551 $$->class = SPECIFIER ;
552 SPEC_NOUN($$) = V_VOID ;
556 $$->class = SPECIFIER ;
557 SPEC_SCLS($$) = S_CONSTANT ;
562 $$->class = SPECIFIER ;
563 SPEC_VOLATILE($$) = 1 ;
567 SPEC_NOUN($$) = V_FLOAT;
568 $$->class = SPECIFIER ;
572 $$->class = SPECIFIER ;
573 SPEC_SCLS($$) = S_XDATA ;
577 $$->class = SPECIFIER ;
578 SPEC_SCLS($$) = S_CODE ;
582 $$->class = SPECIFIER ;
583 SPEC_SCLS($$) = S_EEPROM ;
587 $$->class = SPECIFIER ;
588 SPEC_SCLS($$) = S_DATA ;
592 $$->class = SPECIFIER ;
593 SPEC_SCLS($$) = S_IDATA ;
597 $$->class = SPECIFIER ;
598 SPEC_SCLS($$) = S_PDATA ;
602 $$->class = SPECIFIER ;
603 SPEC_NOUN($$) = V_BIT ;
604 SPEC_SCLS($$) = S_BIT ;
609 | struct_or_union_specifier
619 sym = findSym(TypedefTab,NULL,$1) ;
620 $$ = p = copyLinkChain(sym->type);
621 SPEC_TYPEDEF(getSpec(p)) = 0;
629 $$->class = SPECIFIER ;
630 SPEC_NOUN($$) = V_SBIT;
631 SPEC_SCLS($$) = S_SBIT;
635 $$->class = SPECIFIER ;
636 SPEC_NOUN($$) = V_CHAR;
637 SPEC_SCLS($$) = S_SFR ;
642 struct_or_union_specifier
643 : struct_or_union opt_stag '{' struct_declaration_list '}'
647 /* Create a structdef */
649 sdef->fields = reverseSyms($4) ; /* link the fields */
650 sdef->size = compStructSize($1,sdef); /* update size of */
652 /* Create the specifier */
654 $$->class = SPECIFIER ;
655 SPEC_NOUN($$) = V_STRUCT;
656 SPEC_STRUCT($$)= sdef ;
658 | struct_or_union stag
661 $$->class = SPECIFIER ;
662 SPEC_NOUN($$) = V_STRUCT;
663 SPEC_STRUCT($$) = $2 ;
668 : STRUCT { $$ = STRUCT ; }
669 | UNION { $$ = UNION ; }
674 | { /* synthesize a name add to structtable */
675 $$ = newStruct(genSymName(NestLevel)) ;
676 $$->level = NestLevel ;
677 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
682 : identifier { /* add name to structure table */
683 $$ = findSymWithBlock (StructTab,$1,currBlockno);
685 $$ = newStruct($1->name) ;
686 $$->level = NestLevel ;
687 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
692 struct_declaration_list
694 | struct_declaration_list struct_declaration
697 /* go to the end of the chain */
698 while (sym->next) sym = sym->next;
706 : type_specifier_list struct_declarator_list ';'
708 /* add this type to all the symbols */
710 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
712 pointerTypes(sym->type,copyLinkChain($1));
714 sym->type = copyLinkChain($1);
715 sym->etype = getSpec(sym->type);
718 addDecl (sym,0,cloneSpec($1));
725 struct_declarator_list
727 | struct_declarator_list ',' struct_declarator
736 | ':' constant_expr {
737 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
738 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
740 | declarator ':' constant_expr
742 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
747 : ENUM '{' enumerator_list '}' {
749 allocVariables(reverseSyms($3)) ;
750 $$ = copyLinkChain(cenum->type);
752 | ENUM identifier '{' enumerator_list '}' {
755 $2->type = copyLinkChain(cenum->type);
756 $2->etype = getSpec($2->type);
757 /* add this to the enumerator table */
758 if (!(csym=findSym(enumTab,$2,$2->name)) &&
759 (csym && csym->level == $2->level))
760 werror(E_DUPLICATE_TYPEDEF,csym->name);
762 addSym ( enumTab,$2,$2->name,$2->level,$2->block);
764 allocVariables (reverseSyms($4));
765 $$ = copyLinkChain(cenum->type);
766 SPEC_SCLS(getSpec($$)) = 0 ;
771 /* check the enumerator table */
772 if ((csym = findSym(enumTab,$2,$2->name)))
773 $$ = copyLinkChain(csym->type);
776 $$->class = SPECIFIER ;
777 SPEC_NOUN($$) = V_INT ;
780 SPEC_SCLS(getSpec($$)) = 0 ;
786 | enumerator_list ',' enumerator {
793 : identifier opt_assign_expr {
794 /* make the symbol one level up */
796 $1->type = copyLinkChain($2->type);
797 $1->etype= getSpec($1->type);
798 SPEC_ENUM($1->etype) = 1;
805 : '=' constant_expr {
808 val = constExprValue($2,TRUE);
813 sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
814 $$ = cenum = constVal(lbuff);
817 sprintf(lbuff,"%d",0);
818 $$ = cenum = constVal(lbuff);
824 : declarator2_using_reentrant { $$ = $1; }
825 | pointer declarator2_using_reentrant
827 addDecl ($2,0,reverseLink($1));
832 declarator2_using_reentrant
833 : declarator2 { $$ = $1 ; }
834 | declarator2 using_reentrant { addDecl ($1,0,$2); }
839 | '(' declarator ')' { $$ = $2; }
840 | declarator2 '[' ']'
845 DCL_TYPE(p) = ARRAY ;
849 | declarator2 '[' constant_expr ']'
854 p = (tval = constExprValue($3,TRUE))->etype;
855 /* if it is not a constant then Error */
856 if ( SPEC_SCLS(p) != S_LITERAL)
857 werror(E_CONST_EXPECTED) ;
860 DCL_TYPE(p) = ARRAY ;
861 DCL_ELEM(p) = (int) floatFromVal(tval) ;
865 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
866 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
869 addDecl ($1,FUNCTION,NULL) ;
871 $1->hasVargs = IS_VARG($4);
872 $1->args = reverseVal($4) ;
874 /* nest level was incremented to take care of the parms */
879 | declarator2 '(' parameter_identifier_list ')'
881 werror(E_OLD_STYLE,$1->name) ;
883 /* assume it returns an it */
884 $1->type = $1->etype = newIntLink();
890 : far_near_pointer { $$ = $1 ;}
891 | far_near_pointer type_specifier_list
896 | far_near_pointer pointer
901 | far_near_pointer type_specifier_list pointer
904 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
905 DCL_PTR_CONST($1) = SPEC_CONST($2);
906 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
907 switch (SPEC_SCLS($2)) {
909 DCL_TYPE($3) = FPOINTER;
912 DCL_TYPE($3) = IPOINTER ;
915 DCL_TYPE($3) = PPOINTER ;
918 DCL_TYPE($3) = POINTER ;
921 DCL_PTR_CONST($3) = 1;
922 DCL_TYPE($3) = CPOINTER ;
924 DCL_TYPE($3) = EEPPOINTER;
927 werror(W_PTR_TYPE_INVALID);
931 werror (W_PTR_TYPE_INVALID);
940 DCL_TYPE($$) = POINTER ;
948 : _XDATA { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; }
949 | _CODE { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ; DCL_PTR_CONST($$) = 1;}
950 | _PDATA { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; }
951 | _IDATA { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; }
952 | _NEAR { $$ = NULL ; }
953 | _GENERIC { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; }
954 | _EEPROM { $$ = newLink() ; DCL_TYPE($$) = EEPPOINTER ;}
955 | { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; }
960 | type_specifier_list type_specifier { $$ = mergeSpec ($1,$2); }
963 parameter_identifier_list
965 | identifier_list ',' ELIPSIS
970 | identifier_list ',' identifier
979 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
983 : parameter_declaration
984 | parameter_list ',' parameter_declaration
991 parameter_declaration
992 : type_specifier_list declarator
995 pointerTypes($2->type,$1);
997 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1004 $$->etype = getSpec($$->type);
1009 : type_specifier_list { $$ = $1 ;}
1010 | type_specifier_list abstract_declarator
1012 /* go to the end of the list */
1014 pointerTypes($2,$1);
1015 for ( p = $2 ; p->next ; p=p->next);
1022 : pointer { $$ = reverseLink($1); }
1023 | abstract_declarator2
1024 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1027 abstract_declarator2
1028 : '(' abstract_declarator ')' { $$ = $2 ; }
1031 DCL_TYPE($$) = ARRAY ;
1034 | '[' constant_expr ']' {
1037 DCL_TYPE($$) = ARRAY ;
1038 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1040 | abstract_declarator2 '[' ']' {
1042 DCL_TYPE($$) = ARRAY ;
1046 | abstract_declarator2 '[' constant_expr ']'
1050 DCL_TYPE($$) = ARRAY ;
1051 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1054 | '(' ')' { $$ = NULL;}
1055 | '(' parameter_type_list ')' { $$ = NULL;}
1056 | abstract_declarator2 '(' ')'
1057 | abstract_declarator2 '(' parameter_type_list ')'
1061 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1062 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1063 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1068 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1073 | compound_statement
1074 | expression_statement
1075 | selection_statement
1076 | iteration_statement
1079 ast *ex = newNode(INLINEASM,NULL,NULL);
1080 ALLOC_ATOMIC(ex->values.inlineasm,strlen($1));
1081 strcpy(ex->values.inlineasm,$1);
1087 : identifier ':' statement { $$ = createLabel($1,$3); }
1088 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1089 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1092 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1095 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1099 : start_block end_block { $$ = createBlock(NULL,NULL); }
1100 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1102 declaration_list { addSymChain($2); }
1103 end_block { $$ = createBlock($2,NULL) ; }
1105 declaration_list { addSymChain ($2); }
1107 end_block {$$ = createBlock($2,$4) ; }
1108 | error ';' { $$ = NULL ; }
1114 /* if this is typedef declare it immediately */
1115 if ( $1 && IS_TYPEDEF($1->etype)) {
1116 allocVariables ($1);
1123 | declaration_list declaration
1127 /* if this is a typedef */
1128 if ($2 && IS_TYPEDEF($2->etype)) {
1129 allocVariables ($2);
1133 /* get to the end of the previous decl */
1148 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1151 expression_statement
1157 : ELSE statement { $$ = $2 ; }
1163 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1164 | SWITCH '(' expr ')' {
1166 static int swLabel = 0 ;
1168 /* create a node for expression */
1169 ex = newNode(SWITCH,$3,NULL);
1170 STACK_PUSH(swStk,ex); /* save it in the stack */
1171 ex->values.switchVals.swNum = swLabel ;
1173 /* now create the label */
1174 sprintf(lbuff,"_swBrk_%d",swLabel++);
1175 $<sym>$ = newSymbol(lbuff,NestLevel);
1176 /* put label in the break stack */
1177 STACK_PUSH(breakStack,$<sym>$);
1180 /* get back the switch form the stack */
1181 $$ = STACK_POP(swStk) ;
1182 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1183 STACK_POP(breakStack);
1187 while : WHILE { /* create and push the continue , break & body labels */
1188 static int Lblnum = 0 ;
1190 sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1191 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1193 sprintf (lbuff,"_whilebreak_%d",Lblnum);
1194 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1196 sprintf (lbuff,"_whilebody_%d",Lblnum++);
1197 $$ = newSymbol(lbuff,NestLevel);
1200 do : DO { /* create and push the continue , break & body Labels */
1201 static int Lblnum = 0 ;
1204 sprintf(lbuff,"_docontinue_%d",Lblnum);
1205 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1207 sprintf (lbuff,"_dobreak_%d",Lblnum);
1208 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1210 sprintf (lbuff,"_dobody_%d",Lblnum++);
1211 $$ = newSymbol (lbuff,NestLevel);
1213 for : FOR { /* create & push continue, break & body labels */
1214 static int Lblnum = 0 ;
1217 sprintf (lbuff,"_forcontinue_%d",Lblnum);
1218 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1220 sprintf (lbuff,"_forbreak_%d",Lblnum);
1221 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1223 sprintf (lbuff,"_forbody_%d",Lblnum);
1224 $$ = newSymbol(lbuff,NestLevel);
1226 sprintf (lbuff,"_forcond_%d",Lblnum++);
1227 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1231 : while '(' expr ')' statement
1234 $$ = createWhile ( $1, STACK_POP(continueStack),
1235 STACK_POP(breakStack), $3, $5 );
1236 $$->lineno = $1->lineDef ;
1239 | do statement WHILE '(' expr ')' ';'
1242 $$ = createDo ( $1 , STACK_POP(continueStack),
1243 STACK_POP(breakStack), $5, $2);
1244 $$->lineno = $1->lineDef ;
1247 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1251 /* if break or continue statement present
1252 then create a general case loop */
1253 if (STACK_PEEK(continueStack)->isref ||
1254 STACK_PEEK(breakStack)->isref) {
1255 $$ = createFor ($1, STACK_POP(continueStack),
1256 STACK_POP(breakStack) ,
1257 STACK_POP(forStack) ,
1260 $$ = newNode(FOR,$9,NULL);
1261 AST_FOR($$,trueLabel) = $1;
1262 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1263 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1264 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1265 AST_FOR($$,initExpr) = $3;
1266 AST_FOR($$,condExpr) = $5;
1267 AST_FOR($$,loopExpr) = $7;
1280 : GOTO identifier ';' {
1282 $$ = newAst(EX_VALUE,symbolVal($2));
1283 $$ = newNode(GOTO,$$,NULL);
1286 /* make sure continue is in context */
1287 if (STACK_PEEK(continueStack) == NULL) {
1288 werror(E_BREAK_CONTEXT);
1292 $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(continueStack)));
1293 $$ = newNode(GOTO,$$,NULL);
1294 /* mark the continue label as referenced */
1295 STACK_PEEK(continueStack)->isref = 1;
1299 if (STACK_PEEK(breakStack) == NULL) {
1300 werror(E_BREAK_CONTEXT);
1303 $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(breakStack)));
1304 $$ = newNode(GOTO,$$,NULL);
1305 STACK_PEEK(breakStack)->isref = 1;
1308 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1309 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1313 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }
1317 extern unsigned char *yytext;
1319 extern char *filename;
1320 extern int fatalError;
1322 int yyerror(char *s)
1327 fprintf(stderr,"\n%s(%d) %s: token -> '%s' ; column %d\n",