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
137 { if (!options.lessPedantic)
138 werror(W_EMPTY_SOURCE_FILE);
144 : external_definition
145 | program external_definition
149 : function_definition {
153 ignoreTypedefType = 0;
155 && IS_FUNC($1->type))
157 /* The only legal storage classes for
158 * a function prototype (declaration)
159 * are extern and static. extern is the
160 * default. Thus, if this function isn't
161 * explicitly marked static, mark it
165 && IS_SPEC($1->etype)
166 && !SPEC_STAT($1->etype))
168 SPEC_EXTR($1->etype) = 1;
172 allocVariables ($1) ;
173 cleanUpLevel (SymbolTab,1);
178 : function_declarator function_body { /* function type not specified */
179 /* assume it to be 'int' */
180 addDecl($1,0,newIntLink());
181 $$ = createFunction($1,$2);
183 | declaration_specifiers function_declarator function_body
185 pointerTypes($2->type,copyLinkChain($1));
187 $$ = createFunction($2,$3);
192 : function_attributes
193 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
197 : USING constant_expr {
198 $$ = newLink(SPECIFIER) ;
199 FUNC_REGBANK($$) = (int) floatFromVal(constExprValue($2,TRUE));
201 | REENTRANT { $$ = newLink (SPECIFIER);
204 | CRITICAL { $$ = newLink (SPECIFIER);
205 FUNC_ISCRITICAL($$) = 1;
207 | NAKED { $$ = newLink (SPECIFIER);
210 | JAVANATIVE { $$ = newLink (SPECIFIER);
211 FUNC_ISJAVANATIVE($$)=1;
213 | OVERLAY { $$ = newLink (SPECIFIER);
214 FUNC_ISOVERLAY($$)=1;
216 | NONBANKED {$$ = newLink (SPECIFIER);
217 FUNC_NONBANKED($$) = 1;
218 if (FUNC_BANKED($$)) {
219 werror(W_BANKED_WITH_NONBANKED);
222 | SHADOWREGS {$$ = newLink (SPECIFIER);
223 FUNC_ISSHADOWREGS($$) = 1;
225 | WPARAM {$$ = newLink (SPECIFIER);
226 FUNC_ISWPARAM($$) = 1;
228 | BANKED {$$ = newLink (SPECIFIER);
230 if (FUNC_NONBANKED($$)) {
231 werror(W_BANKED_WITH_NONBANKED);
234 werror(W_BANKED_WITH_STATIC);
239 $$ = newLink (SPECIFIER) ;
240 FUNC_INTNO($$) = $1 ;
247 | declaration_list compound_statement
249 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
255 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
256 | CONSTANT { $$ = newAst_VALUE($1); }
258 | '(' expr ')' { $$ = $2 ; }
262 : STRING_LITERAL { $$ = newAst_VALUE($1); }
267 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
268 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
269 $$->left->funcName = 1;}
270 | postfix_expr '(' argument_expr_list ')'
272 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
274 | postfix_expr '.' { ignoreTypedefType = 1; } identifier
276 ignoreTypedefType = 0;
277 $4 = newSymbol($4->name,NestLevel);
279 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($4)));
280 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($4))) ; */
282 | postfix_expr PTR_OP { ignoreTypedefType = 1; } identifier
284 ignoreTypedefType = 0;
285 $4 = newSymbol($4->name,NestLevel);
287 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($4)));
289 | postfix_expr INC_OP
290 { $$ = newNode(INC_OP,$1,NULL);}
291 | postfix_expr DEC_OP
292 { $$ = newNode(DEC_OP,$1,NULL); }
297 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
302 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
303 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
304 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
305 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
306 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
307 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
321 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
326 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
327 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
328 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
332 : multiplicative_expr
333 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
334 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
339 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
340 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
345 | relational_expr '<' shift_expr { $$ = newNode('<', $1,$3);}
346 | relational_expr '>' shift_expr { $$ = newNode('>', $1,$3);}
347 | relational_expr LE_OP shift_expr { $$ = newNode(LE_OP,$1,$3);}
348 | relational_expr GE_OP shift_expr { $$ = newNode(GE_OP,$1,$3);}
353 | equality_expr EQ_OP relational_expr { $$ = newNode(EQ_OP,$1,$3);}
354 | equality_expr NE_OP relational_expr { $$ = newNode(NE_OP,$1,$3);}
359 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
364 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
369 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
374 | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expr
375 { $$ = newNode(AND_OP,$1,$4);}
380 | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr
381 { $$ = newNode(OR_OP,$1,$4); }
386 | logical_or_expr '?' { seqPointNo++;} logical_or_expr ':' conditional_expr
388 $$ = newNode(':',$4,$6) ;
389 $$ = newNode('?',$1,$$) ;
395 | cast_expr assignment_operator assignment_expr
400 $$ = newNode($2,$1,$3);
403 $$ = createRMW($1, '*', $3);
406 $$ = createRMW($1, '/', $3);
409 $$ = createRMW($1, '%', $3);
412 $$ = createRMW($1, '+', $3);
415 $$ = createRMW($1, '-', $3);
418 $$ = createRMW($1, LEFT_OP, $3);
421 $$ = createRMW($1, RIGHT_OP, $3);
424 $$ = createRMW($1, '&', $3);
427 $$ = createRMW($1, '^', $3);
430 /* $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); */
431 /* $$ = newNode('=',removePostIncDecOps(copyAst($1)),
432 newNode('|',removePreIncDecOps(copyAst($1)),$3)); */
433 $$ = createRMW($1, '|', $3);
458 | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);}
466 : declaration_specifiers ';'
469 werror(W_USELESS_DECL);
473 | declaration_specifiers init_declarator_list ';'
475 /* add the specifier list to the id */
478 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
479 sym_link *lnk = copyLinkChain($1);
480 /* do the pointer stuff */
481 pointerTypes(sym->type,lnk);
482 addDecl (sym,0,lnk) ;
490 declaration_specifiers
491 : storage_class_specifier { $$ = $1; }
492 | storage_class_specifier declaration_specifiers {
493 /* if the decl $2 is not a specifier */
494 /* find the spec and replace it */
497 while (lnk && !IS_SPEC(lnk->next))
499 lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
503 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
505 | type_specifier { $$ = $1; }
506 | type_specifier declaration_specifiers {
507 /* if the decl $2 is not a specifier */
508 /* find the spec and replace it */
511 while (lnk && !IS_SPEC(lnk->next))
513 lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
517 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
523 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
527 : declarator { $1->ival = NULL ; }
528 | declarator '=' initializer { $1->ival = $3 ; }
532 storage_class_specifier
534 $$ = newLink (SPECIFIER) ;
535 SPEC_TYPEDEF($$) = 1 ;
538 $$ = newLink(SPECIFIER);
542 $$ = newLink (SPECIFIER);
546 $$ = newLink (SPECIFIER) ;
547 SPEC_SCLS($$) = S_AUTO ;
550 $$ = newLink (SPECIFIER);
551 SPEC_SCLS($$) = S_REGISTER ;
556 : INTERRUPT { $$ = INTNO_UNSPEC ; }
557 | INTERRUPT constant_expr
558 { int intno = (int) floatFromVal(constExprValue($2,TRUE));
559 if ((intno >= 0) && (intno <= INTNO_MAX))
563 werror(E_INT_BAD_INTNO, intno);
571 | type_specifier2 AT constant_expr
573 /* add this to the storage class specifier */
574 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
575 /* now get the abs addr from value */
576 SPEC_ADDR($1) = (unsigned) floatFromVal(constExprValue($3,TRUE)) ;
582 $$=newLink(SPECIFIER);
583 SPEC_NOUN($$) = V_CHAR ;
584 ignoreTypedefType = 1;
587 $$=newLink(SPECIFIER);
589 ignoreTypedefType = 1;
592 $$=newLink(SPECIFIER);
593 SPEC_NOUN($$) = V_INT ;
594 ignoreTypedefType = 1;
597 $$=newLink(SPECIFIER);
599 ignoreTypedefType = 1;
602 $$=newLink(SPECIFIER);
603 $$->select.s.b_signed = 1;
604 ignoreTypedefType = 1;
607 $$=newLink(SPECIFIER);
609 ignoreTypedefType = 1;
612 $$=newLink(SPECIFIER);
613 SPEC_NOUN($$) = V_VOID ;
614 ignoreTypedefType = 1;
617 $$=newLink(SPECIFIER);
621 $$=newLink(SPECIFIER);
622 SPEC_VOLATILE($$) = 1 ;
625 $$=newLink(SPECIFIER);
626 SPEC_NOUN($$) = V_FLOAT;
627 ignoreTypedefType = 1;
630 $$=newLink(SPECIFIER);
631 SPEC_NOUN($$) = V_FIXED16X16;
632 ignoreTypedefType = 1;
635 $$ = newLink (SPECIFIER);
636 SPEC_SCLS($$) = S_XDATA ;
639 $$ = newLink (SPECIFIER) ;
640 SPEC_SCLS($$) = S_CODE ;
643 $$ = newLink (SPECIFIER) ;
644 SPEC_SCLS($$) = S_EEPROM ;
647 $$ = newLink (SPECIFIER);
648 SPEC_SCLS($$) = S_DATA ;
651 $$ = newLink (SPECIFIER);
652 SPEC_SCLS($$) = S_IDATA ;
655 $$ = newLink (SPECIFIER);
656 SPEC_SCLS($$) = S_PDATA ;
659 $$=newLink(SPECIFIER);
660 SPEC_NOUN($$) = V_BIT ;
661 SPEC_SCLS($$) = S_BIT ;
664 ignoreTypedefType = 1;
667 | struct_or_union_specifier {
670 ignoreTypedefType = 1;
675 ignoreTypedefType = 1;
682 sym = findSym(TypedefTab,NULL,$1) ;
683 $$ = p = copyLinkChain(sym->type);
684 SPEC_TYPEDEF(getSpec(p)) = 0;
685 ignoreTypedefType = 1;
692 $$ = newLink(SPECIFIER) ;
693 SPEC_NOUN($$) = V_SBIT;
694 SPEC_SCLS($$) = S_SBIT;
697 ignoreTypedefType = 1;
704 $$ = newLink(SPECIFIER) ;
705 FUNC_REGBANK($$) = 0;
706 SPEC_NOUN($$) = V_CHAR;
707 SPEC_SCLS($$) = S_SFR ;
709 ignoreTypedefType = 1;
712 $$ = newLink(SPECIFIER) ;
713 FUNC_REGBANK($$) = 1;
714 SPEC_NOUN($$) = V_CHAR;
715 SPEC_SCLS($$) = S_SFR ;
717 ignoreTypedefType = 1;
723 $$ = newLink(SPECIFIER) ;
724 FUNC_REGBANK($$) = 0;
725 SPEC_NOUN($$) = V_INT;
726 SPEC_SCLS($$) = S_SFR;
728 ignoreTypedefType = 1;
734 $$ = newLink(SPECIFIER) ;
735 FUNC_REGBANK($$) = 0;
736 SPEC_NOUN($$) = V_INT;
737 SPEC_SCLS($$) = S_SFR;
740 ignoreTypedefType = 1;
744 struct_or_union_specifier
745 : struct_or_union opt_stag
754 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
758 '{' struct_declaration_list '}'
763 // check for errors in structure members
764 for (sym=$5; sym; sym=sym->next) {
765 if (IS_ABSOLUTE(sym->etype)) {
766 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'");
767 SPEC_ABSA(sym->etype) = 0;
769 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
770 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class");
771 printTypeChainRaw (sym->type,NULL);
772 SPEC_SCLS(sym->etype) = 0;
774 for (dsym=sym->next; dsym; dsym=dsym->next) {
775 if (*dsym->name && strcmp(sym->name, dsym->name)==0) {
776 werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER,
777 $1==STRUCT ? "struct" : "union", sym->name);
778 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
783 /* Create a structdef */
785 sdef->fields = reverseSyms($5) ; /* link the fields */
786 sdef->size = compStructSize($1,sdef); /* update size of */
787 promoteAnonStructs ($1, sdef);
789 /* Create the specifier */
790 $$ = newLink (SPECIFIER) ;
791 SPEC_NOUN($$) = V_STRUCT;
792 SPEC_STRUCT($$)= sdef ;
794 | struct_or_union stag
796 $$ = newLink(SPECIFIER) ;
797 SPEC_NOUN($$) = V_STRUCT;
798 SPEC_STRUCT($$) = $2;
807 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
813 : STRUCT { $$ = STRUCT ; }
814 | UNION { $$ = UNION ; }
819 | { /* synthesize a name add to structtable */
820 $$ = newStruct(genSymName(NestLevel)) ;
821 $$->level = NestLevel ;
822 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
826 : identifier { /* add name to structure table */
827 $$ = findSymWithBlock (StructTab,$1,currBlockno);
829 $$ = newStruct($1->name) ;
830 $$->level = NestLevel ;
831 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
836 struct_declaration_list
838 | struct_declaration_list struct_declaration
842 /* go to the end of the chain */
843 while (sym->next) sym=sym->next;
851 : type_specifier_list struct_declarator_list ';'
853 /* add this type to all the symbols */
855 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
856 sym_link *btype = copyLinkChain($1);
858 /* make the symbol one level up */
861 pointerTypes(sym->type,btype);
864 sym->etype = getSpec(sym->type);
867 addDecl (sym,0,btype);
868 /* make sure the type is complete and sane */
869 checkTypeSanity(sym->etype, sym->name);
871 ignoreTypedefType = 0;
876 struct_declarator_list
878 | struct_declarator_list ',' struct_declarator
887 | ':' constant_expr {
888 unsigned int bitsize;
889 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
890 bitsize= (unsigned int) floatFromVal(constExprValue($2,TRUE));
891 if (bitsize > (port->s.int_size * 8)) {
892 bitsize = port->s.int_size * 8;
893 werror(E_BITFLD_SIZE, bitsize);
896 bitsize = BITVAR_PAD;
897 $$->bitVar = bitsize;
899 | declarator ':' constant_expr
901 unsigned int bitsize;
902 bitsize= (unsigned int) floatFromVal(constExprValue($3,TRUE));
903 if (bitsize > (port->s.int_size * 8)) {
904 bitsize = port->s.int_size * 8;
905 werror(E_BITFLD_SIZE, bitsize);
908 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
909 $$->bitVar = BITVAR_PAD;
910 werror(W_BITFLD_NAMED);
913 $1->bitVar = bitsize;
915 | { $$ = newSymbol ("", NestLevel) ; }
920 : ENUM '{' enumerator_list '}' {
921 $$ = newEnumType ($3); //copyLinkChain(cenum->type);
922 SPEC_SCLS(getSpec($$)) = 0;
925 | ENUM identifier '{' enumerator_list '}' {
929 csym=findSym(enumTab,$2,$2->name);
930 if ((csym && csym->level == $2->level))
932 werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
933 werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
936 enumtype = newEnumType ($4); //copyLinkChain(cenum->type);
937 SPEC_SCLS(getSpec(enumtype)) = 0;
940 /* add this to the enumerator table */
942 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
943 $$ = copyLinkChain(enumtype);
948 /* check the enumerator table */
949 if ((csym = findSym(enumTab,$2,$2->name)))
950 $$ = copyLinkChain(csym->type);
952 $$ = newLink(SPECIFIER) ;
953 SPEC_NOUN($$) = V_INT ;
960 | enumerator_list ',' {
962 | enumerator_list ',' enumerator
966 for (dsym=$1; dsym; dsym=dsym->next)
968 if (strcmp($3->name, dsym->name)==0)
970 werrorfl($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
971 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
981 : identifier opt_assign_expr
983 /* make the symbol one level up */
985 $1->type = copyLinkChain($2->type);
986 $1->etype= getSpec($1->type);
987 SPEC_ENUM($1->etype) = 1;
989 // do this now, so we can use it for the next enums in the list
995 : '=' constant_expr {
998 val = constExprValue($2,TRUE);
999 if (!IS_INT(val->type) && !IS_CHAR(val->type))
1001 werror(E_ENUM_NON_INTEGER);
1002 SNPRINTF(lbuff, sizeof(lbuff),
1003 "%d",(int) floatFromVal(val));
1004 val = constVal(lbuff);
1010 SNPRINTF(lbuff, sizeof(lbuff),
1011 "%d",(int) floatFromVal(cenum)+1);
1012 $$ = cenum = constVal(lbuff);
1015 SNPRINTF(lbuff, sizeof(lbuff),
1017 $$ = cenum = constVal(lbuff);
1023 : declarator3 { $$ = $1 ; }
1024 | pointer declarator3
1026 addDecl ($2,0,reverseLink($1));
1032 : declarator2_function_attributes { $$ = $1 ; }
1033 | declarator2 { $$ = $1 ; }
1037 : declarator2_function_attributes { $$ = $1; }
1038 | pointer declarator2_function_attributes
1040 addDecl ($2,0,reverseLink($1));
1045 declarator2_function_attributes
1046 : function_declarator2 { $$ = $1 ; }
1047 | function_declarator2 function_attribute {
1048 // copy the functionAttributes (not the args and hasVargs !!)
1051 sym_link *funcType=$1->type;
1053 while (funcType && !IS_FUNC(funcType))
1054 funcType = funcType->next;
1057 werror (E_FUNC_ATTR);
1060 args=FUNC_ARGS(funcType);
1061 hasVargs=FUNC_HASVARARGS(funcType);
1063 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
1064 sizeof($2->funcAttrs));
1066 FUNC_ARGS(funcType)=args;
1067 FUNC_HASVARARGS(funcType)=hasVargs;
1070 memset (&$2->funcAttrs, 0,
1071 sizeof($2->funcAttrs));
1080 | '(' declarator ')' { $$ = $2; }
1081 | declarator3 '[' ']'
1085 p = newLink (DECLARATOR);
1086 DCL_TYPE(p) = ARRAY ;
1090 | declarator3 '[' constant_expr ']'
1095 tval = constExprValue($3,TRUE);
1096 /* if it is not a constant then Error */
1097 p = newLink (DECLARATOR);
1098 DCL_TYPE(p) = ARRAY ;
1099 if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1100 werror(E_CONST_EXPECTED) ;
1101 /* Assume a single item array to limit the cascade */
1102 /* of additional errors. */
1106 DCL_ELEM(p) = (int) floatFromVal(tval) ;
1112 function_declarator2
1113 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
1114 | declarator2 '(' { NestLevel++ ; currBlockno++; }
1115 parameter_type_list ')'
1119 addDecl ($1,FUNCTION,NULL) ;
1121 funcType = $1->type;
1122 while (funcType && !IS_FUNC(funcType))
1123 funcType = funcType->next;
1127 FUNC_HASVARARGS(funcType) = IS_VARG($4);
1128 FUNC_ARGS(funcType) = reverseVal($4);
1130 /* nest level was incremented to take care of the parms */
1134 // if this was a pointer (to a function)
1135 if (!IS_FUNC($1->type))
1136 cleanUpLevel(SymbolTab,NestLevel+1);
1140 | declarator2 '(' parameter_identifier_list ')'
1142 werror(E_OLD_STYLE,$1->name) ;
1143 /* assume it returns an int */
1144 $1->type = $1->etype = newIntLink();
1150 : unqualified_pointer { $$ = $1 ;}
1151 | unqualified_pointer type_specifier_list
1156 DCL_PTR_CONST($1) = SPEC_CONST($2);
1157 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1160 werror (W_PTR_TYPE_INVALID);
1162 | unqualified_pointer pointer
1166 DCL_TYPE($2)=port->unqualified_pointer;
1168 | unqualified_pointer type_specifier_list pointer
1171 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1172 DCL_PTR_CONST($1) = SPEC_CONST($2);
1173 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1174 switch (SPEC_SCLS($2)) {
1176 DCL_TYPE($3) = FPOINTER;
1179 DCL_TYPE($3) = IPOINTER ;
1182 DCL_TYPE($3) = PPOINTER ;
1185 DCL_TYPE($3) = POINTER ;
1188 DCL_TYPE($3) = CPOINTER ;
1191 DCL_TYPE($3) = EEPPOINTER;
1194 // this could be just "constant"
1195 // werror(W_PTR_TYPE_INVALID);
1200 werror (W_PTR_TYPE_INVALID);
1208 $$ = newLink(DECLARATOR);
1209 DCL_TYPE($$)=UPOINTER;
1215 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1216 | type_specifier_list type_specifier {
1217 /* if the decl $2 is not a specifier */
1218 /* find the spec and replace it */
1219 if ( !IS_SPEC($2)) {
1220 sym_link *lnk = $2 ;
1221 while (lnk && !IS_SPEC(lnk->next))
1223 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1227 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1231 parameter_identifier_list
1233 | identifier_list ',' ELIPSIS
1238 | identifier_list ',' identifier
1247 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1251 : parameter_declaration
1252 | parameter_list ',' parameter_declaration
1259 parameter_declaration
1260 : type_specifier_list declarator
1263 pointerTypes($2->type,$1);
1265 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1268 ignoreTypedefType = 0;
1273 $$->etype = getSpec($$->type);
1274 ignoreTypedefType = 0;
1279 : type_specifier_list { $$ = $1; ignoreTypedefType = 0;}
1280 | type_specifier_list abstract_declarator
1282 /* go to the end of the list */
1284 pointerTypes($2,$1);
1285 for ( p = $2 ; p && p->next ; p=p->next);
1287 werror(E_SYNTAX_ERROR, yytext);
1292 ignoreTypedefType = 0;
1297 : pointer { $$ = reverseLink($1); }
1298 | abstract_declarator2
1299 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1300 if (IS_PTR($1) && IS_FUNC($2))
1301 DCL_TYPE($1) = CPOINTER;
1305 abstract_declarator2
1306 : '(' abstract_declarator ')' { $$ = $2 ; }
1308 $$ = newLink (DECLARATOR);
1309 DCL_TYPE($$) = ARRAY ;
1312 | '[' constant_expr ']' {
1314 $$ = newLink (DECLARATOR);
1315 DCL_TYPE($$) = ARRAY ;
1316 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1318 | abstract_declarator2 '[' ']' {
1319 $$ = newLink (DECLARATOR);
1320 DCL_TYPE($$) = ARRAY ;
1324 | abstract_declarator2 '[' constant_expr ']'
1327 $$ = newLink (DECLARATOR);
1328 DCL_TYPE($$) = ARRAY ;
1329 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1332 | '(' ')' { $$ = NULL;}
1333 | '(' parameter_type_list ')' { $$ = NULL;}
1334 | abstract_declarator2 '(' ')' {
1335 // $1 must be a pointer to a function
1336 sym_link *p=newLink(DECLARATOR);
1337 DCL_TYPE(p) = FUNCTION;
1339 // ((void (code *) ()) 0) ()
1340 $1=newLink(DECLARATOR);
1341 DCL_TYPE($1)=CPOINTER;
1346 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1347 sym_link *p=newLink(DECLARATOR);
1348 DCL_TYPE(p) = FUNCTION;
1350 FUNC_HASVARARGS(p) = IS_VARG($4);
1351 FUNC_ARGS(p) = reverseVal($4);
1353 /* nest level was incremented to take care of the parms */
1357 /* ((void (code *) (void)) 0) () */
1358 $1=newLink(DECLARATOR);
1359 DCL_TYPE($1)=CPOINTER;
1364 // remove the symbol args (if any)
1365 cleanUpLevel(SymbolTab,NestLevel+1);
1370 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1371 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1372 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1377 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1382 | compound_statement
1383 | expression_statement
1384 | selection_statement
1385 | iteration_statement
1387 | critical_statement
1391 ex = newNode(INLINEASM,NULL,NULL);
1392 ex->values.inlineasm = strdup($1);
1401 STACK_PUSH(continueStack,NULL);
1402 STACK_PUSH(breakStack,NULL);
1408 : critical statement {
1409 STACK_POP(breakStack);
1410 STACK_POP(continueStack);
1412 $$ = newNode(CRITICAL,$2,NULL);
1417 // : identifier ':' statement { $$ = createLabel($1,$3); }
1418 : identifier ':' { $$ = createLabel($1,NULL);
1420 | CASE constant_expr ':'
1422 if (STACK_EMPTY(swStk))
1423 $$ = createCase(NULL,$2,NULL);
1425 $$ = createCase(STACK_PEEK(swStk),$2,NULL);
1427 | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
1429 if (STACK_EMPTY(swStk))
1430 $$ = createDefault(NULL,$<asts>2,NULL);
1432 $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL);
1438 STACK_PUSH(blockNum,currBlockno);
1439 currBlockno = ++blockNo ;
1440 ignoreTypedefType = 0;
1444 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1448 : start_block end_block { $$ = createBlock(NULL,NULL); }
1449 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1451 declaration_list { addSymChain(&$2); }
1452 end_block { $$ = createBlock($2,NULL) ; }
1454 declaration_list { addSymChain (&$2); }
1456 end_block {$$ = createBlock($2,$4) ; }
1457 | error ';' { $$ = NULL ; }
1463 /* if this is typedef declare it immediately */
1464 if ( $1 && IS_TYPEDEF($1->etype)) {
1465 allocVariables ($1);
1470 ignoreTypedefType = 0;
1473 | declaration_list declaration
1477 /* if this is a typedef */
1478 if ($2 && IS_TYPEDEF($2->etype)) {
1479 allocVariables ($2);
1483 /* get to the end of the previous decl */
1493 ignoreTypedefType = 0;
1499 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1502 expression_statement
1504 | expr ';' { $$ = $1; seqPointNo++;}
1508 : ELSE statement { $$ = $2 ; }
1514 : IF '(' expr ')' { seqPointNo++;} statement else_statement
1517 $$ = createIf ($3, $6, $7 );
1520 | SWITCH '(' expr ')' {
1522 static int swLabel = 0 ;
1525 /* create a node for expression */
1526 ex = newNode(SWITCH,$3,NULL);
1527 STACK_PUSH(swStk,ex); /* save it in the stack */
1528 ex->values.switchVals.swNum = swLabel ;
1530 /* now create the label */
1531 SNPRINTF(lbuff, sizeof(lbuff),
1532 "_swBrk_%d",swLabel++);
1533 $<sym>$ = newSymbol(lbuff,NestLevel);
1534 /* put label in the break stack */
1535 STACK_PUSH(breakStack,$<sym>$);
1538 /* get back the switch form the stack */
1539 $$ = STACK_POP(swStk) ;
1540 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1541 STACK_POP(breakStack);
1545 while : WHILE { /* create and push the continue , break & body labels */
1546 static int Lblnum = 0 ;
1548 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1549 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1551 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1552 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1554 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1555 $$ = newSymbol(lbuff,NestLevel);
1559 do : DO { /* create and push the continue , break & body Labels */
1560 static int Lblnum = 0 ;
1563 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1564 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1566 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1567 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1569 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1570 $$ = newSymbol (lbuff,NestLevel);
1574 for : FOR { /* create & push continue, break & body labels */
1575 static int Lblnum = 0 ;
1578 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1579 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1581 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1582 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1584 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1585 $$ = newSymbol(lbuff,NestLevel);
1587 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1588 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1593 : while '(' expr ')' { seqPointNo++;} statement
1596 $$ = createWhile ( $1, STACK_POP(continueStack),
1597 STACK_POP(breakStack), $3, $6 );
1598 $$->lineno = $1->lineDef ;
1601 | do statement WHILE '(' expr ')' ';'
1605 $$ = createDo ( $1 , STACK_POP(continueStack),
1606 STACK_POP(breakStack), $5, $2);
1607 $$->lineno = $1->lineDef ;
1610 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1614 /* if break or continue statement present
1615 then create a general case loop */
1616 if (STACK_PEEK(continueStack)->isref ||
1617 STACK_PEEK(breakStack)->isref) {
1618 $$ = createFor ($1, STACK_POP(continueStack),
1619 STACK_POP(breakStack) ,
1620 STACK_POP(forStack) ,
1623 $$ = newNode(FOR,$9,NULL);
1624 AST_FOR($$,trueLabel) = $1;
1625 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1626 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1627 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1628 AST_FOR($$,initExpr) = $3;
1629 AST_FOR($$,condExpr) = $5;
1630 AST_FOR($$,loopExpr) = $7;
1638 : { $$ = NULL ; seqPointNo++; }
1639 | expr { $$ = $1 ; seqPointNo++; }
1643 : GOTO identifier ';' {
1645 $$ = newAst_VALUE(symbolVal($2));
1646 $$ = newNode(GOTO,$$,NULL);
1649 /* make sure continue is in context */
1650 if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1651 werror(E_BREAK_CONTEXT);
1655 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1656 $$ = newNode(GOTO,$$,NULL);
1657 /* mark the continue label as referenced */
1658 STACK_PEEK(continueStack)->isref = 1;
1662 if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1663 werror(E_BREAK_CONTEXT);
1666 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1667 $$ = newNode(GOTO,$$,NULL);
1668 STACK_PEEK(breakStack)->isref = 1;
1674 werror(E_INVALID_CRITICAL);
1677 $$ = newNode(RETURN,NULL,NULL);
1683 werror(E_INVALID_CRITICAL);
1686 $$ = newNode(RETURN,NULL,$2);
1692 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }