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 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 allocVariables ($1) ;
130 cleanUpLevel (SymbolTab,1);
135 : declarator function_body { /* function type not specified */
136 /* assume it to be 'int' */
137 addDecl($1,0,newIntLink());
138 $$ = createFunction($1,$2);
140 | declaration_specifiers declarator function_body
142 pointerTypes($2->type,copyLinkChain($1));
144 $$ = createFunction($2,$3);
149 : using_reentrant_interrupt
150 | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2); }
153 using_reentrant_interrupt
156 $$->class = SPECIFIER ;
158 SPEC_BANK($$) = (int) floatFromVal($2);
160 | REENTRANT { $$ = newLink ();
161 $$->class = SPECIFIER ;
164 | CRITICAL { $$ = newLink ();
165 $$->class = SPECIFIER ;
168 | NONBANKED {$$ = newLink ();
169 $$->class = SPECIFIER ;
170 SPEC_NONBANKED($$) = 1;
171 if (SPEC_BANKED($$)) {
172 werror(W_BANKED_WITH_NONBANKED);
175 | BANKED {$$ = newLink ();
176 $$->class = SPECIFIER ;
178 if (SPEC_NONBANKED($$)) {
179 werror(W_BANKED_WITH_NONBANKED);
182 werror(W_BANKED_WITH_STATIC);
188 $$->class = SPECIFIER ;
196 | declaration_list compound_statement
198 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
204 : identifier { $$ = newAst(EX_VALUE,symbolVal($1)); }
205 | CONSTANT { $$ = newAst(EX_VALUE,$1); }
207 | '(' expr ')' { $$ = $2 ; }
211 : STRING_LITERAL { $$ = newAst(EX_VALUE,$1); }
216 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
217 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
218 $$->left->funcName = 1;}
219 | postfix_expr '(' argument_expr_list ')'
221 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
223 | postfix_expr '.' identifier
225 $3 = newSymbol($3->name,NestLevel);
227 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst(EX_VALUE,symbolVal($3)));
228 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
230 | postfix_expr PTR_OP identifier
232 $3 = newSymbol($3->name,NestLevel);
234 $$ = newNode(PTR_OP,$1,newAst(EX_VALUE,symbolVal($3)));
236 | postfix_expr INC_OP
237 { $$ = newNode(INC_OP,$1,NULL);}
238 | postfix_expr DEC_OP
239 { $$ = newNode(DEC_OP,$1,NULL); }
244 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
249 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
250 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
251 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
252 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
253 | SIZEOF '(' type_name ')' { $$ = newAst(EX_VALUE,sizeofOp($3)); }
267 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst(EX_LINK,$2),$4); }
272 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
273 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
274 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
278 : multiplicative_expr
279 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
280 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
285 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
286 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
291 | relational_expr '<' shift_expr { $$ = newNode('<',$1,$3); }
292 | relational_expr '>' shift_expr { $$ = newNode('>',$1,$3); }
293 | relational_expr LE_OP shift_expr {
294 /* $$ = newNode(LE_OP,$1,$3); */
295 /* getting 8051 specific here : will change
296 LE_OP operation to "not greater than" i.e.
297 ( a <= b ) === ( ! ( a > b )) */
299 newNode('>', $1 , $3 ),
302 | relational_expr GE_OP shift_expr {
303 /* $$ = newNode(GE_OP,$1,$3) ; */
304 /* getting 8051 specific here : will change
305 GE_OP operation to "not less than" i.e.
306 ( a >= b ) === ( ! ( a < b )) */
308 newNode('<', $1 , $3 ),
315 | equality_expr EQ_OP relational_expr { $$ = newNode(EQ_OP,$1,$3);}
316 | equality_expr NE_OP relational_expr
318 /* $$ = newNode(NE_OP,$1,$3); */
320 expr1 != expr2 is equivalent to
321 (! expr1 == expr2) */
323 newNode(EQ_OP,$1,$3),
330 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
335 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
340 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
345 | logical_and_expr AND_OP inclusive_or_expr
346 { $$ = newNode(AND_OP,$1,$3);}
351 | logical_or_expr OR_OP logical_and_expr
352 { $$ = newNode(OR_OP,$1,$3); }
357 | logical_or_expr '?' logical_or_expr ':' conditional_expr
359 $$ = newNode(':',$3,$5) ;
360 $$ = newNode('?',$1,$$) ;
366 | unary_expr assignment_operator assignment_expr
371 $$ = newNode($2,$1,$3);
374 $$ = newNode('=',$1,newNode('*',copyAst($1),$3));
377 $$ = newNode('=',$1,newNode('/',copyAst($1),$3));
380 $$ = newNode('=',$1,newNode('%',copyAst($1),$3));
383 $$ = newNode('=',$1,newNode('+',copyAst($1),$3));
386 $$ = newNode('=',$1,newNode('-',copyAst($1),$3));
389 $$ = newNode('=',$1,newNode(LEFT_OP,copyAst($1),$3));
392 $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3));
395 $$ = newNode('=',$1,newNode('&',copyAst($1),$3));
398 $$ = newNode('=',$1,newNode('^',copyAst($1),$3));
401 $$ = newNode('=',$1,newNode('|',copyAst($1),$3));
426 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
434 : declaration_specifiers ';' { $$ = NULL ; }
435 | declaration_specifiers init_declarator_list ';'
437 /* add the specifier list to the id */
440 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
441 link *lnk = copyLinkChain($1);
442 /* do the pointer stuff */
443 pointerTypes(sym->type,lnk);
444 addDecl (sym,0,lnk) ;
451 declaration_specifiers
452 : storage_class_specifier { $$ = $1; }
453 | storage_class_specifier declaration_specifiers {
454 /* if the decl $2 is not a specifier */
455 /* find the spec and replace it */
458 while (lnk && !IS_SPEC(lnk->next))
460 lnk->next = mergeSpec($1,lnk->next);
464 $$ = mergeSpec($1,$2);
466 | type_specifier { $$ = $1; }
467 | type_specifier declaration_specifiers {
468 /* if the decl $2 is not a specifier */
469 /* find the spec and replace it */
472 while (lnk && !IS_SPEC(lnk->next))
474 lnk->next = mergeSpec($1,lnk->next);
478 $$ = mergeSpec($1,$2);
484 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
488 : declarator { $1->ival = NULL ; }
489 | declarator '=' initializer { $1->ival = $3 ; }
493 storage_class_specifier
496 $$->class = SPECIFIER ;
497 SPEC_TYPEDEF($$) = 1 ;
501 $$->class = SPECIFIER ;
506 $$->class = SPECIFIER ;
511 $$->class = SPECIFIER ;
512 SPEC_SCLS($$) = S_AUTO ;
516 $$->class = SPECIFIER ;
517 SPEC_SCLS($$) = S_REGISTER ;
522 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
527 | type_specifier2 AT CONSTANT
529 /* add this to the storage class specifier */
530 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
531 /* now get the abs addr from value */
532 SPEC_ADDR($1) = (int) floatFromVal ($3) ;
539 $$->class = SPECIFIER ;
540 SPEC_NOUN($$) = V_CHAR ;
544 $$->class = SPECIFIER ;
550 $$->class = SPECIFIER ;
551 SPEC_NOUN($$) = V_INT ;
555 $$->class = SPECIFIER ;
561 $$->class = SPECIFIER ;
566 $$->class = SPECIFIER ;
571 $$->class = SPECIFIER ;
572 SPEC_NOUN($$) = V_VOID ;
576 $$->class = SPECIFIER ;
577 SPEC_SCLS($$) = S_CONSTANT ;
582 $$->class = SPECIFIER ;
583 SPEC_VOLATILE($$) = 1 ;
587 SPEC_NOUN($$) = V_FLOAT;
588 $$->class = SPECIFIER ;
592 $$->class = SPECIFIER ;
593 SPEC_SCLS($$) = S_XDATA ;
597 $$->class = SPECIFIER ;
598 SPEC_SCLS($$) = S_CODE ;
602 $$->class = SPECIFIER ;
603 SPEC_SCLS($$) = S_EEPROM ;
607 $$->class = SPECIFIER ;
608 SPEC_SCLS($$) = S_DATA ;
612 $$->class = SPECIFIER ;
613 SPEC_SCLS($$) = S_IDATA ;
617 $$->class = SPECIFIER ;
618 SPEC_SCLS($$) = S_PDATA ;
622 $$->class = SPECIFIER ;
623 SPEC_NOUN($$) = V_BIT ;
624 SPEC_SCLS($$) = S_BIT ;
629 | struct_or_union_specifier
639 sym = findSym(TypedefTab,NULL,$1) ;
640 $$ = p = copyLinkChain(sym->type);
641 SPEC_TYPEDEF(getSpec(p)) = 0;
649 $$->class = SPECIFIER ;
650 SPEC_NOUN($$) = V_SBIT;
651 SPEC_SCLS($$) = S_SBIT;
655 $$->class = SPECIFIER ;
656 SPEC_NOUN($$) = V_CHAR;
657 SPEC_SCLS($$) = S_SFR ;
662 struct_or_union_specifier
663 : struct_or_union opt_stag '{' struct_declaration_list '}'
667 /* Create a structdef */
669 sdef->fields = reverseSyms($4) ; /* link the fields */
670 sdef->size = compStructSize($1,sdef); /* update size of */
672 /* Create the specifier */
674 $$->class = SPECIFIER ;
675 SPEC_NOUN($$) = V_STRUCT;
676 SPEC_STRUCT($$)= sdef ;
678 | struct_or_union stag
681 $$->class = SPECIFIER ;
682 SPEC_NOUN($$) = V_STRUCT;
683 SPEC_STRUCT($$) = $2 ;
688 : STRUCT { $$ = STRUCT ; }
689 | UNION { $$ = UNION ; }
694 | { /* synthesize a name add to structtable */
695 $$ = newStruct(genSymName(NestLevel)) ;
696 $$->level = NestLevel ;
697 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
702 : identifier { /* add name to structure table */
703 $$ = findSymWithBlock (StructTab,$1,currBlockno);
705 $$ = newStruct($1->name) ;
706 $$->level = NestLevel ;
707 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
712 struct_declaration_list
714 | struct_declaration_list struct_declaration
717 /* go to the end of the chain */
718 while (sym->next) sym = sym->next;
726 : type_specifier_list struct_declarator_list ';'
728 /* add this type to all the symbols */
730 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
732 pointerTypes(sym->type,copyLinkChain($1));
734 sym->type = copyLinkChain($1);
735 sym->etype = getSpec(sym->type);
738 addDecl (sym,0,cloneSpec($1));
745 struct_declarator_list
747 | struct_declarator_list ',' struct_declarator
756 | ':' constant_expr {
757 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
758 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
760 | declarator ':' constant_expr
762 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
767 : ENUM '{' enumerator_list '}' {
769 allocVariables(reverseSyms($3)) ;
770 $$ = copyLinkChain(cenum->type);
772 | ENUM identifier '{' enumerator_list '}' {
775 $2->type = copyLinkChain(cenum->type);
776 $2->etype = getSpec($2->type);
777 /* add this to the enumerator table */
778 if (!(csym=findSym(enumTab,$2,$2->name)) &&
779 (csym && csym->level == $2->level))
780 werror(E_DUPLICATE_TYPEDEF,csym->name);
782 addSym ( enumTab,$2,$2->name,$2->level,$2->block);
784 allocVariables (reverseSyms($4));
785 $$ = copyLinkChain(cenum->type);
786 SPEC_SCLS(getSpec($$)) = 0 ;
791 /* check the enumerator table */
792 if ((csym = findSym(enumTab,$2,$2->name)))
793 $$ = copyLinkChain(csym->type);
796 $$->class = SPECIFIER ;
797 SPEC_NOUN($$) = V_INT ;
800 SPEC_SCLS(getSpec($$)) = 0 ;
806 | enumerator_list ',' enumerator {
813 : identifier opt_assign_expr {
814 /* make the symbol one level up */
816 $1->type = copyLinkChain($2->type);
817 $1->etype= getSpec($1->type);
818 SPEC_ENUM($1->etype) = 1;
825 : '=' constant_expr {
828 val = constExprValue($2,TRUE);
833 sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
834 $$ = cenum = constVal(lbuff);
837 sprintf(lbuff,"%d",0);
838 $$ = cenum = constVal(lbuff);
844 : declarator2_using_reentrant { $$ = $1; }
845 | pointer declarator2_using_reentrant
847 addDecl ($2,0,reverseLink($1));
852 declarator2_using_reentrant
853 : declarator2 { $$ = $1 ; }
854 | declarator2 using_reentrant { addDecl ($1,0,$2); }
859 | '(' declarator ')' { $$ = $2; }
860 | declarator2 '[' ']'
865 DCL_TYPE(p) = ARRAY ;
869 | declarator2 '[' constant_expr ']'
874 p = (tval = constExprValue($3,TRUE))->etype;
875 /* if it is not a constant then Error */
876 if ( SPEC_SCLS(p) != S_LITERAL)
877 werror(E_CONST_EXPECTED) ;
880 DCL_TYPE(p) = ARRAY ;
881 DCL_ELEM(p) = (int) floatFromVal(tval) ;
885 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
886 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
889 addDecl ($1,FUNCTION,NULL) ;
891 $1->hasVargs = IS_VARG($4);
892 $1->args = reverseVal($4) ;
894 /* nest level was incremented to take care of the parms */
899 | declarator2 '(' parameter_identifier_list ')'
901 werror(E_OLD_STYLE,$1->name) ;
903 /* assume it returns an it */
904 $1->type = $1->etype = newIntLink();
910 : far_near_pointer { $$ = $1 ;}
911 | far_near_pointer type_specifier_list
916 | far_near_pointer pointer
921 | far_near_pointer type_specifier_list pointer
924 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
925 DCL_PTR_CONST($1) = SPEC_CONST($2);
926 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
927 switch (SPEC_SCLS($2)) {
929 DCL_TYPE($3) = FPOINTER;
932 DCL_TYPE($3) = IPOINTER ;
935 DCL_TYPE($3) = PPOINTER ;
938 DCL_TYPE($3) = POINTER ;
941 DCL_PTR_CONST($3) = 1;
942 DCL_TYPE($3) = CPOINTER ;
944 DCL_TYPE($3) = EEPPOINTER;
947 werror(W_PTR_TYPE_INVALID);
951 werror (W_PTR_TYPE_INVALID);
960 DCL_TYPE($$) = POINTER ;
968 : _XDATA { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; }
969 | _CODE { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ; DCL_PTR_CONST($$) = 1;}
970 | _PDATA { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; }
971 | _IDATA { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; }
972 | _NEAR { $$ = NULL ; }
973 | _GENERIC { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; }
974 | _EEPROM { $$ = newLink() ; DCL_TYPE($$) = EEPPOINTER ;}
975 | { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; }
980 | type_specifier_list type_specifier { $$ = mergeSpec ($1,$2); }
983 parameter_identifier_list
985 | identifier_list ',' ELIPSIS
990 | identifier_list ',' identifier
999 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1003 : parameter_declaration
1004 | parameter_list ',' parameter_declaration
1011 parameter_declaration
1012 : type_specifier_list declarator
1015 pointerTypes($2->type,$1);
1017 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1024 $$->etype = getSpec($$->type);
1029 : type_specifier_list { $$ = $1 ;}
1030 | type_specifier_list abstract_declarator
1032 /* go to the end of the list */
1034 pointerTypes($2,$1);
1035 for ( p = $2 ; p->next ; p=p->next);
1042 : pointer { $$ = reverseLink($1); }
1043 | abstract_declarator2
1044 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1047 abstract_declarator2
1048 : '(' abstract_declarator ')' { $$ = $2 ; }
1051 DCL_TYPE($$) = ARRAY ;
1054 | '[' constant_expr ']' {
1057 DCL_TYPE($$) = ARRAY ;
1058 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1060 | abstract_declarator2 '[' ']' {
1062 DCL_TYPE($$) = ARRAY ;
1066 | abstract_declarator2 '[' constant_expr ']'
1070 DCL_TYPE($$) = ARRAY ;
1071 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1074 | '(' ')' { $$ = NULL;}
1075 | '(' parameter_type_list ')' { $$ = NULL;}
1076 | abstract_declarator2 '(' ')'
1077 | abstract_declarator2 '(' parameter_type_list ')'
1081 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1082 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1083 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1088 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1093 | compound_statement
1094 | expression_statement
1095 | selection_statement
1096 | iteration_statement
1099 ast *ex = newNode(INLINEASM,NULL,NULL);
1100 ALLOC_ATOMIC(ex->values.inlineasm,strlen($1));
1101 strcpy(ex->values.inlineasm,$1);
1107 : identifier ':' statement { $$ = createLabel($1,$3); }
1108 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1109 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1112 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1115 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1119 : start_block end_block { $$ = createBlock(NULL,NULL); }
1120 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1122 declaration_list { addSymChain($2); }
1123 end_block { $$ = createBlock($2,NULL) ; }
1125 declaration_list { addSymChain ($2); }
1127 end_block {$$ = createBlock($2,$4) ; }
1128 | error ';' { $$ = NULL ; }
1134 /* if this is typedef declare it immediately */
1135 if ( $1 && IS_TYPEDEF($1->etype)) {
1136 allocVariables ($1);
1143 | declaration_list declaration
1147 /* if this is a typedef */
1148 if ($2 && IS_TYPEDEF($2->etype)) {
1149 allocVariables ($2);
1153 /* get to the end of the previous decl */
1168 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1171 expression_statement
1177 : ELSE statement { $$ = $2 ; }
1183 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1184 | SWITCH '(' expr ')' {
1186 static int swLabel = 0 ;
1188 /* create a node for expression */
1189 ex = newNode(SWITCH,$3,NULL);
1190 STACK_PUSH(swStk,ex); /* save it in the stack */
1191 ex->values.switchVals.swNum = swLabel ;
1193 /* now create the label */
1194 sprintf(lbuff,"_swBrk_%d",swLabel++);
1195 $<sym>$ = newSymbol(lbuff,NestLevel);
1196 /* put label in the break stack */
1197 STACK_PUSH(breakStack,$<sym>$);
1200 /* get back the switch form the stack */
1201 $$ = STACK_POP(swStk) ;
1202 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1203 STACK_POP(breakStack);
1207 while : WHILE { /* create and push the continue , break & body labels */
1208 static int Lblnum = 0 ;
1210 sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1211 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1213 sprintf (lbuff,"_whilebreak_%d",Lblnum);
1214 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1216 sprintf (lbuff,"_whilebody_%d",Lblnum++);
1217 $$ = newSymbol(lbuff,NestLevel);
1220 do : DO { /* create and push the continue , break & body Labels */
1221 static int Lblnum = 0 ;
1224 sprintf(lbuff,"_docontinue_%d",Lblnum);
1225 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1227 sprintf (lbuff,"_dobreak_%d",Lblnum);
1228 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1230 sprintf (lbuff,"_dobody_%d",Lblnum++);
1231 $$ = newSymbol (lbuff,NestLevel);
1233 for : FOR { /* create & push continue, break & body labels */
1234 static int Lblnum = 0 ;
1237 sprintf (lbuff,"_forcontinue_%d",Lblnum);
1238 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1240 sprintf (lbuff,"_forbreak_%d",Lblnum);
1241 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1243 sprintf (lbuff,"_forbody_%d",Lblnum);
1244 $$ = newSymbol(lbuff,NestLevel);
1246 sprintf (lbuff,"_forcond_%d",Lblnum++);
1247 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1251 : while '(' expr ')' statement
1254 $$ = createWhile ( $1, STACK_POP(continueStack),
1255 STACK_POP(breakStack), $3, $5 );
1256 $$->lineno = $1->lineDef ;
1259 | do statement WHILE '(' expr ')' ';'
1262 $$ = createDo ( $1 , STACK_POP(continueStack),
1263 STACK_POP(breakStack), $5, $2);
1264 $$->lineno = $1->lineDef ;
1267 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1271 /* if break or continue statement present
1272 then create a general case loop */
1273 if (STACK_PEEK(continueStack)->isref ||
1274 STACK_PEEK(breakStack)->isref) {
1275 $$ = createFor ($1, STACK_POP(continueStack),
1276 STACK_POP(breakStack) ,
1277 STACK_POP(forStack) ,
1280 $$ = newNode(FOR,$9,NULL);
1281 AST_FOR($$,trueLabel) = $1;
1282 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1283 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1284 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1285 AST_FOR($$,initExpr) = $3;
1286 AST_FOR($$,condExpr) = $5;
1287 AST_FOR($$,loopExpr) = $7;
1300 : GOTO identifier ';' {
1302 $$ = newAst(EX_VALUE,symbolVal($2));
1303 $$ = newNode(GOTO,$$,NULL);
1306 /* make sure continue is in context */
1307 if (STACK_PEEK(continueStack) == NULL) {
1308 werror(E_BREAK_CONTEXT);
1312 $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(continueStack)));
1313 $$ = newNode(GOTO,$$,NULL);
1314 /* mark the continue label as referenced */
1315 STACK_PEEK(continueStack)->isref = 1;
1319 if (STACK_PEEK(breakStack) == NULL) {
1320 werror(E_BREAK_CONTEXT);
1323 $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(breakStack)));
1324 $$ = newNode(GOTO,$$,NULL);
1325 STACK_PEEK(breakStack)->isref = 1;
1328 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1329 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1333 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }