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
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;
175 $$->class = SPECIFIER ;
183 | declaration_list compound_statement
185 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
191 : identifier { $$ = newAst(EX_VALUE,symbolVal($1)); }
192 | CONSTANT { $$ = newAst(EX_VALUE,$1); }
194 | '(' expr ')' { $$ = $2 ; }
198 : STRING_LITERAL { $$ = newAst(EX_VALUE,$1); }
203 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
204 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
205 $$->left->funcName = 1;}
206 | postfix_expr '(' argument_expr_list ')'
208 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
210 | postfix_expr '.' identifier
212 $3 = newSymbol($3->name,NestLevel);
214 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst(EX_VALUE,symbolVal($3)));
215 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
217 | postfix_expr PTR_OP identifier
219 $3 = newSymbol($3->name,NestLevel);
221 $$ = newNode(PTR_OP,$1,newAst(EX_VALUE,symbolVal($3)));
223 | postfix_expr INC_OP
224 { $$ = newNode(INC_OP,$1,NULL);}
225 | postfix_expr DEC_OP
226 { $$ = newNode(DEC_OP,$1,NULL); }
231 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
236 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
237 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
238 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
239 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
240 | SIZEOF '(' type_name ')' { $$ = newAst(EX_VALUE,sizeofOp($3)); }
254 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst(EX_LINK,$2),$4); }
259 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
260 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
261 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
265 : multiplicative_expr
266 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
267 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
272 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
273 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
278 | relational_expr '<' shift_expr { $$ = newNode('<',$1,$3); }
279 | relational_expr '>' shift_expr { $$ = newNode('>',$1,$3); }
280 | relational_expr LE_OP shift_expr {
281 /* $$ = newNode(LE_OP,$1,$3); */
282 /* getting 8051 specific here : will change
283 LE_OP operation to "not greater than" i.e.
284 ( a <= b ) === ( ! ( a > b )) */
286 newNode('>', $1 , $3 ),
289 | relational_expr GE_OP shift_expr {
290 /* $$ = newNode(GE_OP,$1,$3) ; */
291 /* getting 8051 specific here : will change
292 GE_OP operation to "not less than" i.e.
293 ( a >= b ) === ( ! ( a < b )) */
295 newNode('<', $1 , $3 ),
302 | equality_expr EQ_OP relational_expr { $$ = newNode(EQ_OP,$1,$3);}
303 | equality_expr NE_OP relational_expr
305 /* $$ = newNode(NE_OP,$1,$3); */
307 expr1 != expr2 is equivalent to
308 (! expr1 == expr2) */
310 newNode(EQ_OP,$1,$3),
317 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
322 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
327 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
332 | logical_and_expr AND_OP inclusive_or_expr
333 { $$ = newNode(AND_OP,$1,$3);}
338 | logical_or_expr OR_OP logical_and_expr
339 { $$ = newNode(OR_OP,$1,$3); }
344 | logical_or_expr '?' logical_or_expr ':' conditional_expr
346 $$ = newNode(':',$3,$5) ;
347 $$ = newNode('?',$1,$$) ;
353 | unary_expr assignment_operator assignment_expr
358 $$ = newNode($2,$1,$3);
361 $$ = newNode('=',$1,newNode('*',copyAst($1),$3));
364 $$ = newNode('=',$1,newNode('/',copyAst($1),$3));
367 $$ = newNode('=',$1,newNode('%',copyAst($1),$3));
370 $$ = newNode('=',$1,newNode('+',copyAst($1),$3));
373 $$ = newNode('=',$1,newNode('-',copyAst($1),$3));
376 $$ = newNode('=',$1,newNode(LEFT_OP,copyAst($1),$3));
379 $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3));
382 $$ = newNode('=',$1,newNode('&',copyAst($1),$3));
385 $$ = newNode('=',$1,newNode('^',copyAst($1),$3));
388 $$ = newNode('=',$1,newNode('|',copyAst($1),$3));
413 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
421 : declaration_specifiers ';' { $$ = NULL ; }
422 | declaration_specifiers init_declarator_list ';'
424 /* add the specifier list to the id */
427 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
428 link *lnk = copyLinkChain($1);
429 /* do the pointer stuff */
430 pointerTypes(sym->type,lnk);
431 addDecl (sym,0,lnk) ;
438 declaration_specifiers
439 : storage_class_specifier { $$ = $1; }
440 | storage_class_specifier declaration_specifiers {
441 /* if the decl $2 is not a specifier */
442 /* find the spec and replace it */
445 while (lnk && !IS_SPEC(lnk->next))
447 lnk->next = mergeSpec($1,lnk->next);
451 $$ = mergeSpec($1,$2);
453 | type_specifier { $$ = $1; }
454 | type_specifier declaration_specifiers {
455 /* if the decl $2 is not a specifier */
456 /* find the spec and replace it */
459 while (lnk && !IS_SPEC(lnk->next))
461 lnk->next = mergeSpec($1,lnk->next);
465 $$ = mergeSpec($1,$2);
471 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
475 : declarator { $1->ival = NULL ; }
476 | declarator '=' initializer { $1->ival = $3 ; }
480 storage_class_specifier
483 $$->class = SPECIFIER ;
484 SPEC_TYPEDEF($$) = 1 ;
488 $$->class = SPECIFIER ;
493 $$->class = SPECIFIER ;
498 $$->class = SPECIFIER ;
499 SPEC_SCLS($$) = S_AUTO ;
503 $$->class = SPECIFIER ;
504 SPEC_SCLS($$) = S_REGISTER ;
509 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
514 | type_specifier2 AT CONSTANT
516 /* add this to the storage class specifier */
517 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
518 /* now get the abs addr from value */
519 SPEC_ADDR($1) = (int) floatFromVal ($3) ;
526 $$->class = SPECIFIER ;
527 SPEC_NOUN($$) = V_CHAR ;
531 $$->class = SPECIFIER ;
537 $$->class = SPECIFIER ;
538 SPEC_NOUN($$) = V_INT ;
542 $$->class = SPECIFIER ;
548 $$->class = SPECIFIER ;
553 $$->class = SPECIFIER ;
558 $$->class = SPECIFIER ;
559 SPEC_NOUN($$) = V_VOID ;
563 $$->class = SPECIFIER ;
564 SPEC_SCLS($$) = S_CONSTANT ;
569 $$->class = SPECIFIER ;
570 SPEC_VOLATILE($$) = 1 ;
574 SPEC_NOUN($$) = V_FLOAT;
575 $$->class = SPECIFIER ;
579 $$->class = SPECIFIER ;
580 SPEC_SCLS($$) = S_XDATA ;
584 $$->class = SPECIFIER ;
585 SPEC_SCLS($$) = S_CODE ;
589 $$->class = SPECIFIER ;
590 SPEC_SCLS($$) = S_EEPROM ;
594 $$->class = SPECIFIER ;
595 SPEC_SCLS($$) = S_DATA ;
599 $$->class = SPECIFIER ;
600 SPEC_SCLS($$) = S_IDATA ;
604 $$->class = SPECIFIER ;
605 SPEC_SCLS($$) = S_PDATA ;
609 $$->class = SPECIFIER ;
610 SPEC_NOUN($$) = V_BIT ;
611 SPEC_SCLS($$) = S_BIT ;
616 | struct_or_union_specifier
626 sym = findSym(TypedefTab,NULL,$1) ;
627 $$ = p = copyLinkChain(sym->type);
628 SPEC_TYPEDEF(getSpec(p)) = 0;
636 $$->class = SPECIFIER ;
637 SPEC_NOUN($$) = V_SBIT;
638 SPEC_SCLS($$) = S_SBIT;
642 $$->class = SPECIFIER ;
643 SPEC_NOUN($$) = V_CHAR;
644 SPEC_SCLS($$) = S_SFR ;
649 struct_or_union_specifier
650 : struct_or_union opt_stag '{' struct_declaration_list '}'
654 /* Create a structdef */
656 sdef->fields = reverseSyms($4) ; /* link the fields */
657 sdef->size = compStructSize($1,sdef); /* update size of */
659 /* Create the specifier */
661 $$->class = SPECIFIER ;
662 SPEC_NOUN($$) = V_STRUCT;
663 SPEC_STRUCT($$)= sdef ;
665 | struct_or_union stag
668 $$->class = SPECIFIER ;
669 SPEC_NOUN($$) = V_STRUCT;
670 SPEC_STRUCT($$) = $2 ;
675 : STRUCT { $$ = STRUCT ; }
676 | UNION { $$ = UNION ; }
681 | { /* synthesize a name add to structtable */
682 $$ = newStruct(genSymName(NestLevel)) ;
683 $$->level = NestLevel ;
684 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
689 : identifier { /* add name to structure table */
690 $$ = findSymWithBlock (StructTab,$1,currBlockno);
692 $$ = newStruct($1->name) ;
693 $$->level = NestLevel ;
694 addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
699 struct_declaration_list
701 | struct_declaration_list struct_declaration
704 /* go to the end of the chain */
705 while (sym->next) sym = sym->next;
713 : type_specifier_list struct_declarator_list ';'
715 /* add this type to all the symbols */
717 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
719 pointerTypes(sym->type,copyLinkChain($1));
721 sym->type = copyLinkChain($1);
722 sym->etype = getSpec(sym->type);
725 addDecl (sym,0,cloneSpec($1));
732 struct_declarator_list
734 | struct_declarator_list ',' struct_declarator
743 | ':' constant_expr {
744 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
745 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
747 | declarator ':' constant_expr
749 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
754 : ENUM '{' enumerator_list '}' {
756 allocVariables(reverseSyms($3)) ;
757 $$ = copyLinkChain(cenum->type);
759 | ENUM identifier '{' enumerator_list '}' {
762 $2->type = copyLinkChain(cenum->type);
763 $2->etype = getSpec($2->type);
764 /* add this to the enumerator table */
765 if (!(csym=findSym(enumTab,$2,$2->name)) &&
766 (csym && csym->level == $2->level))
767 werror(E_DUPLICATE_TYPEDEF,csym->name);
769 addSym ( enumTab,$2,$2->name,$2->level,$2->block);
771 allocVariables (reverseSyms($4));
772 $$ = copyLinkChain(cenum->type);
773 SPEC_SCLS(getSpec($$)) = 0 ;
778 /* check the enumerator table */
779 if ((csym = findSym(enumTab,$2,$2->name)))
780 $$ = copyLinkChain(csym->type);
783 $$->class = SPECIFIER ;
784 SPEC_NOUN($$) = V_INT ;
787 SPEC_SCLS(getSpec($$)) = 0 ;
793 | enumerator_list ',' enumerator {
800 : identifier opt_assign_expr {
801 /* make the symbol one level up */
803 $1->type = copyLinkChain($2->type);
804 $1->etype= getSpec($1->type);
805 SPEC_ENUM($1->etype) = 1;
812 : '=' constant_expr {
815 val = constExprValue($2,TRUE);
820 sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
821 $$ = cenum = constVal(lbuff);
824 sprintf(lbuff,"%d",0);
825 $$ = cenum = constVal(lbuff);
831 : declarator2_using_reentrant { $$ = $1; }
832 | pointer declarator2_using_reentrant
834 addDecl ($2,0,reverseLink($1));
839 declarator2_using_reentrant
840 : declarator2 { $$ = $1 ; }
841 | declarator2 using_reentrant { addDecl ($1,0,$2); }
846 | '(' declarator ')' { $$ = $2; }
847 | declarator2 '[' ']'
852 DCL_TYPE(p) = ARRAY ;
856 | declarator2 '[' constant_expr ']'
861 p = (tval = constExprValue($3,TRUE))->etype;
862 /* if it is not a constant then Error */
863 if ( SPEC_SCLS(p) != S_LITERAL)
864 werror(E_CONST_EXPECTED) ;
867 DCL_TYPE(p) = ARRAY ;
868 DCL_ELEM(p) = (int) floatFromVal(tval) ;
872 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
873 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
876 addDecl ($1,FUNCTION,NULL) ;
878 $1->hasVargs = IS_VARG($4);
879 $1->args = reverseVal($4) ;
881 /* nest level was incremented to take care of the parms */
886 | declarator2 '(' parameter_identifier_list ')'
888 werror(E_OLD_STYLE,$1->name) ;
890 /* assume it returns an it */
891 $1->type = $1->etype = newIntLink();
897 : far_near_pointer { $$ = $1 ;}
898 | far_near_pointer type_specifier_list
903 | far_near_pointer pointer
908 | far_near_pointer type_specifier_list pointer
911 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
912 DCL_PTR_CONST($1) = SPEC_CONST($2);
913 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
914 switch (SPEC_SCLS($2)) {
916 DCL_TYPE($3) = FPOINTER;
919 DCL_TYPE($3) = IPOINTER ;
922 DCL_TYPE($3) = PPOINTER ;
925 DCL_TYPE($3) = POINTER ;
928 DCL_PTR_CONST($3) = 1;
929 DCL_TYPE($3) = CPOINTER ;
931 DCL_TYPE($3) = EEPPOINTER;
934 werror(W_PTR_TYPE_INVALID);
938 werror (W_PTR_TYPE_INVALID);
947 DCL_TYPE($$) = POINTER ;
955 : _XDATA { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; }
956 | _CODE { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ; DCL_PTR_CONST($$) = 1;}
957 | _PDATA { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; }
958 | _IDATA { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; }
959 | _NEAR { $$ = NULL ; }
960 | _GENERIC { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; }
961 | _EEPROM { $$ = newLink() ; DCL_TYPE($$) = EEPPOINTER ;}
962 | { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; }
967 | type_specifier_list type_specifier { $$ = mergeSpec ($1,$2); }
970 parameter_identifier_list
972 | identifier_list ',' ELIPSIS
977 | identifier_list ',' identifier
986 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
990 : parameter_declaration
991 | parameter_list ',' parameter_declaration
998 parameter_declaration
999 : type_specifier_list declarator
1002 pointerTypes($2->type,$1);
1004 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1011 $$->etype = getSpec($$->type);
1016 : type_specifier_list { $$ = $1 ;}
1017 | type_specifier_list abstract_declarator
1019 /* go to the end of the list */
1021 pointerTypes($2,$1);
1022 for ( p = $2 ; p->next ; p=p->next);
1029 : pointer { $$ = reverseLink($1); }
1030 | abstract_declarator2
1031 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1034 abstract_declarator2
1035 : '(' abstract_declarator ')' { $$ = $2 ; }
1038 DCL_TYPE($$) = ARRAY ;
1041 | '[' constant_expr ']' {
1044 DCL_TYPE($$) = ARRAY ;
1045 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1047 | abstract_declarator2 '[' ']' {
1049 DCL_TYPE($$) = ARRAY ;
1053 | abstract_declarator2 '[' constant_expr ']'
1057 DCL_TYPE($$) = ARRAY ;
1058 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1061 | '(' ')' { $$ = NULL;}
1062 | '(' parameter_type_list ')' { $$ = NULL;}
1063 | abstract_declarator2 '(' ')'
1064 | abstract_declarator2 '(' parameter_type_list ')'
1068 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1069 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1070 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1075 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1080 | compound_statement
1081 | expression_statement
1082 | selection_statement
1083 | iteration_statement
1086 ast *ex = newNode(INLINEASM,NULL,NULL);
1087 ALLOC_ATOMIC(ex->values.inlineasm,strlen($1));
1088 strcpy(ex->values.inlineasm,$1);
1094 : identifier ':' statement { $$ = createLabel($1,$3); }
1095 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1096 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1099 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1102 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1106 : start_block end_block { $$ = createBlock(NULL,NULL); }
1107 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1109 declaration_list { addSymChain($2); }
1110 end_block { $$ = createBlock($2,NULL) ; }
1112 declaration_list { addSymChain ($2); }
1114 end_block {$$ = createBlock($2,$4) ; }
1115 | error ';' { $$ = NULL ; }
1121 /* if this is typedef declare it immediately */
1122 if ( $1 && IS_TYPEDEF($1->etype)) {
1123 allocVariables ($1);
1130 | declaration_list declaration
1134 /* if this is a typedef */
1135 if ($2 && IS_TYPEDEF($2->etype)) {
1136 allocVariables ($2);
1140 /* get to the end of the previous decl */
1155 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1158 expression_statement
1164 : ELSE statement { $$ = $2 ; }
1170 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1171 | SWITCH '(' expr ')' {
1173 static int swLabel = 0 ;
1175 /* create a node for expression */
1176 ex = newNode(SWITCH,$3,NULL);
1177 STACK_PUSH(swStk,ex); /* save it in the stack */
1178 ex->values.switchVals.swNum = swLabel ;
1180 /* now create the label */
1181 sprintf(lbuff,"_swBrk_%d",swLabel++);
1182 $<sym>$ = newSymbol(lbuff,NestLevel);
1183 /* put label in the break stack */
1184 STACK_PUSH(breakStack,$<sym>$);
1187 /* get back the switch form the stack */
1188 $$ = STACK_POP(swStk) ;
1189 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1190 STACK_POP(breakStack);
1194 while : WHILE { /* create and push the continue , break & body labels */
1195 static int Lblnum = 0 ;
1197 sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1198 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1200 sprintf (lbuff,"_whilebreak_%d",Lblnum);
1201 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1203 sprintf (lbuff,"_whilebody_%d",Lblnum++);
1204 $$ = newSymbol(lbuff,NestLevel);
1207 do : DO { /* create and push the continue , break & body Labels */
1208 static int Lblnum = 0 ;
1211 sprintf(lbuff,"_docontinue_%d",Lblnum);
1212 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1214 sprintf (lbuff,"_dobreak_%d",Lblnum);
1215 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1217 sprintf (lbuff,"_dobody_%d",Lblnum++);
1218 $$ = newSymbol (lbuff,NestLevel);
1220 for : FOR { /* create & push continue, break & body labels */
1221 static int Lblnum = 0 ;
1224 sprintf (lbuff,"_forcontinue_%d",Lblnum);
1225 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1227 sprintf (lbuff,"_forbreak_%d",Lblnum);
1228 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1230 sprintf (lbuff,"_forbody_%d",Lblnum);
1231 $$ = newSymbol(lbuff,NestLevel);
1233 sprintf (lbuff,"_forcond_%d",Lblnum++);
1234 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1238 : while '(' expr ')' statement
1241 $$ = createWhile ( $1, STACK_POP(continueStack),
1242 STACK_POP(breakStack), $3, $5 );
1243 $$->lineno = $1->lineDef ;
1246 | do statement WHILE '(' expr ')' ';'
1249 $$ = createDo ( $1 , STACK_POP(continueStack),
1250 STACK_POP(breakStack), $5, $2);
1251 $$->lineno = $1->lineDef ;
1254 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1258 /* if break or continue statement present
1259 then create a general case loop */
1260 if (STACK_PEEK(continueStack)->isref ||
1261 STACK_PEEK(breakStack)->isref) {
1262 $$ = createFor ($1, STACK_POP(continueStack),
1263 STACK_POP(breakStack) ,
1264 STACK_POP(forStack) ,
1267 $$ = newNode(FOR,$9,NULL);
1268 AST_FOR($$,trueLabel) = $1;
1269 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1270 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1271 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1272 AST_FOR($$,initExpr) = $3;
1273 AST_FOR($$,condExpr) = $5;
1274 AST_FOR($$,loopExpr) = $7;
1287 : GOTO identifier ';' {
1289 $$ = newAst(EX_VALUE,symbolVal($2));
1290 $$ = newNode(GOTO,$$,NULL);
1293 /* make sure continue is in context */
1294 if (STACK_PEEK(continueStack) == NULL) {
1295 werror(E_BREAK_CONTEXT);
1299 $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(continueStack)));
1300 $$ = newNode(GOTO,$$,NULL);
1301 /* mark the continue label as referenced */
1302 STACK_PEEK(continueStack)->isref = 1;
1306 if (STACK_PEEK(breakStack) == NULL) {
1307 werror(E_BREAK_CONTEXT);
1310 $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(breakStack)));
1311 $$ = newNode(GOTO,$$,NULL);
1312 STACK_PEEK(breakStack)->isref = 1;
1315 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1316 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1320 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }
1324 extern unsigned char *yytext;
1326 extern char *filename;
1327 extern int fatalError;
1329 int yyerror(char *s)
1334 fprintf(stderr,"\n%s(%d) %s: token -> '%s' ; column %d\n",