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"
38 extern int yyerror (char *);
40 int NestLevel = 0 ; /* current NestLevel */
41 int stackPtr = 1 ; /* stack pointer */
42 int xstackPtr = 0 ; /* xstack pointer */
44 int blockNo = 0 ; /* sequential block number */
49 char lbuff[1024]; /* local buffer */
51 /* break & continue stacks */
52 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
53 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
54 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
55 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
56 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
58 value *cenum = NULL ; /* current enumeration type chain*/
62 symbol *sym ; /* symbol table pointer */
63 structdef *sdef; /* structure definition */
64 char yychar[SDCC_NAME_MAX+1];
65 sym_link *lnk ; /* declarator or specifier */
66 int yyint; /* integer value returned */
67 value *val ; /* for integer constant */
68 initList *ilist; /* initial list */
69 char yyinline[MAX_INLINEASM]; /* inlined assembler code */
70 ast *asts; /* expression tree */
73 %token <yychar> IDENTIFIER TYPE_NAME
74 %token <val> CONSTANT STRING_LITERAL
76 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
78 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
79 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
80 %token <yyint> XOR_ASSIGN OR_ASSIGN
81 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
82 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
83 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
84 %token STRUCT UNION ENUM ELIPSIS RANGE FAR _XDATA _CODE _GENERIC _NEAR _PDATA _IDATA _EEPROM
85 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
86 %token <yyinline> INLINEASM
87 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
88 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
90 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND
92 %type <yyint> Interrupt_storage
93 %type <sym> identifier declarator declarator2 enumerator_list enumerator
94 %type <sym> struct_declarator
95 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
96 %type <sym> declaration init_declarator_list init_declarator
97 %type <sym> declaration_list identifier_list parameter_identifier_list
98 %type <sym> declarator2_using_reentrant while do for
99 %type <lnk> pointer type_specifier_list type_specifier type_name
100 %type <lnk> storage_class_specifier struct_or_union_specifier
101 %type <lnk> declaration_specifiers sfr_reg_bit type_specifier2
102 %type <lnk> using_reentrant using_reentrant_interrupt enum_specifier
103 %type <lnk> abstract_declarator abstract_declarator2 far_near_pointer far_near
104 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
105 %type <sdef> stag opt_stag
106 %type <asts> primary_expr
107 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
108 %type <asts> additive_expr shift_expr relational_expr equality_expr
109 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
110 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
111 %type <asts> expr argument_expr_list function_definition expr_opt
112 %type <asts> statement_list statement labeled_statement compound_statement
113 %type <asts> expression_statement selection_statement iteration_statement
114 %type <asts> jump_statement function_body else_statement string_literal
115 %type <ilist> initializer initializer_list
116 %type <yyint> unary_operator assignment_operator struct_or_union
123 : external_definition
124 | file external_definition
128 : function_definition { blockNo=0;}
131 && IS_FUNC($1->type))
133 /* The only legal storage classes for
134 * a function prototype (declaration)
135 * are extern and static. extern is the
136 * default. Thus, if this function isn't
137 * explicitly marked static, mark it
141 && IS_SPEC($1->etype)
142 && !SPEC_STAT($1->etype))
144 SPEC_EXTR($1->etype) = 1;
148 allocVariables ($1) ;
149 cleanUpLevel (SymbolTab,1);
154 : declarator function_body { /* function type not specified */
155 /* assume it to be 'int' */
156 addDecl($1,0,newIntLink());
157 $$ = createFunction($1,$2);
159 | declaration_specifiers declarator function_body
161 pointerTypes($2->type,copyLinkChain($1));
163 $$ = createFunction($2,$3);
168 : using_reentrant_interrupt
169 | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2); }
172 using_reentrant_interrupt
175 $$->class = SPECIFIER ;
177 SPEC_BANK($$) = (int) floatFromVal($2);
179 | REENTRANT { $$ = newLink ();
180 $$->class = SPECIFIER ;
183 | CRITICAL { $$ = newLink ();
184 $$->class = SPECIFIER ;
187 | NONBANKED {$$ = newLink ();
188 $$->class = SPECIFIER ;
189 SPEC_NONBANKED($$) = 1;
190 if (SPEC_BANKED($$)) {
191 werror(W_BANKED_WITH_NONBANKED);
194 | BANKED {$$ = newLink ();
195 $$->class = SPECIFIER ;
197 if (SPEC_NONBANKED($$)) {
198 werror(W_BANKED_WITH_NONBANKED);
201 werror(W_BANKED_WITH_STATIC);
207 $$->class = SPECIFIER ;
215 | declaration_list compound_statement
217 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
223 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
224 | CONSTANT { $$ = newAst_VALUE($1); }
226 | '(' expr ')' { $$ = $2 ; }
230 : STRING_LITERAL { $$ = newAst_VALUE($1); }
235 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
236 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
237 $$->left->funcName = 1;}
238 | postfix_expr '(' argument_expr_list ')'
240 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
242 | postfix_expr '.' identifier
244 $3 = newSymbol($3->name,NestLevel);
246 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
247 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
249 | postfix_expr PTR_OP identifier
251 $3 = newSymbol($3->name,NestLevel);
253 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
255 | postfix_expr INC_OP
256 { $$ = newNode(INC_OP,$1,NULL);}
257 | postfix_expr DEC_OP
258 { $$ = newNode(DEC_OP,$1,NULL); }
263 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
268 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
269 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
270 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
271 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
272 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
286 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
291 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
292 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
293 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
297 : multiplicative_expr
298 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
299 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
304 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
305 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
310 | relational_expr '<' shift_expr {
312 newNode('!',newNode(GE_OP,$1,$3),NULL) :
313 newNode('<', $1,$3));
315 | relational_expr '>' shift_expr {
317 newNode('!',newNode(LE_OP,$1,$3),NULL) :
320 | relational_expr LE_OP shift_expr {
322 newNode('!', newNode('>', $1 , $3 ), NULL) :
323 newNode(LE_OP,$1,$3));
325 | relational_expr GE_OP shift_expr {
327 newNode('!', newNode('<', $1 , $3 ), NULL) :
328 newNode(GE_OP,$1,$3));
334 | equality_expr EQ_OP relational_expr {
336 newNode('!',newNode(NE_OP,$1,$3),NULL) :
337 newNode(EQ_OP,$1,$3));
339 | equality_expr NE_OP relational_expr {
341 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
342 newNode(NE_OP,$1,$3));
348 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
353 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
358 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
363 | logical_and_expr AND_OP inclusive_or_expr
364 { $$ = newNode(AND_OP,$1,$3);}
369 | logical_or_expr OR_OP logical_and_expr
370 { $$ = newNode(OR_OP,$1,$3); }
375 | logical_or_expr '?' logical_or_expr ':' conditional_expr
377 $$ = newNode(':',$3,$5) ;
378 $$ = newNode('?',$1,$$) ;
384 | unary_expr assignment_operator assignment_expr
389 $$ = newNode($2,$1,$3);
392 $$ = newNode('=',$1,newNode('*',copyAst($1),$3));
395 $$ = newNode('=',$1,newNode('/',copyAst($1),$3));
398 $$ = newNode('=',$1,newNode('%',copyAst($1),$3));
401 $$ = newNode('=',$1,newNode('+',copyAst($1),$3));
404 $$ = newNode('=',$1,newNode('-',copyAst($1),$3));
407 $$ = newNode('=',$1,newNode(LEFT_OP,copyAst($1),$3));
410 $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3));
413 $$ = newNode('=',$1,newNode('&',copyAst($1),$3));
416 $$ = newNode('=',$1,newNode('^',copyAst($1),$3));
419 $$ = newNode('=',$1,newNode('|',copyAst($1),$3));
444 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
452 : declaration_specifiers ';' { $$ = NULL ; }
453 | declaration_specifiers init_declarator_list ';'
455 /* add the specifier list to the id */
458 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
459 sym_link *lnk = copyLinkChain($1);
460 /* do the pointer stuff */
461 pointerTypes(sym->type,lnk);
462 addDecl (sym,0,lnk) ;
469 declaration_specifiers
470 : storage_class_specifier { $$ = $1; }
471 | storage_class_specifier declaration_specifiers {
472 /* if the decl $2 is not a specifier */
473 /* find the spec and replace it */
476 while (lnk && !IS_SPEC(lnk->next))
478 lnk->next = mergeSpec($1,lnk->next);
482 $$ = mergeSpec($1,$2);
484 | type_specifier { $$ = $1; }
485 | type_specifier declaration_specifiers {
486 /* if the decl $2 is not a specifier */
487 /* find the spec and replace it */
490 while (lnk && !IS_SPEC(lnk->next))
492 lnk->next = mergeSpec($1,lnk->next);
496 $$ = mergeSpec($1,$2);
502 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
506 : declarator { $1->ival = NULL ; }
507 | declarator '=' initializer { $1->ival = $3 ; }
511 storage_class_specifier
514 $$->class = SPECIFIER ;
515 SPEC_TYPEDEF($$) = 1 ;
519 $$->class = SPECIFIER ;
524 $$->class = SPECIFIER ;
529 $$->class = SPECIFIER ;
530 SPEC_SCLS($$) = S_AUTO ;
534 $$->class = SPECIFIER ;
535 SPEC_SCLS($$) = S_REGISTER ;
540 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
545 | type_specifier2 AT constant_expr
547 /* add this to the storage class specifier */
548 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
549 /* now get the abs addr from value */
550 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
557 $$->class = SPECIFIER ;
558 SPEC_NOUN($$) = V_CHAR ;
562 $$->class = SPECIFIER ;
568 $$->class = SPECIFIER ;
569 SPEC_NOUN($$) = V_INT ;
573 $$->class = SPECIFIER ;
579 $$->class = SPECIFIER ;
584 $$->class = SPECIFIER ;
589 $$->class = SPECIFIER ;
590 SPEC_NOUN($$) = V_VOID ;
594 $$->class = SPECIFIER ;
595 SPEC_SCLS($$) = S_CONSTANT ;
600 $$->class = SPECIFIER ;
601 SPEC_VOLATILE($$) = 1 ;
605 SPEC_NOUN($$) = V_FLOAT;
606 $$->class = SPECIFIER ;
610 $$->class = SPECIFIER ;
611 SPEC_SCLS($$) = S_XDATA ;
615 $$->class = SPECIFIER ;
616 SPEC_SCLS($$) = S_CODE ;
620 $$->class = SPECIFIER ;
621 SPEC_SCLS($$) = S_EEPROM ;
625 $$->class = SPECIFIER ;
626 SPEC_SCLS($$) = S_DATA ;
630 $$->class = SPECIFIER ;
631 SPEC_SCLS($$) = S_IDATA ;
635 $$->class = SPECIFIER ;
636 SPEC_SCLS($$) = S_PDATA ;
640 $$->class = SPECIFIER ;
641 SPEC_NOUN($$) = V_BIT ;
642 SPEC_SCLS($$) = S_BIT ;
647 | struct_or_union_specifier
657 sym = findSym(TypedefTab,NULL,$1) ;
658 $$ = p = copyLinkChain(sym->type);
659 SPEC_TYPEDEF(getSpec(p)) = 0;
667 $$->class = SPECIFIER ;
668 SPEC_NOUN($$) = V_SBIT;
669 SPEC_SCLS($$) = S_SBIT;
673 $$->class = SPECIFIER ;
674 SPEC_NOUN($$) = V_CHAR;
675 SPEC_SCLS($$) = S_SFR ;
680 struct_or_union_specifier
681 : struct_or_union opt_stag '{' struct_declaration_list '}'
685 /* Create a structdef */
687 sdef->fields = reverseSyms($4) ; /* link the fields */
688 sdef->size = compStructSize($1,sdef); /* update size of */
690 /* Create the specifier */
692 $$->class = SPECIFIER ;
693 SPEC_NOUN($$) = V_STRUCT;
694 SPEC_STRUCT($$)= sdef ;
696 | struct_or_union stag
699 $$->class = SPECIFIER ;
700 SPEC_NOUN($$) = V_STRUCT;
701 SPEC_STRUCT($$) = $2 ;
706 : STRUCT { $$ = STRUCT ; }
707 | UNION { $$ = UNION ; }
712 | { /* synthesize a name add to structtable */
713 $$ = newStruct(genSymName(NestLevel)) ;
714 $$->level = NestLevel ;
715 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
720 : identifier { /* add name to structure table */
721 $$ = findSymWithBlock (StructTab,$1,currBlockno);
723 $$ = newStruct($1->name) ;
724 $$->level = NestLevel ;
725 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
730 struct_declaration_list
732 | struct_declaration_list struct_declaration
735 /* go to the end of the chain */
736 while (sym->next) sym = sym->next;
744 : type_specifier_list struct_declarator_list ';'
746 /* add this type to all the symbols */
748 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
750 pointerTypes(sym->type,copyLinkChain($1));
752 sym->type = copyLinkChain($1);
753 sym->etype = getSpec(sym->type);
756 addDecl (sym,0,cloneSpec($1));
763 struct_declarator_list
765 | struct_declarator_list ',' struct_declarator
774 | ':' constant_expr {
775 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
776 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
778 | declarator ':' constant_expr
780 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
785 : ENUM '{' enumerator_list '}' {
787 allocVariables(reverseSyms($3)) ;
788 $$ = copyLinkChain(cenum->type);
790 | ENUM identifier '{' enumerator_list '}' {
793 $2->type = copyLinkChain(cenum->type);
794 $2->etype = getSpec($2->type);
795 /* add this to the enumerator table */
796 if (!(csym=findSym(enumTab,$2,$2->name)) &&
797 (csym && csym->level == $2->level))
798 werror(E_DUPLICATE_TYPEDEF,csym->name);
800 addSym ( enumTab,$2,$2->name,$2->level,$2->block);
802 allocVariables (reverseSyms($4));
803 $$ = copyLinkChain(cenum->type);
804 SPEC_SCLS(getSpec($$)) = 0 ;
809 /* check the enumerator table */
810 if ((csym = findSym(enumTab,$2,$2->name)))
811 $$ = copyLinkChain(csym->type);
814 $$->class = SPECIFIER ;
815 SPEC_NOUN($$) = V_INT ;
818 SPEC_SCLS(getSpec($$)) = 0 ;
824 | enumerator_list ',' enumerator {
831 : identifier opt_assign_expr {
832 /* make the symbol one level up */
834 $1->type = copyLinkChain($2->type);
835 $1->etype= getSpec($1->type);
836 SPEC_ENUM($1->etype) = 1;
843 : '=' constant_expr {
846 val = constExprValue($2,TRUE);
851 sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
852 $$ = cenum = constVal(lbuff);
855 sprintf(lbuff,"%d",0);
856 $$ = cenum = constVal(lbuff);
862 : declarator2_using_reentrant { $$ = $1; }
863 | pointer declarator2_using_reentrant
865 addDecl ($2,0,reverseLink($1));
870 declarator2_using_reentrant
871 : declarator2 { $$ = $1 ; }
872 | declarator2 using_reentrant { addDecl ($1,0,$2); }
877 | '(' declarator ')' { $$ = $2; }
878 | declarator2 '[' ']'
883 DCL_TYPE(p) = ARRAY ;
887 | declarator2 '[' constant_expr ']'
892 p = (tval = constExprValue($3,TRUE))->etype;
893 /* if it is not a constant then Error */
894 if ( SPEC_SCLS(p) != S_LITERAL)
895 werror(E_CONST_EXPECTED) ;
898 DCL_TYPE(p) = ARRAY ;
899 DCL_ELEM(p) = (int) floatFromVal(tval) ;
903 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
904 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
907 addDecl ($1,FUNCTION,NULL) ;
909 $1->hasVargs = IS_VARG($4);
910 $1->args = reverseVal($4) ;
912 /* nest level was incremented to take care of the parms */
917 | declarator2 '(' parameter_identifier_list ')'
919 werror(E_OLD_STYLE,$1->name) ;
921 /* assume it returns an it */
922 $1->type = $1->etype = newIntLink();
928 : far_near_pointer { $$ = $1 ;}
929 | far_near_pointer type_specifier_list
934 | far_near_pointer pointer
939 | far_near_pointer type_specifier_list pointer
942 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
943 DCL_PTR_CONST($1) = SPEC_CONST($2);
944 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
945 switch (SPEC_SCLS($2)) {
947 DCL_TYPE($3) = FPOINTER;
950 DCL_TYPE($3) = IPOINTER ;
953 DCL_TYPE($3) = PPOINTER ;
956 DCL_TYPE($3) = POINTER ;
959 DCL_PTR_CONST($3) = 1;
960 DCL_TYPE($3) = CPOINTER ;
962 DCL_TYPE($3) = EEPPOINTER;
965 werror(W_PTR_TYPE_INVALID);
969 werror (W_PTR_TYPE_INVALID);
978 DCL_TYPE($$) = POINTER ;
986 : _XDATA { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; }
987 | _CODE { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ; DCL_PTR_CONST($$) = 1;}
988 | _PDATA { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; }
989 | _IDATA { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; }
990 | _NEAR { $$ = NULL ; }
991 | _GENERIC { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; }
992 | _EEPROM { $$ = newLink() ; DCL_TYPE($$) = EEPPOINTER ;}
993 | { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; }
998 | type_specifier_list type_specifier { $$ = mergeSpec ($1,$2); }
1001 parameter_identifier_list
1003 | identifier_list ',' ELIPSIS
1008 | identifier_list ',' identifier
1017 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1021 : parameter_declaration
1022 | parameter_list ',' parameter_declaration
1029 parameter_declaration
1030 : type_specifier_list declarator
1033 pointerTypes($2->type,$1);
1035 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1042 $$->etype = getSpec($$->type);
1047 : type_specifier_list { $$ = $1 ;}
1048 | type_specifier_list abstract_declarator
1050 /* go to the end of the list */
1052 pointerTypes($2,$1);
1053 for ( p = $2 ; p->next ; p=p->next);
1060 : pointer { $$ = reverseLink($1); }
1061 | abstract_declarator2
1062 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1065 abstract_declarator2
1066 : '(' abstract_declarator ')' { $$ = $2 ; }
1069 DCL_TYPE($$) = ARRAY ;
1072 | '[' constant_expr ']' {
1075 DCL_TYPE($$) = ARRAY ;
1076 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1078 | abstract_declarator2 '[' ']' {
1080 DCL_TYPE($$) = ARRAY ;
1084 | abstract_declarator2 '[' constant_expr ']'
1088 DCL_TYPE($$) = ARRAY ;
1089 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1092 | '(' ')' { $$ = NULL;}
1093 | '(' parameter_type_list ')' { $$ = NULL;}
1094 | abstract_declarator2 '(' ')'
1095 | abstract_declarator2 '(' parameter_type_list ')'
1099 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1100 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1101 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1106 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1111 | compound_statement
1112 | expression_statement
1113 | selection_statement
1114 | iteration_statement
1117 ast *ex = newNode(INLINEASM,NULL,NULL);
1118 ex->values.inlineasm = Safe_calloc(1,strlen($1)+1);
1119 strcpy(ex->values.inlineasm,$1);
1125 : identifier ':' statement { $$ = createLabel($1,$3); }
1126 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1127 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1130 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1133 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1137 : start_block end_block { $$ = createBlock(NULL,NULL); }
1138 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1140 declaration_list { addSymChain($2); }
1141 end_block { $$ = createBlock($2,NULL) ; }
1143 declaration_list { addSymChain ($2); }
1145 end_block {$$ = createBlock($2,$4) ; }
1146 | error ';' { $$ = NULL ; }
1152 /* if this is typedef declare it immediately */
1153 if ( $1 && IS_TYPEDEF($1->etype)) {
1154 allocVariables ($1);
1161 | declaration_list declaration
1165 /* if this is a typedef */
1166 if ($2 && IS_TYPEDEF($2->etype)) {
1167 allocVariables ($2);
1171 /* get to the end of the previous decl */
1186 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1189 expression_statement
1195 : ELSE statement { $$ = $2 ; }
1201 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1202 | SWITCH '(' expr ')' {
1204 static int swLabel = 0 ;
1206 /* create a node for expression */
1207 ex = newNode(SWITCH,$3,NULL);
1208 STACK_PUSH(swStk,ex); /* save it in the stack */
1209 ex->values.switchVals.swNum = swLabel ;
1211 /* now create the label */
1212 sprintf(lbuff,"_swBrk_%d",swLabel++);
1213 $<sym>$ = newSymbol(lbuff,NestLevel);
1214 /* put label in the break stack */
1215 STACK_PUSH(breakStack,$<sym>$);
1218 /* get back the switch form the stack */
1219 $$ = STACK_POP(swStk) ;
1220 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1221 STACK_POP(breakStack);
1225 while : WHILE { /* create and push the continue , break & body labels */
1226 static int Lblnum = 0 ;
1228 sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1229 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1231 sprintf (lbuff,"_whilebreak_%d",Lblnum);
1232 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1234 sprintf (lbuff,"_whilebody_%d",Lblnum++);
1235 $$ = newSymbol(lbuff,NestLevel);
1238 do : DO { /* create and push the continue , break & body Labels */
1239 static int Lblnum = 0 ;
1242 sprintf(lbuff,"_docontinue_%d",Lblnum);
1243 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1245 sprintf (lbuff,"_dobreak_%d",Lblnum);
1246 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1248 sprintf (lbuff,"_dobody_%d",Lblnum++);
1249 $$ = newSymbol (lbuff,NestLevel);
1251 for : FOR { /* create & push continue, break & body labels */
1252 static int Lblnum = 0 ;
1255 sprintf (lbuff,"_forcontinue_%d",Lblnum);
1256 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1258 sprintf (lbuff,"_forbreak_%d",Lblnum);
1259 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1261 sprintf (lbuff,"_forbody_%d",Lblnum);
1262 $$ = newSymbol(lbuff,NestLevel);
1264 sprintf (lbuff,"_forcond_%d",Lblnum++);
1265 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1269 : while '(' expr ')' statement
1272 $$ = createWhile ( $1, STACK_POP(continueStack),
1273 STACK_POP(breakStack), $3, $5 );
1274 $$->lineno = $1->lineDef ;
1277 | do statement WHILE '(' expr ')' ';'
1280 $$ = createDo ( $1 , STACK_POP(continueStack),
1281 STACK_POP(breakStack), $5, $2);
1282 $$->lineno = $1->lineDef ;
1285 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1289 /* if break or continue statement present
1290 then create a general case loop */
1291 if (STACK_PEEK(continueStack)->isref ||
1292 STACK_PEEK(breakStack)->isref) {
1293 $$ = createFor ($1, STACK_POP(continueStack),
1294 STACK_POP(breakStack) ,
1295 STACK_POP(forStack) ,
1298 $$ = newNode(FOR,$9,NULL);
1299 AST_FOR($$,trueLabel) = $1;
1300 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1301 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1302 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1303 AST_FOR($$,initExpr) = $3;
1304 AST_FOR($$,condExpr) = $5;
1305 AST_FOR($$,loopExpr) = $7;
1318 : GOTO identifier ';' {
1320 $$ = newAst_VALUE(symbolVal($2));
1321 $$ = newNode(GOTO,$$,NULL);
1324 /* make sure continue is in context */
1325 if (STACK_PEEK(continueStack) == NULL) {
1326 werror(E_BREAK_CONTEXT);
1330 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1331 $$ = newNode(GOTO,$$,NULL);
1332 /* mark the continue label as referenced */
1333 STACK_PEEK(continueStack)->isref = 1;
1337 if (STACK_PEEK(breakStack) == NULL) {
1338 werror(E_BREAK_CONTEXT);
1341 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1342 $$ = newNode(GOTO,$$,NULL);
1343 STACK_PEEK(breakStack)->isref = 1;
1346 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1347 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1351 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }