1 /*-----------------------------------------------------------------------
3 SDCC.y - parser definition file for sdcc :
4 Written By : Sandeep Dutta . sandeep.dutta@usa.net (1997)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
28 #include "SDCCglobl.h"
30 #include "SDCChasht.h"
36 extern int yyerror (char *);
38 int NestLevel = 0 ; /* current NestLevel */
39 int stackPtr = 1 ; /* stack pointer */
40 int xstackPtr = 0 ; /* xstack pointer */
42 int blockNo = 0 ; /* sequential block number */
47 char lbuff[1024]; /* local buffer */
49 /* break & continue stacks */
50 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
51 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
52 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
53 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
54 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
56 value *cenum = NULL ; /* current enumeration type chain*/
60 symbol *sym ; /* symbol table pointer */
61 structdef *sdef; /* structure definition */
62 char yychar[SDCC_NAME_MAX+1];
63 link *lnk ; /* declarator or specifier */
64 int yyint; /* integer value returned */
65 value *val ; /* for integer constant */
66 initList *ilist; /* initial list */
67 char yyinline[MAX_INLINEASM]; /* inlined assembler code */
68 ast *asts; /* expression tree */
71 %token <yychar> IDENTIFIER TYPE_NAME
72 %token <val> CONSTANT STRING_LITERAL
74 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
76 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
77 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
78 %token <yyint> XOR_ASSIGN OR_ASSIGN
79 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
80 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
81 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
82 %token STRUCT UNION ENUM ELIPSIS RANGE FAR _XDATA _CODE _GENERIC _NEAR _PDATA _IDATA _EEPROM
83 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
84 %token <yyinline> INLINEASM
85 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
86 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
88 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND
90 %type <yyint> Interrupt_storage
91 %type <sym> identifier declarator declarator2 enumerator_list enumerator
92 %type <sym> struct_declarator
93 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
94 %type <sym> declaration init_declarator_list init_declarator
95 %type <sym> declaration_list identifier_list parameter_identifier_list
96 %type <sym> declarator2_using_reentrant while do for
97 %type <lnk> pointer type_specifier_list type_specifier type_name
98 %type <lnk> storage_class_specifier struct_or_union_specifier
99 %type <lnk> declaration_specifiers sfr_reg_bit type_specifier2
100 %type <lnk> using_reentrant using_reentrant_interrupt enum_specifier
101 %type <lnk> abstract_declarator abstract_declarator2 far_near_pointer far_near
102 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
103 %type <sdef> stag opt_stag
104 %type <asts> primary_expr
105 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
106 %type <asts> additive_expr shift_expr relational_expr equality_expr
107 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
108 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
109 %type <asts> expr argument_expr_list function_definition expr_opt
110 %type <asts> statement_list statement labeled_statement compound_statement
111 %type <asts> expression_statement selection_statement iteration_statement
112 %type <asts> jump_statement function_body else_statement string_literal
113 %type <ilist> initializer initializer_list
114 %type <yyint> unary_operator assignment_operator struct_or_union
121 : external_definition
122 | file external_definition
126 : function_definition { blockNo=0;}
129 && IS_FUNC($1->type))
131 /* The only legal storage classes for
132 * a function prototype (declaration)
133 * are extern and static. extern is the
134 * default. Thus, if this function isn't
135 * explicitly marked static, mark it
139 && IS_SPEC($1->etype)
140 && !SPEC_STAT($1->etype))
142 SPEC_EXTR($1->etype) = 1;
146 allocVariables ($1) ;
147 cleanUpLevel (SymbolTab,1);
152 : declarator function_body { /* function type not specified */
153 /* assume it to be 'int' */
154 addDecl($1,0,newIntLink());
155 $$ = createFunction($1,$2);
157 | declaration_specifiers declarator function_body
159 pointerTypes($2->type,copyLinkChain($1));
161 $$ = createFunction($2,$3);
166 : using_reentrant_interrupt
167 | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2); }
170 using_reentrant_interrupt
173 $$->class = SPECIFIER ;
175 SPEC_BANK($$) = (int) floatFromVal($2);
177 | REENTRANT { $$ = newLink ();
178 $$->class = SPECIFIER ;
181 | CRITICAL { $$ = newLink ();
182 $$->class = SPECIFIER ;
185 | NONBANKED {$$ = newLink ();
186 $$->class = SPECIFIER ;
187 SPEC_NONBANKED($$) = 1;
188 if (SPEC_BANKED($$)) {
189 werror(W_BANKED_WITH_NONBANKED);
192 | BANKED {$$ = newLink ();
193 $$->class = SPECIFIER ;
195 if (SPEC_NONBANKED($$)) {
196 werror(W_BANKED_WITH_NONBANKED);
199 werror(W_BANKED_WITH_STATIC);
205 $$->class = SPECIFIER ;
213 | declaration_list compound_statement
215 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
221 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
222 | CONSTANT { $$ = newAst_VALUE($1); }
224 | '(' expr ')' { $$ = $2 ; }
228 : STRING_LITERAL { $$ = newAst_VALUE($1); }
233 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
234 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
235 $$->left->funcName = 1;}
236 | postfix_expr '(' argument_expr_list ')'
238 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
240 | postfix_expr '.' identifier
242 $3 = newSymbol($3->name,NestLevel);
244 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
245 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
247 | postfix_expr PTR_OP identifier
249 $3 = newSymbol($3->name,NestLevel);
251 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
253 | postfix_expr INC_OP
254 { $$ = newNode(INC_OP,$1,NULL);}
255 | postfix_expr DEC_OP
256 { $$ = newNode(DEC_OP,$1,NULL); }
261 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
266 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
267 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
268 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
269 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
270 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
284 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
289 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
290 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
291 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
295 : multiplicative_expr
296 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
297 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
302 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
303 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
308 | relational_expr '<' shift_expr {
310 newNode('!',newNode(GE_OP,$1,$3),NULL) :
311 newNode('<', $1,$3));
313 | relational_expr '>' shift_expr {
315 newNode('!',newNode(LE_OP,$1,$3),NULL) :
318 | relational_expr LE_OP shift_expr {
320 newNode('!', newNode('>', $1 , $3 ), NULL) :
321 newNode(LE_OP,$1,$3));
323 | relational_expr GE_OP shift_expr {
325 newNode('!', newNode('<', $1 , $3 ), NULL) :
326 newNode(GE_OP,$1,$3));
332 | equality_expr EQ_OP relational_expr {
334 newNode('!',newNode(NE_OP,$1,$3),NULL) :
335 newNode(EQ_OP,$1,$3));
337 | equality_expr NE_OP relational_expr {
339 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
340 newNode(NE_OP,$1,$3));
346 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
351 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
356 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
361 | logical_and_expr AND_OP inclusive_or_expr
362 { $$ = newNode(AND_OP,$1,$3);}
367 | logical_or_expr OR_OP logical_and_expr
368 { $$ = newNode(OR_OP,$1,$3); }
373 | logical_or_expr '?' logical_or_expr ':' conditional_expr
375 $$ = newNode(':',$3,$5) ;
376 $$ = newNode('?',$1,$$) ;
382 | unary_expr assignment_operator assignment_expr
387 $$ = newNode($2,$1,$3);
390 $$ = newNode('=',$1,newNode('*',copyAst($1),$3));
393 $$ = newNode('=',$1,newNode('/',copyAst($1),$3));
396 $$ = newNode('=',$1,newNode('%',copyAst($1),$3));
399 $$ = newNode('=',$1,newNode('+',copyAst($1),$3));
402 $$ = newNode('=',$1,newNode('-',copyAst($1),$3));
405 $$ = newNode('=',$1,newNode(LEFT_OP,copyAst($1),$3));
408 $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3));
411 $$ = newNode('=',$1,newNode('&',copyAst($1),$3));
414 $$ = newNode('=',$1,newNode('^',copyAst($1),$3));
417 $$ = newNode('=',$1,newNode('|',copyAst($1),$3));
442 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
450 : declaration_specifiers ';' { $$ = NULL ; }
451 | declaration_specifiers init_declarator_list ';'
453 /* add the specifier list to the id */
456 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
457 link *lnk = copyLinkChain($1);
458 /* do the pointer stuff */
459 pointerTypes(sym->type,lnk);
460 addDecl (sym,0,lnk) ;
467 declaration_specifiers
468 : storage_class_specifier { $$ = $1; }
469 | storage_class_specifier declaration_specifiers {
470 /* if the decl $2 is not a specifier */
471 /* find the spec and replace it */
474 while (lnk && !IS_SPEC(lnk->next))
476 lnk->next = mergeSpec($1,lnk->next);
480 $$ = mergeSpec($1,$2);
482 | type_specifier { $$ = $1; }
483 | type_specifier declaration_specifiers {
484 /* if the decl $2 is not a specifier */
485 /* find the spec and replace it */
488 while (lnk && !IS_SPEC(lnk->next))
490 lnk->next = mergeSpec($1,lnk->next);
494 $$ = mergeSpec($1,$2);
500 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
504 : declarator { $1->ival = NULL ; }
505 | declarator '=' initializer { $1->ival = $3 ; }
509 storage_class_specifier
512 $$->class = SPECIFIER ;
513 SPEC_TYPEDEF($$) = 1 ;
517 $$->class = SPECIFIER ;
522 $$->class = SPECIFIER ;
527 $$->class = SPECIFIER ;
528 SPEC_SCLS($$) = S_AUTO ;
532 $$->class = SPECIFIER ;
533 SPEC_SCLS($$) = S_REGISTER ;
538 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
543 | type_specifier2 AT constant_expr
545 /* add this to the storage class specifier */
546 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
547 /* now get the abs addr from value */
548 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
555 $$->class = SPECIFIER ;
556 SPEC_NOUN($$) = V_CHAR ;
560 $$->class = SPECIFIER ;
566 $$->class = SPECIFIER ;
567 SPEC_NOUN($$) = V_INT ;
571 $$->class = SPECIFIER ;
577 $$->class = SPECIFIER ;
582 $$->class = SPECIFIER ;
587 $$->class = SPECIFIER ;
588 SPEC_NOUN($$) = V_VOID ;
592 $$->class = SPECIFIER ;
593 SPEC_SCLS($$) = S_CONSTANT ;
598 $$->class = SPECIFIER ;
599 SPEC_VOLATILE($$) = 1 ;
603 SPEC_NOUN($$) = V_FLOAT;
604 $$->class = SPECIFIER ;
608 $$->class = SPECIFIER ;
609 SPEC_SCLS($$) = S_XDATA ;
613 $$->class = SPECIFIER ;
614 SPEC_SCLS($$) = S_CODE ;
618 $$->class = SPECIFIER ;
619 SPEC_SCLS($$) = S_EEPROM ;
623 $$->class = SPECIFIER ;
624 SPEC_SCLS($$) = S_DATA ;
628 $$->class = SPECIFIER ;
629 SPEC_SCLS($$) = S_IDATA ;
633 $$->class = SPECIFIER ;
634 SPEC_SCLS($$) = S_PDATA ;
638 $$->class = SPECIFIER ;
639 SPEC_NOUN($$) = V_BIT ;
640 SPEC_SCLS($$) = S_BIT ;
645 | struct_or_union_specifier
655 sym = findSym(TypedefTab,NULL,$1) ;
656 $$ = p = copyLinkChain(sym->type);
657 SPEC_TYPEDEF(getSpec(p)) = 0;
665 $$->class = SPECIFIER ;
666 SPEC_NOUN($$) = V_SBIT;
667 SPEC_SCLS($$) = S_SBIT;
671 $$->class = SPECIFIER ;
672 SPEC_NOUN($$) = V_CHAR;
673 SPEC_SCLS($$) = S_SFR ;
678 struct_or_union_specifier
679 : struct_or_union opt_stag '{' struct_declaration_list '}'
683 /* Create a structdef */
685 sdef->fields = reverseSyms($4) ; /* link the fields */
686 sdef->size = compStructSize($1,sdef); /* update size of */
688 /* Create the specifier */
690 $$->class = SPECIFIER ;
691 SPEC_NOUN($$) = V_STRUCT;
692 SPEC_STRUCT($$)= sdef ;
694 | struct_or_union stag
697 $$->class = SPECIFIER ;
698 SPEC_NOUN($$) = V_STRUCT;
699 SPEC_STRUCT($$) = $2 ;
704 : STRUCT { $$ = STRUCT ; }
705 | UNION { $$ = UNION ; }
710 | { /* synthesize a name add to structtable */
711 $$ = newStruct(genSymName(NestLevel)) ;
712 $$->level = NestLevel ;
713 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
718 : identifier { /* add name to structure table */
719 $$ = findSymWithBlock (StructTab,$1,currBlockno);
721 $$ = newStruct($1->name) ;
722 $$->level = NestLevel ;
723 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
728 struct_declaration_list
730 | struct_declaration_list struct_declaration
733 /* go to the end of the chain */
734 while (sym->next) sym = sym->next;
742 : type_specifier_list struct_declarator_list ';'
744 /* add this type to all the symbols */
746 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
748 pointerTypes(sym->type,copyLinkChain($1));
750 sym->type = copyLinkChain($1);
751 sym->etype = getSpec(sym->type);
754 addDecl (sym,0,cloneSpec($1));
761 struct_declarator_list
763 | struct_declarator_list ',' struct_declarator
772 | ':' constant_expr {
773 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
774 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
776 | declarator ':' constant_expr
778 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
783 : ENUM '{' enumerator_list '}' {
785 allocVariables(reverseSyms($3)) ;
786 $$ = copyLinkChain(cenum->type);
788 | ENUM identifier '{' enumerator_list '}' {
791 $2->type = copyLinkChain(cenum->type);
792 $2->etype = getSpec($2->type);
793 /* add this to the enumerator table */
794 if (!(csym=findSym(enumTab,$2,$2->name)) &&
795 (csym && csym->level == $2->level))
796 werror(E_DUPLICATE_TYPEDEF,csym->name);
798 addSym ( enumTab,$2,$2->name,$2->level,$2->block);
800 allocVariables (reverseSyms($4));
801 $$ = copyLinkChain(cenum->type);
802 SPEC_SCLS(getSpec($$)) = 0 ;
807 /* check the enumerator table */
808 if ((csym = findSym(enumTab,$2,$2->name)))
809 $$ = copyLinkChain(csym->type);
812 $$->class = SPECIFIER ;
813 SPEC_NOUN($$) = V_INT ;
816 SPEC_SCLS(getSpec($$)) = 0 ;
822 | enumerator_list ',' enumerator {
829 : identifier opt_assign_expr {
830 /* make the symbol one level up */
832 $1->type = copyLinkChain($2->type);
833 $1->etype= getSpec($1->type);
834 SPEC_ENUM($1->etype) = 1;
841 : '=' constant_expr {
844 val = constExprValue($2,TRUE);
849 sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
850 $$ = cenum = constVal(lbuff);
853 sprintf(lbuff,"%d",0);
854 $$ = cenum = constVal(lbuff);
860 : declarator2_using_reentrant { $$ = $1; }
861 | pointer declarator2_using_reentrant
863 addDecl ($2,0,reverseLink($1));
868 declarator2_using_reentrant
869 : declarator2 { $$ = $1 ; }
870 | declarator2 using_reentrant { addDecl ($1,0,$2); }
875 | '(' declarator ')' { $$ = $2; }
876 | declarator2 '[' ']'
881 DCL_TYPE(p) = ARRAY ;
885 | declarator2 '[' constant_expr ']'
890 p = (tval = constExprValue($3,TRUE))->etype;
891 /* if it is not a constant then Error */
892 if ( SPEC_SCLS(p) != S_LITERAL)
893 werror(E_CONST_EXPECTED) ;
896 DCL_TYPE(p) = ARRAY ;
897 DCL_ELEM(p) = (int) floatFromVal(tval) ;
901 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
902 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
905 addDecl ($1,FUNCTION,NULL) ;
907 $1->hasVargs = IS_VARG($4);
908 $1->args = reverseVal($4) ;
910 /* nest level was incremented to take care of the parms */
915 | declarator2 '(' parameter_identifier_list ')'
917 werror(E_OLD_STYLE,$1->name) ;
919 /* assume it returns an it */
920 $1->type = $1->etype = newIntLink();
926 : far_near_pointer { $$ = $1 ;}
927 | far_near_pointer type_specifier_list
932 | far_near_pointer pointer
937 | far_near_pointer type_specifier_list pointer
940 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
941 DCL_PTR_CONST($1) = SPEC_CONST($2);
942 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
943 switch (SPEC_SCLS($2)) {
945 DCL_TYPE($3) = FPOINTER;
948 DCL_TYPE($3) = IPOINTER ;
951 DCL_TYPE($3) = PPOINTER ;
954 DCL_TYPE($3) = POINTER ;
957 DCL_PTR_CONST($3) = 1;
958 DCL_TYPE($3) = CPOINTER ;
960 DCL_TYPE($3) = EEPPOINTER;
963 werror(W_PTR_TYPE_INVALID);
967 werror (W_PTR_TYPE_INVALID);
976 DCL_TYPE($$) = POINTER ;
984 : _XDATA { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; }
985 | _CODE { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ; DCL_PTR_CONST($$) = 1;}
986 | _PDATA { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; }
987 | _IDATA { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; }
988 | _NEAR { $$ = NULL ; }
989 | _GENERIC { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; }
990 | _EEPROM { $$ = newLink() ; DCL_TYPE($$) = EEPPOINTER ;}
991 | { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; }
996 | type_specifier_list type_specifier { $$ = mergeSpec ($1,$2); }
999 parameter_identifier_list
1001 | identifier_list ',' ELIPSIS
1006 | identifier_list ',' identifier
1015 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1019 : parameter_declaration
1020 | parameter_list ',' parameter_declaration
1027 parameter_declaration
1028 : type_specifier_list declarator
1031 pointerTypes($2->type,$1);
1033 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1040 $$->etype = getSpec($$->type);
1045 : type_specifier_list { $$ = $1 ;}
1046 | type_specifier_list abstract_declarator
1048 /* go to the end of the list */
1050 pointerTypes($2,$1);
1051 for ( p = $2 ; p->next ; p=p->next);
1058 : pointer { $$ = reverseLink($1); }
1059 | abstract_declarator2
1060 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1063 abstract_declarator2
1064 : '(' abstract_declarator ')' { $$ = $2 ; }
1067 DCL_TYPE($$) = ARRAY ;
1070 | '[' constant_expr ']' {
1073 DCL_TYPE($$) = ARRAY ;
1074 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1076 | abstract_declarator2 '[' ']' {
1078 DCL_TYPE($$) = ARRAY ;
1082 | abstract_declarator2 '[' constant_expr ']'
1086 DCL_TYPE($$) = ARRAY ;
1087 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1090 | '(' ')' { $$ = NULL;}
1091 | '(' parameter_type_list ')' { $$ = NULL;}
1092 | abstract_declarator2 '(' ')'
1093 | abstract_declarator2 '(' parameter_type_list ')'
1097 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1098 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1099 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1104 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1109 | compound_statement
1110 | expression_statement
1111 | selection_statement
1112 | iteration_statement
1115 ast *ex = newNode(INLINEASM,NULL,NULL);
1116 ALLOC_ATOMIC(ex->values.inlineasm,strlen($1));
1117 strcpy(ex->values.inlineasm,$1);
1123 : identifier ':' statement { $$ = createLabel($1,$3); }
1124 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1125 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1128 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1131 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1135 : start_block end_block { $$ = createBlock(NULL,NULL); }
1136 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1138 declaration_list { addSymChain($2); }
1139 end_block { $$ = createBlock($2,NULL) ; }
1141 declaration_list { addSymChain ($2); }
1143 end_block {$$ = createBlock($2,$4) ; }
1144 | error ';' { $$ = NULL ; }
1150 /* if this is typedef declare it immediately */
1151 if ( $1 && IS_TYPEDEF($1->etype)) {
1152 allocVariables ($1);
1159 | declaration_list declaration
1163 /* if this is a typedef */
1164 if ($2 && IS_TYPEDEF($2->etype)) {
1165 allocVariables ($2);
1169 /* get to the end of the previous decl */
1184 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1187 expression_statement
1193 : ELSE statement { $$ = $2 ; }
1199 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1200 | SWITCH '(' expr ')' {
1202 static int swLabel = 0 ;
1204 /* create a node for expression */
1205 ex = newNode(SWITCH,$3,NULL);
1206 STACK_PUSH(swStk,ex); /* save it in the stack */
1207 ex->values.switchVals.swNum = swLabel ;
1209 /* now create the label */
1210 sprintf(lbuff,"_swBrk_%d",swLabel++);
1211 $<sym>$ = newSymbol(lbuff,NestLevel);
1212 /* put label in the break stack */
1213 STACK_PUSH(breakStack,$<sym>$);
1216 /* get back the switch form the stack */
1217 $$ = STACK_POP(swStk) ;
1218 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1219 STACK_POP(breakStack);
1223 while : WHILE { /* create and push the continue , break & body labels */
1224 static int Lblnum = 0 ;
1226 sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1227 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1229 sprintf (lbuff,"_whilebreak_%d",Lblnum);
1230 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1232 sprintf (lbuff,"_whilebody_%d",Lblnum++);
1233 $$ = newSymbol(lbuff,NestLevel);
1236 do : DO { /* create and push the continue , break & body Labels */
1237 static int Lblnum = 0 ;
1240 sprintf(lbuff,"_docontinue_%d",Lblnum);
1241 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1243 sprintf (lbuff,"_dobreak_%d",Lblnum);
1244 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1246 sprintf (lbuff,"_dobody_%d",Lblnum++);
1247 $$ = newSymbol (lbuff,NestLevel);
1249 for : FOR { /* create & push continue, break & body labels */
1250 static int Lblnum = 0 ;
1253 sprintf (lbuff,"_forcontinue_%d",Lblnum);
1254 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1256 sprintf (lbuff,"_forbreak_%d",Lblnum);
1257 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1259 sprintf (lbuff,"_forbody_%d",Lblnum);
1260 $$ = newSymbol(lbuff,NestLevel);
1262 sprintf (lbuff,"_forcond_%d",Lblnum++);
1263 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1267 : while '(' expr ')' statement
1270 $$ = createWhile ( $1, STACK_POP(continueStack),
1271 STACK_POP(breakStack), $3, $5 );
1272 $$->lineno = $1->lineDef ;
1275 | do statement WHILE '(' expr ')' ';'
1278 $$ = createDo ( $1 , STACK_POP(continueStack),
1279 STACK_POP(breakStack), $5, $2);
1280 $$->lineno = $1->lineDef ;
1283 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1287 /* if break or continue statement present
1288 then create a general case loop */
1289 if (STACK_PEEK(continueStack)->isref ||
1290 STACK_PEEK(breakStack)->isref) {
1291 $$ = createFor ($1, STACK_POP(continueStack),
1292 STACK_POP(breakStack) ,
1293 STACK_POP(forStack) ,
1296 $$ = newNode(FOR,$9,NULL);
1297 AST_FOR($$,trueLabel) = $1;
1298 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1299 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1300 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1301 AST_FOR($$,initExpr) = $3;
1302 AST_FOR($$,condExpr) = $5;
1303 AST_FOR($$,loopExpr) = $7;
1316 : GOTO identifier ';' {
1318 $$ = newAst_VALUE(symbolVal($2));
1319 $$ = newNode(GOTO,$$,NULL);
1322 /* make sure continue is in context */
1323 if (STACK_PEEK(continueStack) == NULL) {
1324 werror(E_BREAK_CONTEXT);
1328 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1329 $$ = newNode(GOTO,$$,NULL);
1330 /* mark the continue label as referenced */
1331 STACK_PEEK(continueStack)->isref = 1;
1335 if (STACK_PEEK(breakStack) == NULL) {
1336 werror(E_BREAK_CONTEXT);
1339 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1340 $$ = newNode(GOTO,$$,NULL);
1341 STACK_PEEK(breakStack)->isref = 1;
1344 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1345 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1349 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }