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"
39 extern int yyerror (char *);
41 int NestLevel = 0 ; /* current NestLevel */
42 int stackPtr = 1 ; /* stack pointer */
43 int xstackPtr = 0 ; /* xstack pointer */
45 int blockNo = 0 ; /* sequential block number */
48 int seqPointNo= 1 ; /* sequence point number */
49 int ignoreTypedefType=0;
53 char lbuff[1024]; /* local buffer */
55 /* break & continue stacks */
56 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
57 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
58 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
59 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
60 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
62 value *cenum = NULL ; /* current enumeration type chain*/
63 bool uselessDecl = TRUE;
71 symbol *sym ; /* symbol table pointer */
72 structdef *sdef; /* structure definition */
73 char yychar[SDCC_NAME_MAX+1];
74 sym_link *lnk ; /* declarator or specifier */
75 int yyint; /* integer value returned */
76 value *val ; /* for integer constant */
77 initList *ilist; /* initial list */
78 const char *yyinline; /* inlined assembler code */
79 ast *asts; /* expression tree */
82 %token <yychar> IDENTIFIER TYPE_NAME
83 %token <val> CONSTANT STRING_LITERAL
85 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
87 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
88 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
89 %token <yyint> XOR_ASSIGN OR_ASSIGN
90 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR SFR16 SFR32
91 %token AT SBIT REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL
92 %token NONBANKED BANKED SHADOWREGS WPARAM
93 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE FIXED16X16 CONST VOLATILE VOID BIT
94 %token STRUCT UNION ENUM ELIPSIS RANGE FAR
95 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
96 %token NAKED JAVANATIVE OVERLAY
97 %token <yyinline> INLINEASM
98 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT GETABIT GETBYTE GETWORD
99 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
101 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
102 %token DUMMY_READ_VOLATILE ENDCRITICAL SWAP INLINE RESTRICT
104 %type <yyint> Interrupt_storage
105 %type <sym> identifier declarator declarator2 declarator3 enumerator_list enumerator
106 %type <sym> struct_declarator function_declarator function_declarator2
107 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
108 %type <sym> declaration init_declarator_list init_declarator
109 %type <sym> declaration_list identifier_list parameter_identifier_list
110 %type <sym> declarator2_function_attributes while do for critical
111 %type <lnk> pointer type_specifier_list type_specifier type_name
112 %type <lnk> storage_class_specifier struct_or_union_specifier
113 %type <lnk> declaration_specifiers sfr_reg_bit sfr_attributes type_specifier2
114 %type <lnk> function_attribute function_attributes enum_specifier
115 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
116 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
117 %type <sdef> stag opt_stag
118 %type <asts> primary_expr
119 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
120 %type <asts> additive_expr shift_expr relational_expr equality_expr
121 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
122 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
123 %type <asts> expr argument_expr_list function_definition expr_opt
124 %type <asts> statement_list statement labeled_statement compound_statement
125 %type <asts> expression_statement selection_statement iteration_statement
126 %type <asts> jump_statement function_body else_statement string_literal
127 %type <asts> critical_statement
128 %type <ilist> initializer initializer_list
129 %type <yyint> unary_operator assignment_operator struct_or_union
136 : external_definition
137 | file external_definition
141 : function_definition {
145 ignoreTypedefType = 0;
147 && IS_FUNC($1->type))
149 /* The only legal storage classes for
150 * a function prototype (declaration)
151 * are extern and static. extern is the
152 * default. Thus, if this function isn't
153 * explicitly marked static, mark it
157 && IS_SPEC($1->etype)
158 && !SPEC_STAT($1->etype))
160 SPEC_EXTR($1->etype) = 1;
164 allocVariables ($1) ;
165 cleanUpLevel (SymbolTab,1);
170 : function_declarator function_body { /* function type not specified */
171 /* assume it to be 'int' */
172 addDecl($1,0,newIntLink());
173 $$ = createFunction($1,$2);
175 | declaration_specifiers function_declarator function_body
177 pointerTypes($2->type,copyLinkChain($1));
179 $$ = createFunction($2,$3);
184 : function_attributes
185 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
189 : USING constant_expr {
190 $$ = newLink(SPECIFIER) ;
191 FUNC_REGBANK($$) = (int) floatFromVal(constExprValue($2,TRUE));
193 | REENTRANT { $$ = newLink (SPECIFIER);
196 | CRITICAL { $$ = newLink (SPECIFIER);
197 FUNC_ISCRITICAL($$) = 1;
199 | NAKED { $$ = newLink (SPECIFIER);
202 | JAVANATIVE { $$ = newLink (SPECIFIER);
203 FUNC_ISJAVANATIVE($$)=1;
205 | OVERLAY { $$ = newLink (SPECIFIER);
206 FUNC_ISOVERLAY($$)=1;
208 | NONBANKED {$$ = newLink (SPECIFIER);
209 FUNC_NONBANKED($$) = 1;
210 if (FUNC_BANKED($$)) {
211 werror(W_BANKED_WITH_NONBANKED);
214 | SHADOWREGS {$$ = newLink (SPECIFIER);
215 FUNC_ISSHADOWREGS($$) = 1;
217 | WPARAM {$$ = newLink (SPECIFIER);
218 FUNC_ISWPARAM($$) = 1;
220 | BANKED {$$ = newLink (SPECIFIER);
222 if (FUNC_NONBANKED($$)) {
223 werror(W_BANKED_WITH_NONBANKED);
226 werror(W_BANKED_WITH_STATIC);
231 $$ = newLink (SPECIFIER) ;
232 FUNC_INTNO($$) = $1 ;
239 | declaration_list compound_statement
241 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
247 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
248 | CONSTANT { $$ = newAst_VALUE($1); }
250 | '(' expr ')' { $$ = $2 ; }
254 : STRING_LITERAL { $$ = newAst_VALUE($1); }
259 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
260 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
261 $$->left->funcName = 1;}
262 | postfix_expr '(' argument_expr_list ')'
264 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
266 | postfix_expr '.' { ignoreTypedefType = 1; } identifier
268 ignoreTypedefType = 0;
269 $4 = newSymbol($4->name,NestLevel);
271 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($4)));
272 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($4))) ; */
274 | postfix_expr PTR_OP { ignoreTypedefType = 1; } identifier
276 ignoreTypedefType = 0;
277 $4 = newSymbol($4->name,NestLevel);
279 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($4)));
281 | postfix_expr INC_OP
282 { $$ = newNode(INC_OP,$1,NULL);}
283 | postfix_expr DEC_OP
284 { $$ = newNode(DEC_OP,$1,NULL); }
289 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
294 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
295 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
296 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
297 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
298 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
299 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
313 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
318 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
319 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
320 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
324 : multiplicative_expr
325 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
326 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
331 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
332 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
337 | relational_expr '<' shift_expr { $$ = newNode('<', $1,$3);}
338 | relational_expr '>' shift_expr { $$ = newNode('>', $1,$3);}
339 | relational_expr LE_OP shift_expr { $$ = newNode(LE_OP,$1,$3);}
340 | relational_expr GE_OP shift_expr { $$ = newNode(GE_OP,$1,$3);}
345 | equality_expr EQ_OP relational_expr { $$ = newNode(EQ_OP,$1,$3);}
346 | equality_expr NE_OP relational_expr { $$ = newNode(NE_OP,$1,$3);}
351 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
356 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
361 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
366 | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expr
367 { $$ = newNode(AND_OP,$1,$4);}
372 | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr
373 { $$ = newNode(OR_OP,$1,$4); }
378 | logical_or_expr '?' { seqPointNo++;} logical_or_expr ':' conditional_expr
380 $$ = newNode(':',$4,$6) ;
381 $$ = newNode('?',$1,$$) ;
387 | cast_expr assignment_operator assignment_expr
392 $$ = newNode($2,$1,$3);
395 $$ = createRMW($1, '*', $3);
398 $$ = createRMW($1, '/', $3);
401 $$ = createRMW($1, '%', $3);
404 $$ = createRMW($1, '+', $3);
407 $$ = createRMW($1, '-', $3);
410 $$ = createRMW($1, LEFT_OP, $3);
413 $$ = createRMW($1, RIGHT_OP, $3);
416 $$ = createRMW($1, '&', $3);
419 $$ = createRMW($1, '^', $3);
422 /* $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); */
423 /* $$ = newNode('=',removePostIncDecOps(copyAst($1)),
424 newNode('|',removePreIncDecOps(copyAst($1)),$3)); */
425 $$ = createRMW($1, '|', $3);
450 | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);}
458 : declaration_specifiers ';'
461 werror(W_USELESS_DECL);
465 | declaration_specifiers init_declarator_list ';'
467 /* add the specifier list to the id */
470 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
471 sym_link *lnk = copyLinkChain($1);
472 /* do the pointer stuff */
473 pointerTypes(sym->type,lnk);
474 addDecl (sym,0,lnk) ;
482 declaration_specifiers
483 : storage_class_specifier { $$ = $1; }
484 | storage_class_specifier declaration_specifiers {
485 /* if the decl $2 is not a specifier */
486 /* find the spec and replace it */
489 while (lnk && !IS_SPEC(lnk->next))
491 lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
495 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
497 | type_specifier { $$ = $1; }
498 | type_specifier declaration_specifiers {
499 /* if the decl $2 is not a specifier */
500 /* find the spec and replace it */
503 while (lnk && !IS_SPEC(lnk->next))
505 lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
509 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
515 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
519 : declarator { $1->ival = NULL ; }
520 | declarator '=' initializer { $1->ival = $3 ; }
524 storage_class_specifier
526 $$ = newLink (SPECIFIER) ;
527 SPEC_TYPEDEF($$) = 1 ;
530 $$ = newLink(SPECIFIER);
534 $$ = newLink (SPECIFIER);
538 $$ = newLink (SPECIFIER) ;
539 SPEC_SCLS($$) = S_AUTO ;
542 $$ = newLink (SPECIFIER);
543 SPEC_SCLS($$) = S_REGISTER ;
548 : INTERRUPT { $$ = INTNO_UNSPEC ; }
549 | INTERRUPT constant_expr
550 { int intno = (int) floatFromVal(constExprValue($2,TRUE));
551 if ((intno >= 0) && (intno <= INTNO_MAX))
555 werror(E_INT_BAD_INTNO, intno);
563 | type_specifier2 AT constant_expr
565 /* add this to the storage class specifier */
566 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
567 /* now get the abs addr from value */
568 SPEC_ADDR($1) = (unsigned) floatFromVal(constExprValue($3,TRUE)) ;
574 $$=newLink(SPECIFIER);
575 SPEC_NOUN($$) = V_CHAR ;
576 ignoreTypedefType = 1;
579 $$=newLink(SPECIFIER);
581 ignoreTypedefType = 1;
584 $$=newLink(SPECIFIER);
585 SPEC_NOUN($$) = V_INT ;
586 ignoreTypedefType = 1;
589 $$=newLink(SPECIFIER);
591 ignoreTypedefType = 1;
594 $$=newLink(SPECIFIER);
595 $$->select.s.b_signed = 1;
596 ignoreTypedefType = 1;
599 $$=newLink(SPECIFIER);
601 ignoreTypedefType = 1;
604 $$=newLink(SPECIFIER);
605 SPEC_NOUN($$) = V_VOID ;
606 ignoreTypedefType = 1;
609 $$=newLink(SPECIFIER);
613 $$=newLink(SPECIFIER);
614 SPEC_VOLATILE($$) = 1 ;
617 $$=newLink(SPECIFIER);
618 SPEC_NOUN($$) = V_FLOAT;
619 ignoreTypedefType = 1;
622 $$=newLink(SPECIFIER);
623 SPEC_NOUN($$) = V_FIXED16X16;
624 ignoreTypedefType = 1;
627 $$ = newLink (SPECIFIER);
628 SPEC_SCLS($$) = S_XDATA ;
631 $$ = newLink (SPECIFIER) ;
632 SPEC_SCLS($$) = S_CODE ;
635 $$ = newLink (SPECIFIER) ;
636 SPEC_SCLS($$) = S_EEPROM ;
639 $$ = newLink (SPECIFIER);
640 SPEC_SCLS($$) = S_DATA ;
643 $$ = newLink (SPECIFIER);
644 SPEC_SCLS($$) = S_IDATA ;
647 $$ = newLink (SPECIFIER);
648 SPEC_SCLS($$) = S_PDATA ;
651 $$=newLink(SPECIFIER);
652 SPEC_NOUN($$) = V_BIT ;
653 SPEC_SCLS($$) = S_BIT ;
656 ignoreTypedefType = 1;
659 | struct_or_union_specifier {
662 ignoreTypedefType = 1;
667 ignoreTypedefType = 1;
674 sym = findSym(TypedefTab,NULL,$1) ;
675 $$ = p = copyLinkChain(sym->type);
676 SPEC_TYPEDEF(getSpec(p)) = 0;
677 ignoreTypedefType = 1;
684 $$ = newLink(SPECIFIER) ;
685 SPEC_NOUN($$) = V_SBIT;
686 SPEC_SCLS($$) = S_SBIT;
689 ignoreTypedefType = 1;
696 $$ = newLink(SPECIFIER) ;
697 FUNC_REGBANK($$) = 0;
698 SPEC_NOUN($$) = V_CHAR;
699 SPEC_SCLS($$) = S_SFR ;
701 ignoreTypedefType = 1;
704 $$ = newLink(SPECIFIER) ;
705 FUNC_REGBANK($$) = 1;
706 SPEC_NOUN($$) = V_CHAR;
707 SPEC_SCLS($$) = S_SFR ;
709 ignoreTypedefType = 1;
715 $$ = newLink(SPECIFIER) ;
716 FUNC_REGBANK($$) = 0;
717 SPEC_NOUN($$) = V_INT;
718 SPEC_SCLS($$) = S_SFR;
720 ignoreTypedefType = 1;
726 $$ = newLink(SPECIFIER) ;
727 FUNC_REGBANK($$) = 0;
728 SPEC_NOUN($$) = V_INT;
729 SPEC_SCLS($$) = S_SFR;
732 ignoreTypedefType = 1;
736 struct_or_union_specifier
737 : struct_or_union opt_stag
746 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
750 '{' struct_declaration_list '}'
755 // check for errors in structure members
756 for (sym=$5; sym; sym=sym->next) {
757 if (IS_ABSOLUTE(sym->etype)) {
758 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'");
759 SPEC_ABSA(sym->etype) = 0;
761 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
762 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class");
763 printTypeChainRaw (sym->type,NULL);
764 SPEC_SCLS(sym->etype) = 0;
766 for (dsym=sym->next; dsym; dsym=dsym->next) {
767 if (*dsym->name && strcmp(sym->name, dsym->name)==0) {
768 werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER,
769 $1==STRUCT ? "struct" : "union", sym->name);
770 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
775 /* Create a structdef */
777 sdef->fields = reverseSyms($5) ; /* link the fields */
778 sdef->size = compStructSize($1,sdef); /* update size of */
779 promoteAnonStructs ($1, sdef);
781 /* Create the specifier */
782 $$ = newLink (SPECIFIER) ;
783 SPEC_NOUN($$) = V_STRUCT;
784 SPEC_STRUCT($$)= sdef ;
786 | struct_or_union stag
788 $$ = newLink(SPECIFIER) ;
789 SPEC_NOUN($$) = V_STRUCT;
790 SPEC_STRUCT($$) = $2;
799 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
805 : STRUCT { $$ = STRUCT ; }
806 | UNION { $$ = UNION ; }
811 | { /* synthesize a name add to structtable */
812 $$ = newStruct(genSymName(NestLevel)) ;
813 $$->level = NestLevel ;
814 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
818 : identifier { /* add name to structure table */
819 $$ = findSymWithBlock (StructTab,$1,currBlockno);
821 $$ = newStruct($1->name) ;
822 $$->level = NestLevel ;
823 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
828 struct_declaration_list
830 | struct_declaration_list struct_declaration
834 /* go to the end of the chain */
835 while (sym->next) sym=sym->next;
843 : type_specifier_list struct_declarator_list ';'
845 /* add this type to all the symbols */
847 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
848 sym_link *btype = copyLinkChain($1);
850 /* make the symbol one level up */
853 pointerTypes(sym->type,btype);
856 sym->etype = getSpec(sym->type);
859 addDecl (sym,0,btype);
860 /* make sure the type is complete and sane */
861 checkTypeSanity(sym->etype, sym->name);
863 ignoreTypedefType = 0;
868 struct_declarator_list
870 | struct_declarator_list ',' struct_declarator
879 | ':' constant_expr {
880 unsigned int bitsize;
881 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
882 bitsize= (unsigned int) floatFromVal(constExprValue($2,TRUE));
883 if (bitsize > (port->s.int_size * 8)) {
884 bitsize = port->s.int_size * 8;
885 werror(E_BITFLD_SIZE, bitsize);
888 bitsize = BITVAR_PAD;
889 $$->bitVar = bitsize;
891 | declarator ':' constant_expr
893 unsigned int bitsize;
894 bitsize= (unsigned int) floatFromVal(constExprValue($3,TRUE));
895 if (bitsize > (port->s.int_size * 8)) {
896 bitsize = port->s.int_size * 8;
897 werror(E_BITFLD_SIZE, bitsize);
900 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
901 $$->bitVar = BITVAR_PAD;
902 werror(W_BITFLD_NAMED);
905 $1->bitVar = bitsize;
907 | { $$ = newSymbol ("", NestLevel) ; }
912 : ENUM '{' enumerator_list '}' {
913 $$ = newEnumType ($3); //copyLinkChain(cenum->type);
914 SPEC_SCLS(getSpec($$)) = 0;
917 | ENUM identifier '{' enumerator_list '}' {
921 csym=findSym(enumTab,$2,$2->name);
922 if ((csym && csym->level == $2->level))
924 werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
925 werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
928 enumtype = newEnumType ($4); //copyLinkChain(cenum->type);
929 SPEC_SCLS(getSpec(enumtype)) = 0;
932 /* add this to the enumerator table */
934 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
935 $$ = copyLinkChain(enumtype);
940 /* check the enumerator table */
941 if ((csym = findSym(enumTab,$2,$2->name)))
942 $$ = copyLinkChain(csym->type);
944 $$ = newLink(SPECIFIER) ;
945 SPEC_NOUN($$) = V_INT ;
952 | enumerator_list ',' {
954 | enumerator_list ',' enumerator
958 for (dsym=$1; dsym; dsym=dsym->next)
960 if (strcmp($3->name, dsym->name)==0)
962 werrorfl($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
963 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
973 : identifier opt_assign_expr
975 /* make the symbol one level up */
977 $1->type = copyLinkChain($2->type);
978 $1->etype= getSpec($1->type);
979 SPEC_ENUM($1->etype) = 1;
981 // do this now, so we can use it for the next enums in the list
987 : '=' constant_expr {
990 val = constExprValue($2,TRUE);
991 if (!IS_INT(val->type) && !IS_CHAR(val->type))
993 werror(E_ENUM_NON_INTEGER);
994 SNPRINTF(lbuff, sizeof(lbuff),
995 "%d",(int) floatFromVal(val));
996 val = constVal(lbuff);
1002 SNPRINTF(lbuff, sizeof(lbuff),
1003 "%d",(int) floatFromVal(cenum)+1);
1004 $$ = cenum = constVal(lbuff);
1007 SNPRINTF(lbuff, sizeof(lbuff),
1009 $$ = cenum = constVal(lbuff);
1015 : declarator3 { $$ = $1 ; }
1016 | pointer declarator3
1018 addDecl ($2,0,reverseLink($1));
1024 : declarator2_function_attributes { $$ = $1 ; }
1025 | declarator2 { $$ = $1 ; }
1029 : declarator2_function_attributes { $$ = $1; }
1030 | pointer declarator2_function_attributes
1032 addDecl ($2,0,reverseLink($1));
1037 declarator2_function_attributes
1038 : function_declarator2 { $$ = $1 ; }
1039 | function_declarator2 function_attribute {
1040 // copy the functionAttributes (not the args and hasVargs !!)
1043 sym_link *funcType=$1->type;
1045 while (funcType && !IS_FUNC(funcType))
1046 funcType = funcType->next;
1049 werror (E_FUNC_ATTR);
1052 args=FUNC_ARGS(funcType);
1053 hasVargs=FUNC_HASVARARGS(funcType);
1055 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
1056 sizeof($2->funcAttrs));
1058 FUNC_ARGS(funcType)=args;
1059 FUNC_HASVARARGS(funcType)=hasVargs;
1062 memset (&$2->funcAttrs, 0,
1063 sizeof($2->funcAttrs));
1072 | '(' declarator ')' { $$ = $2; }
1073 | declarator3 '[' ']'
1077 p = newLink (DECLARATOR);
1078 DCL_TYPE(p) = ARRAY ;
1082 | declarator3 '[' constant_expr ']'
1087 tval = constExprValue($3,TRUE);
1088 /* if it is not a constant then Error */
1089 p = newLink (DECLARATOR);
1090 DCL_TYPE(p) = ARRAY ;
1091 if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1092 werror(E_CONST_EXPECTED) ;
1093 /* Assume a single item array to limit the cascade */
1094 /* of additional errors. */
1098 DCL_ELEM(p) = (int) floatFromVal(tval) ;
1104 function_declarator2
1105 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
1106 | declarator2 '(' { NestLevel++ ; currBlockno++; }
1107 parameter_type_list ')'
1111 addDecl ($1,FUNCTION,NULL) ;
1113 funcType = $1->type;
1114 while (funcType && !IS_FUNC(funcType))
1115 funcType = funcType->next;
1119 FUNC_HASVARARGS(funcType) = IS_VARG($4);
1120 FUNC_ARGS(funcType) = reverseVal($4);
1122 /* nest level was incremented to take care of the parms */
1126 // if this was a pointer (to a function)
1127 if (!IS_FUNC($1->type))
1128 cleanUpLevel(SymbolTab,NestLevel+1);
1132 | declarator2 '(' parameter_identifier_list ')'
1134 werror(E_OLD_STYLE,$1->name) ;
1135 /* assume it returns an int */
1136 $1->type = $1->etype = newIntLink();
1142 : unqualified_pointer { $$ = $1 ;}
1143 | unqualified_pointer type_specifier_list
1148 DCL_PTR_CONST($1) = SPEC_CONST($2);
1149 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1152 werror (W_PTR_TYPE_INVALID);
1154 | unqualified_pointer pointer
1158 DCL_TYPE($2)=port->unqualified_pointer;
1160 | unqualified_pointer type_specifier_list pointer
1163 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1164 DCL_PTR_CONST($1) = SPEC_CONST($2);
1165 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1166 switch (SPEC_SCLS($2)) {
1168 DCL_TYPE($3) = FPOINTER;
1171 DCL_TYPE($3) = IPOINTER ;
1174 DCL_TYPE($3) = PPOINTER ;
1177 DCL_TYPE($3) = POINTER ;
1180 DCL_TYPE($3) = CPOINTER ;
1183 DCL_TYPE($3) = EEPPOINTER;
1186 // this could be just "constant"
1187 // werror(W_PTR_TYPE_INVALID);
1192 werror (W_PTR_TYPE_INVALID);
1200 $$ = newLink(DECLARATOR);
1201 DCL_TYPE($$)=UPOINTER;
1207 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1208 | type_specifier_list type_specifier {
1209 /* if the decl $2 is not a specifier */
1210 /* find the spec and replace it */
1211 if ( !IS_SPEC($2)) {
1212 sym_link *lnk = $2 ;
1213 while (lnk && !IS_SPEC(lnk->next))
1215 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1219 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1223 parameter_identifier_list
1225 | identifier_list ',' ELIPSIS
1230 | identifier_list ',' identifier
1239 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1243 : parameter_declaration
1244 | parameter_list ',' parameter_declaration
1251 parameter_declaration
1252 : type_specifier_list declarator
1255 pointerTypes($2->type,$1);
1257 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1260 ignoreTypedefType = 0;
1265 $$->etype = getSpec($$->type);
1266 ignoreTypedefType = 0;
1271 : type_specifier_list { $$ = $1; ignoreTypedefType = 0;}
1272 | type_specifier_list abstract_declarator
1274 /* go to the end of the list */
1276 pointerTypes($2,$1);
1277 for ( p = $2 ; p && p->next ; p=p->next);
1279 werror(E_SYNTAX_ERROR, yytext);
1284 ignoreTypedefType = 0;
1289 : pointer { $$ = reverseLink($1); }
1290 | abstract_declarator2
1291 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1292 if (IS_PTR($1) && IS_FUNC($2))
1293 DCL_TYPE($1) = CPOINTER;
1297 abstract_declarator2
1298 : '(' abstract_declarator ')' { $$ = $2 ; }
1300 $$ = newLink (DECLARATOR);
1301 DCL_TYPE($$) = ARRAY ;
1304 | '[' constant_expr ']' {
1306 $$ = newLink (DECLARATOR);
1307 DCL_TYPE($$) = ARRAY ;
1308 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1310 | abstract_declarator2 '[' ']' {
1311 $$ = newLink (DECLARATOR);
1312 DCL_TYPE($$) = ARRAY ;
1316 | abstract_declarator2 '[' constant_expr ']'
1319 $$ = newLink (DECLARATOR);
1320 DCL_TYPE($$) = ARRAY ;
1321 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1324 | '(' ')' { $$ = NULL;}
1325 | '(' parameter_type_list ')' { $$ = NULL;}
1326 | abstract_declarator2 '(' ')' {
1327 // $1 must be a pointer to a function
1328 sym_link *p=newLink(DECLARATOR);
1329 DCL_TYPE(p) = FUNCTION;
1331 // ((void (code *) ()) 0) ()
1332 $1=newLink(DECLARATOR);
1333 DCL_TYPE($1)=CPOINTER;
1338 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1339 sym_link *p=newLink(DECLARATOR);
1340 DCL_TYPE(p) = FUNCTION;
1342 FUNC_HASVARARGS(p) = IS_VARG($4);
1343 FUNC_ARGS(p) = reverseVal($4);
1345 /* nest level was incremented to take care of the parms */
1349 /* ((void (code *) (void)) 0) () */
1350 $1=newLink(DECLARATOR);
1351 DCL_TYPE($1)=CPOINTER;
1356 // remove the symbol args (if any)
1357 cleanUpLevel(SymbolTab,NestLevel+1);
1362 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1363 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1364 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1369 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1374 | compound_statement
1375 | expression_statement
1376 | selection_statement
1377 | iteration_statement
1379 | critical_statement
1383 ex = newNode(INLINEASM,NULL,NULL);
1384 ex->values.inlineasm = strdup($1);
1393 STACK_PUSH(continueStack,NULL);
1394 STACK_PUSH(breakStack,NULL);
1400 : critical statement {
1401 STACK_POP(breakStack);
1402 STACK_POP(continueStack);
1404 $$ = newNode(CRITICAL,$2,NULL);
1409 // : identifier ':' statement { $$ = createLabel($1,$3); }
1410 : identifier ':' { $$ = createLabel($1,NULL);
1412 | CASE constant_expr ':'
1414 if (STACK_EMPTY(swStk))
1415 $$ = createCase(NULL,$2,NULL);
1417 $$ = createCase(STACK_PEEK(swStk),$2,NULL);
1419 | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
1421 if (STACK_EMPTY(swStk))
1422 $$ = createDefault(NULL,$<asts>2,NULL);
1424 $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL);
1430 STACK_PUSH(blockNum,currBlockno);
1431 currBlockno = ++blockNo ;
1432 ignoreTypedefType = 0;
1436 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1440 : start_block end_block { $$ = createBlock(NULL,NULL); }
1441 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1443 declaration_list { addSymChain(&$2); }
1444 end_block { $$ = createBlock($2,NULL) ; }
1446 declaration_list { addSymChain (&$2); }
1448 end_block {$$ = createBlock($2,$4) ; }
1449 | error ';' { $$ = NULL ; }
1455 /* if this is typedef declare it immediately */
1456 if ( $1 && IS_TYPEDEF($1->etype)) {
1457 allocVariables ($1);
1462 ignoreTypedefType = 0;
1465 | declaration_list declaration
1469 /* if this is a typedef */
1470 if ($2 && IS_TYPEDEF($2->etype)) {
1471 allocVariables ($2);
1475 /* get to the end of the previous decl */
1485 ignoreTypedefType = 0;
1491 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1494 expression_statement
1496 | expr ';' { $$ = $1; seqPointNo++;}
1500 : ELSE statement { $$ = $2 ; }
1506 : IF '(' expr ')' { seqPointNo++;} statement else_statement
1509 $$ = createIf ($3, $6, $7 );
1512 | SWITCH '(' expr ')' {
1514 static int swLabel = 0 ;
1517 /* create a node for expression */
1518 ex = newNode(SWITCH,$3,NULL);
1519 STACK_PUSH(swStk,ex); /* save it in the stack */
1520 ex->values.switchVals.swNum = swLabel ;
1522 /* now create the label */
1523 SNPRINTF(lbuff, sizeof(lbuff),
1524 "_swBrk_%d",swLabel++);
1525 $<sym>$ = newSymbol(lbuff,NestLevel);
1526 /* put label in the break stack */
1527 STACK_PUSH(breakStack,$<sym>$);
1530 /* get back the switch form the stack */
1531 $$ = STACK_POP(swStk) ;
1532 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1533 STACK_POP(breakStack);
1537 while : WHILE { /* create and push the continue , break & body labels */
1538 static int Lblnum = 0 ;
1540 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1541 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1543 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1544 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1546 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1547 $$ = newSymbol(lbuff,NestLevel);
1551 do : DO { /* create and push the continue , break & body Labels */
1552 static int Lblnum = 0 ;
1555 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1556 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1558 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1559 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1561 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1562 $$ = newSymbol (lbuff,NestLevel);
1566 for : FOR { /* create & push continue, break & body labels */
1567 static int Lblnum = 0 ;
1570 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1571 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1573 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1574 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1576 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1577 $$ = newSymbol(lbuff,NestLevel);
1579 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1580 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1585 : while '(' expr ')' { seqPointNo++;} statement
1588 $$ = createWhile ( $1, STACK_POP(continueStack),
1589 STACK_POP(breakStack), $3, $6 );
1590 $$->lineno = $1->lineDef ;
1593 | do statement WHILE '(' expr ')' ';'
1597 $$ = createDo ( $1 , STACK_POP(continueStack),
1598 STACK_POP(breakStack), $5, $2);
1599 $$->lineno = $1->lineDef ;
1602 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1606 /* if break or continue statement present
1607 then create a general case loop */
1608 if (STACK_PEEK(continueStack)->isref ||
1609 STACK_PEEK(breakStack)->isref) {
1610 $$ = createFor ($1, STACK_POP(continueStack),
1611 STACK_POP(breakStack) ,
1612 STACK_POP(forStack) ,
1615 $$ = newNode(FOR,$9,NULL);
1616 AST_FOR($$,trueLabel) = $1;
1617 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1618 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1619 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1620 AST_FOR($$,initExpr) = $3;
1621 AST_FOR($$,condExpr) = $5;
1622 AST_FOR($$,loopExpr) = $7;
1630 : { $$ = NULL ; seqPointNo++; }
1631 | expr { $$ = $1 ; seqPointNo++; }
1635 : GOTO identifier ';' {
1637 $$ = newAst_VALUE(symbolVal($2));
1638 $$ = newNode(GOTO,$$,NULL);
1641 /* make sure continue is in context */
1642 if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1643 werror(E_BREAK_CONTEXT);
1647 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1648 $$ = newNode(GOTO,$$,NULL);
1649 /* mark the continue label as referenced */
1650 STACK_PEEK(continueStack)->isref = 1;
1654 if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1655 werror(E_BREAK_CONTEXT);
1658 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1659 $$ = newNode(GOTO,$$,NULL);
1660 STACK_PEEK(breakStack)->isref = 1;
1666 werror(E_INVALID_CRITICAL);
1669 $$ = newNode(RETURN,NULL,NULL);
1675 werror(E_INVALID_CRITICAL);
1678 $$ = newNode(RETURN,NULL,$2);
1684 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }