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 AT SBIT
91 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
92 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
93 %token STRUCT UNION ENUM ELIPSIS RANGE FAR
94 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
95 %token NAKED JAVANATIVE OVERLAY
96 %token <yyinline> INLINEASM
97 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
98 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
100 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
101 %token DUMMY_READ_VOLATILE ENDCRITICAL SWAP
103 %type <yyint> Interrupt_storage
104 %type <sym> identifier declarator declarator2 declarator3 enumerator_list enumerator
105 %type <sym> struct_declarator function_declarator function_declarator2
106 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
107 %type <sym> declaration init_declarator_list init_declarator
108 %type <sym> declaration_list identifier_list parameter_identifier_list
109 %type <sym> declarator2_function_attributes while do for critical
110 %type <lnk> pointer type_specifier_list type_specifier type_name
111 %type <lnk> storage_class_specifier struct_or_union_specifier
112 %type <lnk> declaration_specifiers sfr_reg_bit sfr_attributes type_specifier2
113 %type <lnk> function_attribute function_attributes enum_specifier
114 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
115 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
116 %type <sdef> stag opt_stag
117 %type <asts> primary_expr
118 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
119 %type <asts> additive_expr shift_expr relational_expr equality_expr
120 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
121 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
122 %type <asts> expr argument_expr_list function_definition expr_opt
123 %type <asts> statement_list statement labeled_statement compound_statement
124 %type <asts> expression_statement selection_statement iteration_statement
125 %type <asts> jump_statement function_body else_statement string_literal
126 %type <asts> critical_statement
127 %type <ilist> initializer initializer_list
128 %type <yyint> unary_operator assignment_operator struct_or_union
135 : external_definition
136 | file external_definition
140 : function_definition {
144 ignoreTypedefType = 0;
146 && IS_FUNC($1->type))
148 /* The only legal storage classes for
149 * a function prototype (declaration)
150 * are extern and static. extern is the
151 * default. Thus, if this function isn't
152 * explicitly marked static, mark it
156 && IS_SPEC($1->etype)
157 && !SPEC_STAT($1->etype))
159 SPEC_EXTR($1->etype) = 1;
163 allocVariables ($1) ;
164 cleanUpLevel (SymbolTab,1);
169 : function_declarator function_body { /* function type not specified */
170 /* assume it to be 'int' */
171 addDecl($1,0,newIntLink());
172 $$ = createFunction($1,$2);
174 | declaration_specifiers function_declarator function_body
176 pointerTypes($2->type,copyLinkChain($1));
178 $$ = createFunction($2,$3);
183 : function_attributes
184 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
189 $$ = newLink(SPECIFIER) ;
190 FUNC_REGBANK($$) = (int) floatFromVal($2);
192 | REENTRANT { $$ = newLink (SPECIFIER);
195 | CRITICAL { $$ = newLink (SPECIFIER);
196 FUNC_ISCRITICAL($$) = 1;
198 | NAKED { $$ = newLink (SPECIFIER);
201 | JAVANATIVE { $$ = newLink (SPECIFIER);
202 FUNC_ISJAVANATIVE($$)=1;
204 | OVERLAY { $$ = newLink (SPECIFIER);
205 FUNC_ISOVERLAY($$)=1;
207 | NONBANKED {$$ = newLink (SPECIFIER);
208 FUNC_NONBANKED($$) = 1;
209 if (FUNC_BANKED($$)) {
210 werror(W_BANKED_WITH_NONBANKED);
213 | BANKED {$$ = newLink (SPECIFIER);
215 if (FUNC_NONBANKED($$)) {
216 werror(W_BANKED_WITH_NONBANKED);
219 werror(W_BANKED_WITH_STATIC);
224 $$ = newLink (SPECIFIER) ;
225 FUNC_INTNO($$) = $1 ;
232 | declaration_list compound_statement
234 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
240 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
241 | CONSTANT { $$ = newAst_VALUE($1); }
243 | '(' expr ')' { $$ = $2 ; }
247 : STRING_LITERAL { $$ = newAst_VALUE($1); }
252 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
253 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
254 $$->left->funcName = 1;}
255 | postfix_expr '(' argument_expr_list ')'
257 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
259 | postfix_expr '.' { ignoreTypedefType = 1; } identifier
261 ignoreTypedefType = 0;
262 $4 = newSymbol($4->name,NestLevel);
264 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($4)));
265 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($4))) ; */
267 | postfix_expr PTR_OP { ignoreTypedefType = 1; } identifier
269 ignoreTypedefType = 0;
270 $4 = newSymbol($4->name,NestLevel);
272 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($4)));
274 | postfix_expr INC_OP
275 { $$ = newNode(INC_OP,$1,NULL);}
276 | postfix_expr DEC_OP
277 { $$ = newNode(DEC_OP,$1,NULL); }
282 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
287 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
288 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
289 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
290 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
291 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
292 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
306 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
311 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
312 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
313 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
317 : multiplicative_expr
318 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
319 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
324 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
325 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
330 | relational_expr '<' shift_expr {
332 newNode('!',newNode(GE_OP,$1,$3),NULL) :
333 newNode('<', $1,$3));
335 | relational_expr '>' shift_expr {
337 newNode('!',newNode(LE_OP,$1,$3),NULL) :
340 | relational_expr LE_OP shift_expr {
342 newNode('!', newNode('>', $1 , $3 ), NULL) :
343 newNode(LE_OP,$1,$3));
345 | relational_expr GE_OP shift_expr {
347 newNode('!', newNode('<', $1 , $3 ), NULL) :
348 newNode(GE_OP,$1,$3));
354 | equality_expr EQ_OP relational_expr {
356 newNode('!',newNode(NE_OP,$1,$3),NULL) :
357 newNode(EQ_OP,$1,$3));
359 | equality_expr NE_OP relational_expr {
361 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
362 newNode(NE_OP,$1,$3));
368 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
373 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
378 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
383 | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expr
384 { $$ = newNode(AND_OP,$1,$4);}
389 | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr
390 { $$ = newNode(OR_OP,$1,$4); }
395 | logical_or_expr '?' { seqPointNo++;} logical_or_expr ':' conditional_expr
397 $$ = newNode(':',$4,$6) ;
398 $$ = newNode('?',$1,$$) ;
404 | unary_expr assignment_operator assignment_expr
409 $$ = newNode($2,$1,$3);
412 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
413 newNode('*',removePreIncDecOps(copyAst($1)),$3));
416 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
417 newNode('/',removePreIncDecOps(copyAst($1)),$3));
420 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
421 newNode('%',removePreIncDecOps(copyAst($1)),$3));
424 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
425 newNode('+',removePreIncDecOps(copyAst($1)),$3));
428 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
429 newNode('-',removePreIncDecOps(copyAst($1)),$3));
432 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
433 newNode(LEFT_OP,removePreIncDecOps(copyAst($1)),$3));
436 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
437 newNode(RIGHT_OP,removePreIncDecOps(copyAst($1)),$3));
440 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
441 newNode('&',removePreIncDecOps(copyAst($1)),$3));
444 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
445 newNode('^',removePreIncDecOps(copyAst($1)),$3));
448 /* $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); */
449 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
450 newNode('|',removePreIncDecOps(copyAst($1)),$3));
475 | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);}
483 : declaration_specifiers ';'
486 werror(W_USELESS_DECL);
490 | declaration_specifiers init_declarator_list ';'
492 /* add the specifier list to the id */
495 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
496 sym_link *lnk = copyLinkChain($1);
497 /* do the pointer stuff */
498 pointerTypes(sym->type,lnk);
499 addDecl (sym,0,lnk) ;
507 declaration_specifiers
508 : storage_class_specifier { $$ = $1; }
509 | storage_class_specifier declaration_specifiers {
510 /* if the decl $2 is not a specifier */
511 /* find the spec and replace it */
514 while (lnk && !IS_SPEC(lnk->next))
516 lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
520 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
522 | type_specifier { $$ = $1; }
523 | type_specifier declaration_specifiers {
524 /* if the decl $2 is not a specifier */
525 /* find the spec and replace it */
528 while (lnk && !IS_SPEC(lnk->next))
530 lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
534 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
540 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
544 : declarator { $1->ival = NULL ; }
545 | declarator '=' initializer { $1->ival = $3 ; }
549 storage_class_specifier
551 $$ = newLink (SPECIFIER) ;
552 SPEC_TYPEDEF($$) = 1 ;
555 $$ = newLink(SPECIFIER);
559 $$ = newLink (SPECIFIER);
563 $$ = newLink (SPECIFIER) ;
564 SPEC_SCLS($$) = S_AUTO ;
567 $$ = newLink (SPECIFIER);
568 SPEC_SCLS($$) = S_REGISTER ;
573 : INTERRUPT { $$ = INTNO_UNSPEC ; }
575 { int intno = (int) floatFromVal($2);
576 if ((intno >= 0) && (intno <= INTNO_MAX))
580 werror(E_INT_BAD_INTNO, intno);
588 | type_specifier2 AT constant_expr
590 /* add this to the storage class specifier */
591 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
592 /* now get the abs addr from value */
593 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
599 $$=newLink(SPECIFIER);
600 SPEC_NOUN($$) = V_CHAR ;
601 ignoreTypedefType = 1;
604 $$=newLink(SPECIFIER);
605 $$->select.s._short = 1 ;
606 ignoreTypedefType = 1;
609 $$=newLink(SPECIFIER);
610 SPEC_NOUN($$) = V_INT ;
611 ignoreTypedefType = 1;
614 $$=newLink(SPECIFIER);
616 ignoreTypedefType = 1;
619 $$=newLink(SPECIFIER);
620 $$->select.s._signed = 1;
621 ignoreTypedefType = 1;
624 $$=newLink(SPECIFIER);
626 ignoreTypedefType = 1;
629 $$=newLink(SPECIFIER);
630 SPEC_NOUN($$) = V_VOID ;
631 ignoreTypedefType = 1;
634 $$=newLink(SPECIFIER);
638 $$=newLink(SPECIFIER);
639 SPEC_VOLATILE($$) = 1 ;
642 $$=newLink(SPECIFIER);
643 SPEC_NOUN($$) = V_FLOAT;
644 ignoreTypedefType = 1;
647 $$ = newLink (SPECIFIER);
648 SPEC_SCLS($$) = S_XDATA ;
651 $$ = newLink (SPECIFIER) ;
652 SPEC_SCLS($$) = S_CODE ;
655 $$ = newLink (SPECIFIER) ;
656 SPEC_SCLS($$) = S_EEPROM ;
659 $$ = newLink (SPECIFIER);
660 SPEC_SCLS($$) = S_DATA ;
663 $$ = newLink (SPECIFIER);
664 SPEC_SCLS($$) = S_IDATA ;
667 $$ = newLink (SPECIFIER);
668 SPEC_SCLS($$) = S_PDATA ;
671 $$=newLink(SPECIFIER);
672 SPEC_NOUN($$) = V_BIT ;
673 SPEC_SCLS($$) = S_BIT ;
676 ignoreTypedefType = 1;
679 | struct_or_union_specifier {
682 ignoreTypedefType = 1;
687 ignoreTypedefType = 1;
694 sym = findSym(TypedefTab,NULL,$1) ;
695 $$ = p = copyLinkChain(sym->type);
696 SPEC_TYPEDEF(getSpec(p)) = 0;
697 ignoreTypedefType = 1;
704 $$ = newLink(SPECIFIER) ;
705 SPEC_NOUN($$) = V_SBIT;
706 SPEC_SCLS($$) = S_SBIT;
709 ignoreTypedefType = 1;
716 $$ = newLink(SPECIFIER) ;
717 FUNC_REGBANK($$) = 0;
718 SPEC_NOUN($$) = V_CHAR;
719 SPEC_SCLS($$) = S_SFR ;
721 ignoreTypedefType = 1;
724 $$ = newLink(SPECIFIER) ;
725 FUNC_REGBANK($$) = 1;
726 SPEC_NOUN($$) = V_CHAR;
727 SPEC_SCLS($$) = S_SFR ;
729 ignoreTypedefType = 1;
733 struct_or_union_specifier
734 : struct_or_union opt_stag
743 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
747 '{' struct_declaration_list '}'
752 // check for errors in structure members
753 for (sym=$5; sym; sym=sym->next) {
754 if (IS_ABSOLUTE(sym->etype)) {
755 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'");
756 SPEC_ABSA(sym->etype) = 0;
758 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
759 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class");
760 printTypeChainRaw (sym->type,NULL);
761 SPEC_SCLS(sym->etype) = 0;
763 for (dsym=sym->next; dsym; dsym=dsym->next) {
764 if (*dsym->name && strcmp(sym->name, dsym->name)==0) {
765 werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER,
766 $1==STRUCT ? "struct" : "union", sym->name);
767 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
772 /* Create a structdef */
774 sdef->fields = reverseSyms($5) ; /* link the fields */
775 sdef->size = compStructSize($1,sdef); /* update size of */
776 promoteAnonStructs ($1, sdef);
778 /* Create the specifier */
779 $$ = newLink (SPECIFIER) ;
780 SPEC_NOUN($$) = V_STRUCT;
781 SPEC_STRUCT($$)= sdef ;
783 | struct_or_union stag
785 $$ = newLink(SPECIFIER) ;
786 SPEC_NOUN($$) = V_STRUCT;
787 SPEC_STRUCT($$) = $2;
796 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
802 : STRUCT { $$ = STRUCT ; }
803 | UNION { $$ = UNION ; }
808 | { /* synthesize a name add to structtable */
809 $$ = newStruct(genSymName(NestLevel)) ;
810 $$->level = NestLevel ;
811 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
815 : identifier { /* add name to structure table */
816 $$ = findSymWithBlock (StructTab,$1,currBlockno);
818 $$ = newStruct($1->name) ;
819 $$->level = NestLevel ;
820 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
825 struct_declaration_list
827 | struct_declaration_list struct_declaration
831 /* go to the end of the chain */
832 while (sym->next) sym=sym->next;
840 : type_specifier_list struct_declarator_list ';'
842 /* add this type to all the symbols */
844 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
845 sym_link *btype = copyLinkChain($1);
847 /* make the symbol one level up */
850 pointerTypes(sym->type,btype);
853 sym->etype = getSpec(sym->type);
856 addDecl (sym,0,btype);
857 /* make sure the type is complete and sane */
858 checkTypeSanity(sym->etype, sym->name);
860 ignoreTypedefType = 0;
865 struct_declarator_list
867 | struct_declarator_list ',' struct_declarator
876 | ':' constant_expr {
878 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
879 bitsize= (int) floatFromVal(constExprValue($2,TRUE));
880 if (bitsize > (port->s.int_size * 8)) {
881 bitsize = port->s.int_size * 8;
882 werror(E_BITFLD_SIZE, bitsize);
885 bitsize = BITVAR_PAD;
886 $$->bitVar = bitsize;
888 | declarator ':' constant_expr
891 bitsize= (int) floatFromVal(constExprValue($3,TRUE));
892 if (bitsize > (port->s.int_size * 8)) {
893 bitsize = port->s.int_size * 8;
894 werror(E_BITFLD_SIZE, bitsize);
897 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
898 $$->bitVar = BITVAR_PAD;
899 werror(W_BITFLD_NAMED);
902 $1->bitVar = bitsize;
904 | { $$ = newSymbol ("", NestLevel) ; }
909 : ENUM '{' enumerator_list '}' {
910 $$ = newEnumType ($3); //copyLinkChain(cenum->type);
911 SPEC_SCLS(getSpec($$)) = 0;
914 | ENUM identifier '{' enumerator_list '}' {
918 csym=findSym(enumTab,$2,$2->name);
919 if ((csym && csym->level == $2->level))
921 werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
922 werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
925 enumtype = newEnumType ($4); //copyLinkChain(cenum->type);
926 SPEC_SCLS(getSpec(enumtype)) = 0;
929 /* add this to the enumerator table */
931 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
932 $$ = copyLinkChain(enumtype);
937 /* check the enumerator table */
938 if ((csym = findSym(enumTab,$2,$2->name)))
939 $$ = copyLinkChain(csym->type);
941 $$ = newLink(SPECIFIER) ;
942 SPEC_NOUN($$) = V_INT ;
949 | enumerator_list ',' {
951 | enumerator_list ',' enumerator
955 for (dsym=$1; dsym; dsym=dsym->next)
957 if (strcmp($3->name, dsym->name)==0)
959 werrorfl($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
960 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
970 : identifier opt_assign_expr
972 /* make the symbol one level up */
974 $1->type = copyLinkChain($2->type);
975 $1->etype= getSpec($1->type);
976 SPEC_ENUM($1->etype) = 1;
978 // do this now, so we can use it for the next enums in the list
984 : '=' constant_expr {
987 val = constExprValue($2,TRUE);
988 if (!IS_INT(val->type) && !IS_CHAR(val->type))
990 werror(E_ENUM_NON_INTEGER);
991 SNPRINTF(lbuff, sizeof(lbuff),
992 "%d",(int) floatFromVal(val));
993 val = constVal(lbuff);
999 SNPRINTF(lbuff, sizeof(lbuff),
1000 "%d",(int) floatFromVal(cenum)+1);
1001 $$ = cenum = constVal(lbuff);
1004 SNPRINTF(lbuff, sizeof(lbuff),
1006 $$ = cenum = constVal(lbuff);
1012 : declarator3 { $$ = $1 ; }
1013 | pointer declarator3
1015 addDecl ($2,0,reverseLink($1));
1021 : declarator2_function_attributes { $$ = $1 ; }
1022 | declarator2 { $$ = $1 ; }
1026 : declarator2_function_attributes { $$ = $1; }
1027 | pointer declarator2_function_attributes
1029 addDecl ($2,0,reverseLink($1));
1034 declarator2_function_attributes
1035 : function_declarator2 { $$ = $1 ; }
1036 | function_declarator2 function_attribute {
1037 // copy the functionAttributes (not the args and hasVargs !!)
1040 sym_link *funcType=$1->type;
1042 while (funcType && !IS_FUNC(funcType))
1043 funcType = funcType->next;
1046 werror (E_FUNC_ATTR);
1049 args=FUNC_ARGS(funcType);
1050 hasVargs=FUNC_HASVARARGS(funcType);
1052 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
1053 sizeof($2->funcAttrs));
1055 FUNC_ARGS(funcType)=args;
1056 FUNC_HASVARARGS(funcType)=hasVargs;
1059 memset (&$2->funcAttrs, 0,
1060 sizeof($2->funcAttrs));
1069 | '(' declarator ')' { $$ = $2; }
1070 | declarator3 '[' ']'
1074 p = newLink (DECLARATOR);
1075 DCL_TYPE(p) = ARRAY ;
1079 | declarator3 '[' constant_expr ']'
1084 tval = constExprValue($3,TRUE);
1085 /* if it is not a constant then Error */
1086 p = newLink (DECLARATOR);
1087 DCL_TYPE(p) = ARRAY ;
1088 if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1089 werror(E_CONST_EXPECTED) ;
1090 /* Assume a single item array to limit the cascade */
1091 /* of additional errors. */
1095 DCL_ELEM(p) = (int) floatFromVal(tval) ;
1101 function_declarator2
1102 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
1103 | declarator2 '(' { NestLevel++ ; currBlockno++; }
1104 parameter_type_list ')'
1108 addDecl ($1,FUNCTION,NULL) ;
1110 funcType = $1->type;
1111 while (funcType && !IS_FUNC(funcType))
1112 funcType = funcType->next;
1116 FUNC_HASVARARGS(funcType) = IS_VARG($4);
1117 FUNC_ARGS(funcType) = reverseVal($4);
1119 /* nest level was incremented to take care of the parms */
1123 // if this was a pointer (to a function)
1124 if (!IS_FUNC($1->type))
1125 cleanUpLevel(SymbolTab,NestLevel+1);
1129 | declarator2 '(' parameter_identifier_list ')'
1131 werror(E_OLD_STYLE,$1->name) ;
1132 /* assume it returns an int */
1133 $1->type = $1->etype = newIntLink();
1139 : unqualified_pointer { $$ = $1 ;}
1140 | unqualified_pointer type_specifier_list
1145 DCL_PTR_CONST($1) = SPEC_CONST($2);
1146 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1149 werror (W_PTR_TYPE_INVALID);
1151 | unqualified_pointer pointer
1155 DCL_TYPE($2)=port->unqualified_pointer;
1157 | unqualified_pointer type_specifier_list pointer
1160 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1161 DCL_PTR_CONST($1) = SPEC_CONST($2);
1162 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1163 switch (SPEC_SCLS($2)) {
1165 DCL_TYPE($3) = FPOINTER;
1168 DCL_TYPE($3) = IPOINTER ;
1171 DCL_TYPE($3) = PPOINTER ;
1174 DCL_TYPE($3) = POINTER ;
1177 DCL_TYPE($3) = CPOINTER ;
1180 DCL_TYPE($3) = EEPPOINTER;
1183 // this could be just "constant"
1184 // werror(W_PTR_TYPE_INVALID);
1189 werror (W_PTR_TYPE_INVALID);
1197 $$ = newLink(DECLARATOR);
1198 DCL_TYPE($$)=UPOINTER;
1204 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1205 | type_specifier_list type_specifier {
1206 /* if the decl $2 is not a specifier */
1207 /* find the spec and replace it */
1208 if ( !IS_SPEC($2)) {
1209 sym_link *lnk = $2 ;
1210 while (lnk && !IS_SPEC(lnk->next))
1212 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1216 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1220 parameter_identifier_list
1222 | identifier_list ',' ELIPSIS
1227 | identifier_list ',' identifier
1236 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1240 : parameter_declaration
1241 | parameter_list ',' parameter_declaration
1248 parameter_declaration
1249 : type_specifier_list declarator
1252 pointerTypes($2->type,$1);
1254 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1257 ignoreTypedefType = 0;
1262 $$->etype = getSpec($$->type);
1263 ignoreTypedefType = 0;
1268 : type_specifier_list { $$ = $1; ignoreTypedefType = 0;}
1269 | type_specifier_list abstract_declarator
1271 /* go to the end of the list */
1273 pointerTypes($2,$1);
1274 for ( p = $2 ; p && p->next ; p=p->next);
1276 werror(E_SYNTAX_ERROR, yytext);
1281 ignoreTypedefType = 0;
1286 : pointer { $$ = reverseLink($1); }
1287 | abstract_declarator2
1288 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1289 if (IS_PTR($1) && IS_FUNC($2))
1290 DCL_TYPE($1) = CPOINTER;
1294 abstract_declarator2
1295 : '(' abstract_declarator ')' { $$ = $2 ; }
1297 $$ = newLink (DECLARATOR);
1298 DCL_TYPE($$) = ARRAY ;
1301 | '[' constant_expr ']' {
1303 $$ = newLink (DECLARATOR);
1304 DCL_TYPE($$) = ARRAY ;
1305 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1307 | abstract_declarator2 '[' ']' {
1308 $$ = newLink (DECLARATOR);
1309 DCL_TYPE($$) = ARRAY ;
1313 | abstract_declarator2 '[' constant_expr ']'
1316 $$ = newLink (DECLARATOR);
1317 DCL_TYPE($$) = ARRAY ;
1318 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1321 | '(' ')' { $$ = NULL;}
1322 | '(' parameter_type_list ')' { $$ = NULL;}
1323 | abstract_declarator2 '(' ')' {
1324 // $1 must be a pointer to a function
1325 sym_link *p=newLink(DECLARATOR);
1326 DCL_TYPE(p) = FUNCTION;
1328 // ((void (code *) ()) 0) ()
1329 $1=newLink(DECLARATOR);
1330 DCL_TYPE($1)=CPOINTER;
1335 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1336 sym_link *p=newLink(DECLARATOR);
1337 DCL_TYPE(p) = FUNCTION;
1339 FUNC_HASVARARGS(p) = IS_VARG($4);
1340 FUNC_ARGS(p) = reverseVal($4);
1342 /* nest level was incremented to take care of the parms */
1348 // remove the symbol args (if any)
1349 cleanUpLevel(SymbolTab,NestLevel+1);
1354 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1355 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1356 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1361 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1366 | compound_statement
1367 | expression_statement
1368 | selection_statement
1369 | iteration_statement
1371 | critical_statement
1375 ex = newNode(INLINEASM,NULL,NULL);
1376 ex->values.inlineasm = strdup($1);
1385 STACK_PUSH(continueStack,NULL);
1386 STACK_PUSH(breakStack,NULL);
1392 : critical statement {
1393 STACK_POP(breakStack);
1394 STACK_POP(continueStack);
1396 $$ = newNode(CRITICAL,$2,NULL);
1401 // : identifier ':' statement { $$ = createLabel($1,$3); }
1402 : identifier ':' { $$ = createLabel($1,NULL);
1404 | CASE constant_expr ':'
1406 if (STACK_EMPTY(swStk))
1407 $$ = createCase(NULL,$2,NULL);
1409 $$ = createCase(STACK_PEEK(swStk),$2,NULL);
1411 | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
1413 if (STACK_EMPTY(swStk))
1414 $$ = createDefault(NULL,$<asts>2,NULL);
1416 $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL);
1422 STACK_PUSH(blockNum,currBlockno);
1423 currBlockno = ++blockNo ;
1424 ignoreTypedefType = 0;
1428 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1432 : start_block end_block { $$ = createBlock(NULL,NULL); }
1433 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1435 declaration_list { addSymChain($2); }
1436 end_block { $$ = createBlock($2,NULL) ; }
1438 declaration_list { addSymChain ($2); }
1440 end_block {$$ = createBlock($2,$4) ; }
1441 | error ';' { $$ = NULL ; }
1447 /* if this is typedef declare it immediately */
1448 if ( $1 && IS_TYPEDEF($1->etype)) {
1449 allocVariables ($1);
1454 ignoreTypedefType = 0;
1457 | declaration_list declaration
1461 /* if this is a typedef */
1462 if ($2 && IS_TYPEDEF($2->etype)) {
1463 allocVariables ($2);
1467 /* get to the end of the previous decl */
1477 ignoreTypedefType = 0;
1483 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1486 expression_statement
1488 | expr ';' { $$ = $1; seqPointNo++;}
1492 : ELSE statement { $$ = $2 ; }
1498 : IF '(' expr ')' { seqPointNo++;} statement else_statement
1501 $$ = createIf ($3, $6, $7 );
1504 | SWITCH '(' expr ')' {
1506 static int swLabel = 0 ;
1509 /* create a node for expression */
1510 ex = newNode(SWITCH,$3,NULL);
1511 STACK_PUSH(swStk,ex); /* save it in the stack */
1512 ex->values.switchVals.swNum = swLabel ;
1514 /* now create the label */
1515 SNPRINTF(lbuff, sizeof(lbuff),
1516 "_swBrk_%d",swLabel++);
1517 $<sym>$ = newSymbol(lbuff,NestLevel);
1518 /* put label in the break stack */
1519 STACK_PUSH(breakStack,$<sym>$);
1522 /* get back the switch form the stack */
1523 $$ = STACK_POP(swStk) ;
1524 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1525 STACK_POP(breakStack);
1529 while : WHILE { /* create and push the continue , break & body labels */
1530 static int Lblnum = 0 ;
1532 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1533 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1535 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1536 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1538 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1539 $$ = newSymbol(lbuff,NestLevel);
1543 do : DO { /* create and push the continue , break & body Labels */
1544 static int Lblnum = 0 ;
1547 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1548 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1550 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1551 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1553 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1554 $$ = newSymbol (lbuff,NestLevel);
1558 for : FOR { /* create & push continue, break & body labels */
1559 static int Lblnum = 0 ;
1562 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1563 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1565 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1566 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1568 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1569 $$ = newSymbol(lbuff,NestLevel);
1571 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1572 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1577 : while '(' expr ')' { seqPointNo++;} statement
1580 $$ = createWhile ( $1, STACK_POP(continueStack),
1581 STACK_POP(breakStack), $3, $6 );
1582 $$->lineno = $1->lineDef ;
1585 | do statement WHILE '(' expr ')' ';'
1589 $$ = createDo ( $1 , STACK_POP(continueStack),
1590 STACK_POP(breakStack), $5, $2);
1591 $$->lineno = $1->lineDef ;
1594 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1598 /* if break or continue statement present
1599 then create a general case loop */
1600 if (STACK_PEEK(continueStack)->isref ||
1601 STACK_PEEK(breakStack)->isref) {
1602 $$ = createFor ($1, STACK_POP(continueStack),
1603 STACK_POP(breakStack) ,
1604 STACK_POP(forStack) ,
1607 $$ = newNode(FOR,$9,NULL);
1608 AST_FOR($$,trueLabel) = $1;
1609 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1610 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1611 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1612 AST_FOR($$,initExpr) = $3;
1613 AST_FOR($$,condExpr) = $5;
1614 AST_FOR($$,loopExpr) = $7;
1622 : { $$ = NULL ; seqPointNo++; }
1623 | expr { $$ = $1 ; seqPointNo++; }
1627 : GOTO identifier ';' {
1629 $$ = newAst_VALUE(symbolVal($2));
1630 $$ = newNode(GOTO,$$,NULL);
1633 /* make sure continue is in context */
1634 if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1635 werror(E_BREAK_CONTEXT);
1639 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1640 $$ = newNode(GOTO,$$,NULL);
1641 /* mark the continue label as referenced */
1642 STACK_PEEK(continueStack)->isref = 1;
1646 if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1647 werror(E_BREAK_CONTEXT);
1650 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1651 $$ = newNode(GOTO,$$,NULL);
1652 STACK_PEEK(breakStack)->isref = 1;
1658 werror(E_INVALID_CRITICAL);
1661 $$ = newNode(RETURN,NULL,NULL);
1667 werror(E_INVALID_CRITICAL);
1670 $$ = newNode(RETURN,NULL,$2);
1676 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }