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 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
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));
186 if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
189 $$ = createFunction($2,$3);
194 : function_attributes
195 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
199 : USING constant_expr {
200 $$ = newLink(SPECIFIER) ;
201 FUNC_REGBANK($$) = (int) floatFromVal(constExprValue($2,TRUE));
203 | REENTRANT { $$ = newLink (SPECIFIER);
206 | CRITICAL { $$ = newLink (SPECIFIER);
207 FUNC_ISCRITICAL($$) = 1;
209 | NAKED { $$ = newLink (SPECIFIER);
212 | JAVANATIVE { $$ = newLink (SPECIFIER);
213 FUNC_ISJAVANATIVE($$)=1;
215 | OVERLAY { $$ = newLink (SPECIFIER);
216 FUNC_ISOVERLAY($$)=1;
218 | NONBANKED {$$ = newLink (SPECIFIER);
219 FUNC_NONBANKED($$) = 1;
220 if (FUNC_BANKED($$)) {
221 werror(W_BANKED_WITH_NONBANKED);
224 | SHADOWREGS {$$ = newLink (SPECIFIER);
225 FUNC_ISSHADOWREGS($$) = 1;
227 | WPARAM {$$ = newLink (SPECIFIER);
228 FUNC_ISWPARAM($$) = 1;
230 | BANKED {$$ = newLink (SPECIFIER);
232 if (FUNC_NONBANKED($$)) {
233 werror(W_BANKED_WITH_NONBANKED);
236 werror(W_BANKED_WITH_STATIC);
241 $$ = newLink (SPECIFIER) ;
242 FUNC_INTNO($$) = $1 ;
249 | declaration_list compound_statement
251 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
257 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
258 | CONSTANT { $$ = newAst_VALUE($1); }
260 | '(' expr ')' { $$ = $2 ; }
264 : STRING_LITERAL { $$ = newAst_VALUE($1); }
269 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
270 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
271 $$->left->funcName = 1;}
272 | postfix_expr '(' argument_expr_list ')'
274 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
276 | postfix_expr '.' { ignoreTypedefType = 1; } identifier
278 ignoreTypedefType = 0;
279 $4 = newSymbol($4->name,NestLevel);
281 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($4)));
282 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($4))) ; */
284 | postfix_expr PTR_OP { ignoreTypedefType = 1; } identifier
286 ignoreTypedefType = 0;
287 $4 = newSymbol($4->name,NestLevel);
289 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($4)));
291 | postfix_expr INC_OP
292 { $$ = newNode(INC_OP,$1,NULL);}
293 | postfix_expr DEC_OP
294 { $$ = newNode(DEC_OP,$1,NULL); }
299 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
304 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
305 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
306 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
307 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
308 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
309 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
323 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
328 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
329 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
330 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
334 : multiplicative_expr
335 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
336 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
341 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
342 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
347 | relational_expr '<' shift_expr { $$ = newNode('<', $1,$3);}
348 | relational_expr '>' shift_expr { $$ = newNode('>', $1,$3);}
349 | relational_expr LE_OP shift_expr { $$ = newNode(LE_OP,$1,$3);}
350 | relational_expr GE_OP shift_expr { $$ = newNode(GE_OP,$1,$3);}
355 | equality_expr EQ_OP relational_expr { $$ = newNode(EQ_OP,$1,$3);}
356 | equality_expr NE_OP relational_expr { $$ = newNode(NE_OP,$1,$3);}
361 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
366 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
371 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
376 | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expr
377 { $$ = newNode(AND_OP,$1,$4);}
382 | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr
383 { $$ = newNode(OR_OP,$1,$4); }
388 | logical_or_expr '?' { seqPointNo++;} logical_or_expr ':' conditional_expr
390 $$ = newNode(':',$4,$6) ;
391 $$ = newNode('?',$1,$$) ;
397 | cast_expr assignment_operator assignment_expr
402 $$ = newNode($2,$1,$3);
405 $$ = createRMW($1, '*', $3);
408 $$ = createRMW($1, '/', $3);
411 $$ = createRMW($1, '%', $3);
414 $$ = createRMW($1, '+', $3);
417 $$ = createRMW($1, '-', $3);
420 $$ = createRMW($1, LEFT_OP, $3);
423 $$ = createRMW($1, RIGHT_OP, $3);
426 $$ = createRMW($1, '&', $3);
429 $$ = createRMW($1, '^', $3);
432 /* $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); */
433 /* $$ = newNode('=',removePostIncDecOps(copyAst($1)),
434 newNode('|',removePreIncDecOps(copyAst($1)),$3)); */
435 $$ = createRMW($1, '|', $3);
460 | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);}
468 : declaration_specifiers ';'
471 werror(W_USELESS_DECL);
475 | declaration_specifiers init_declarator_list ';'
477 /* add the specifier list to the id */
480 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
481 sym_link *lnk = copyLinkChain($1);
482 if (options.unsigned_char && SPEC_NOUN(lnk) == V_CHAR && !lnk->select.s.b_signed)
484 /* do the pointer stuff */
485 pointerTypes(sym->type,lnk);
486 addDecl (sym,0,lnk) ;
494 declaration_specifiers
495 : storage_class_specifier { $$ = $1; }
496 | storage_class_specifier declaration_specifiers {
497 /* if the decl $2 is not a specifier */
498 /* find the spec and replace it */
501 while (lnk && !IS_SPEC(lnk->next))
503 lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
507 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
509 | type_specifier { $$ = $1; }
510 | type_specifier declaration_specifiers {
511 /* if the decl $2 is not a specifier */
512 /* find the spec and replace it */
515 while (lnk && !IS_SPEC(lnk->next))
517 lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
521 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
527 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
531 : declarator { $1->ival = NULL ; }
532 | declarator '=' initializer { $1->ival = $3 ; }
536 storage_class_specifier
538 $$ = newLink (SPECIFIER) ;
539 SPEC_TYPEDEF($$) = 1 ;
542 $$ = newLink(SPECIFIER);
546 $$ = newLink (SPECIFIER);
550 $$ = newLink (SPECIFIER) ;
551 SPEC_SCLS($$) = S_AUTO ;
554 $$ = newLink (SPECIFIER);
555 SPEC_SCLS($$) = S_REGISTER ;
560 : INTERRUPT { $$ = INTNO_UNSPEC ; }
561 | INTERRUPT constant_expr
562 { int intno = (int) floatFromVal(constExprValue($2,TRUE));
563 if ((intno >= 0) && (intno <= INTNO_MAX))
567 werror(E_INT_BAD_INTNO, intno);
575 | type_specifier2 AT constant_expr
577 /* add this to the storage class specifier */
578 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
579 /* now get the abs addr from value */
580 SPEC_ADDR($1) = (unsigned) floatFromVal(constExprValue($3,TRUE)) ;
586 $$=newLink(SPECIFIER);
587 SPEC_NOUN($$) = V_CHAR ;
588 ignoreTypedefType = 1;
591 $$=newLink(SPECIFIER);
593 ignoreTypedefType = 1;
596 $$=newLink(SPECIFIER);
597 SPEC_NOUN($$) = V_INT ;
598 ignoreTypedefType = 1;
601 $$=newLink(SPECIFIER);
603 ignoreTypedefType = 1;
606 $$=newLink(SPECIFIER);
607 $$->select.s.b_signed = 1;
608 ignoreTypedefType = 1;
611 $$=newLink(SPECIFIER);
613 ignoreTypedefType = 1;
616 $$=newLink(SPECIFIER);
617 SPEC_NOUN($$) = V_VOID ;
618 ignoreTypedefType = 1;
621 $$=newLink(SPECIFIER);
625 $$=newLink(SPECIFIER);
626 SPEC_VOLATILE($$) = 1 ;
629 $$=newLink(SPECIFIER);
630 SPEC_NOUN($$) = V_FLOAT;
631 ignoreTypedefType = 1;
634 $$=newLink(SPECIFIER);
635 SPEC_NOUN($$) = V_FIXED16X16;
636 ignoreTypedefType = 1;
639 $$ = newLink (SPECIFIER);
640 SPEC_SCLS($$) = S_XDATA ;
643 $$ = newLink (SPECIFIER) ;
644 SPEC_SCLS($$) = S_CODE ;
647 $$ = newLink (SPECIFIER) ;
648 SPEC_SCLS($$) = S_EEPROM ;
651 $$ = newLink (SPECIFIER);
652 SPEC_SCLS($$) = S_DATA ;
655 $$ = newLink (SPECIFIER);
656 SPEC_SCLS($$) = S_IDATA ;
659 $$ = newLink (SPECIFIER);
660 SPEC_SCLS($$) = S_PDATA ;
663 $$=newLink(SPECIFIER);
664 SPEC_NOUN($$) = V_BIT ;
665 SPEC_SCLS($$) = S_BIT ;
668 ignoreTypedefType = 1;
671 | struct_or_union_specifier {
674 ignoreTypedefType = 1;
679 ignoreTypedefType = 1;
686 sym = findSym(TypedefTab,NULL,$1) ;
687 $$ = p = copyLinkChain(sym->type);
688 SPEC_TYPEDEF(getSpec(p)) = 0;
689 ignoreTypedefType = 1;
696 $$ = newLink(SPECIFIER) ;
697 SPEC_NOUN($$) = V_SBIT;
698 SPEC_SCLS($$) = S_SBIT;
701 ignoreTypedefType = 1;
708 $$ = newLink(SPECIFIER) ;
709 FUNC_REGBANK($$) = 0;
710 SPEC_NOUN($$) = V_CHAR;
711 SPEC_SCLS($$) = S_SFR ;
713 ignoreTypedefType = 1;
716 $$ = newLink(SPECIFIER) ;
717 FUNC_REGBANK($$) = 1;
718 SPEC_NOUN($$) = V_CHAR;
719 SPEC_SCLS($$) = S_SFR ;
721 ignoreTypedefType = 1;
727 $$ = newLink(SPECIFIER) ;
728 FUNC_REGBANK($$) = 0;
729 SPEC_NOUN($$) = V_INT;
730 SPEC_SCLS($$) = S_SFR;
732 ignoreTypedefType = 1;
738 $$ = newLink(SPECIFIER) ;
739 FUNC_REGBANK($$) = 0;
740 SPEC_NOUN($$) = V_INT;
741 SPEC_SCLS($$) = S_SFR;
744 ignoreTypedefType = 1;
748 struct_or_union_specifier
749 : struct_or_union opt_stag
758 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
762 '{' struct_declaration_list '}'
767 // check for errors in structure members
768 for (sym=$5; sym; sym=sym->next) {
769 if (IS_ABSOLUTE(sym->etype)) {
770 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'");
771 SPEC_ABSA(sym->etype) = 0;
773 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
774 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class");
775 printTypeChainRaw (sym->type,NULL);
776 SPEC_SCLS(sym->etype) = 0;
778 for (dsym=sym->next; dsym; dsym=dsym->next) {
779 if (*dsym->name && strcmp(sym->name, dsym->name)==0) {
780 werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER,
781 $1==STRUCT ? "struct" : "union", sym->name);
782 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
787 /* Create a structdef */
789 sdef->fields = reverseSyms($5) ; /* link the fields */
790 sdef->size = compStructSize($1,sdef); /* update size of */
791 promoteAnonStructs ($1, sdef);
793 /* Create the specifier */
794 $$ = newLink (SPECIFIER) ;
795 SPEC_NOUN($$) = V_STRUCT;
796 SPEC_STRUCT($$)= sdef ;
798 | struct_or_union stag
800 $$ = newLink(SPECIFIER) ;
801 SPEC_NOUN($$) = V_STRUCT;
802 SPEC_STRUCT($$) = $2;
811 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
817 : STRUCT { $$ = STRUCT ; }
818 | UNION { $$ = UNION ; }
823 | { /* synthesize a name add to structtable */
824 $$ = newStruct(genSymName(NestLevel)) ;
825 $$->level = NestLevel ;
826 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
830 : identifier { /* add name to structure table */
831 $$ = findSymWithBlock (StructTab,$1,currBlockno);
833 $$ = newStruct($1->name) ;
834 $$->level = NestLevel ;
835 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
840 struct_declaration_list
842 | struct_declaration_list struct_declaration
846 /* go to the end of the chain */
847 while (sym->next) sym=sym->next;
855 : type_specifier_list struct_declarator_list ';'
857 /* add this type to all the symbols */
859 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
860 sym_link *btype = copyLinkChain($1);
861 if (options.unsigned_char && SPEC_NOUN(btype) == V_CHAR && !(btype)->select.s.b_signed)
862 SPEC_USIGN(btype) = 1;
864 /* make the symbol one level up */
867 pointerTypes(sym->type,btype);
870 sym->etype = getSpec(sym->type);
873 addDecl (sym,0,btype);
874 /* make sure the type is complete and sane */
875 checkTypeSanity(sym->etype, sym->name);
877 ignoreTypedefType = 0;
882 struct_declarator_list
884 | struct_declarator_list ',' struct_declarator
893 | ':' constant_expr {
894 unsigned int bitsize;
895 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
896 bitsize= (unsigned int) floatFromVal(constExprValue($2,TRUE));
897 if (bitsize > (port->s.int_size * 8)) {
898 bitsize = port->s.int_size * 8;
899 werror(E_BITFLD_SIZE, bitsize);
902 bitsize = BITVAR_PAD;
903 $$->bitVar = bitsize;
905 | declarator ':' constant_expr
907 unsigned int bitsize;
908 bitsize= (unsigned int) floatFromVal(constExprValue($3,TRUE));
909 if (bitsize > (port->s.int_size * 8)) {
910 bitsize = port->s.int_size * 8;
911 werror(E_BITFLD_SIZE, bitsize);
914 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
915 $$->bitVar = BITVAR_PAD;
916 werror(W_BITFLD_NAMED);
919 $1->bitVar = bitsize;
921 | { $$ = newSymbol ("", NestLevel) ; }
926 : ENUM '{' enumerator_list '}' {
927 $$ = newEnumType ($3); //copyLinkChain(cenum->type);
928 SPEC_SCLS(getSpec($$)) = 0;
931 | ENUM identifier '{' enumerator_list '}' {
935 csym=findSym(enumTab,$2,$2->name);
936 if ((csym && csym->level == $2->level))
938 werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
939 werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
942 enumtype = newEnumType ($4); //copyLinkChain(cenum->type);
943 SPEC_SCLS(getSpec(enumtype)) = 0;
946 /* add this to the enumerator table */
948 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
949 $$ = copyLinkChain(enumtype);
954 /* check the enumerator table */
955 if ((csym = findSym(enumTab,$2,$2->name)))
956 $$ = copyLinkChain(csym->type);
958 $$ = newLink(SPECIFIER) ;
959 SPEC_NOUN($$) = V_INT ;
966 | enumerator_list ',' {
968 | enumerator_list ',' enumerator
972 for (dsym=$1; dsym; dsym=dsym->next)
974 if (strcmp($3->name, dsym->name)==0)
976 werrorfl($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
977 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
987 : identifier opt_assign_expr
989 /* make the symbol one level up */
991 $1->type = copyLinkChain($2->type);
992 $1->etype= getSpec($1->type);
993 SPEC_ENUM($1->etype) = 1;
995 // do this now, so we can use it for the next enums in the list
1001 : '=' constant_expr {
1004 val = constExprValue($2,TRUE);
1005 if (!IS_INT(val->type) && !IS_CHAR(val->type))
1007 werror(E_ENUM_NON_INTEGER);
1008 SNPRINTF(lbuff, sizeof(lbuff),
1009 "%d",(int) floatFromVal(val));
1010 val = constVal(lbuff);
1016 SNPRINTF(lbuff, sizeof(lbuff),
1017 "%d",(int) floatFromVal(cenum)+1);
1018 $$ = cenum = constVal(lbuff);
1021 SNPRINTF(lbuff, sizeof(lbuff),
1023 $$ = cenum = constVal(lbuff);
1029 : declarator3 { $$ = $1 ; }
1030 | pointer declarator3
1032 addDecl ($2,0,reverseLink($1));
1038 : declarator2_function_attributes { $$ = $1 ; }
1039 | declarator2 { $$ = $1 ; }
1043 : declarator2_function_attributes { $$ = $1; }
1044 | pointer declarator2_function_attributes
1046 addDecl ($2,0,reverseLink($1));
1051 declarator2_function_attributes
1052 : function_declarator2 { $$ = $1 ; }
1053 | function_declarator2 function_attribute {
1054 // copy the functionAttributes (not the args and hasVargs !!)
1057 sym_link *funcType=$1->type;
1059 while (funcType && !IS_FUNC(funcType))
1060 funcType = funcType->next;
1063 werror (E_FUNC_ATTR);
1066 args=FUNC_ARGS(funcType);
1067 hasVargs=FUNC_HASVARARGS(funcType);
1069 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
1070 sizeof($2->funcAttrs));
1072 FUNC_ARGS(funcType)=args;
1073 FUNC_HASVARARGS(funcType)=hasVargs;
1076 memset (&$2->funcAttrs, 0,
1077 sizeof($2->funcAttrs));
1086 | '(' declarator ')' { $$ = $2; }
1087 | declarator3 '[' ']'
1091 p = newLink (DECLARATOR);
1092 DCL_TYPE(p) = ARRAY ;
1096 | declarator3 '[' constant_expr ']'
1101 tval = constExprValue($3,TRUE);
1102 /* if it is not a constant then Error */
1103 p = newLink (DECLARATOR);
1104 DCL_TYPE(p) = ARRAY ;
1105 if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1106 werror(E_CONST_EXPECTED) ;
1107 /* Assume a single item array to limit the cascade */
1108 /* of additional errors. */
1112 DCL_ELEM(p) = (int) floatFromVal(tval) ;
1118 function_declarator2
1119 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
1120 | declarator2 '(' { NestLevel++ ; currBlockno++; }
1121 parameter_type_list ')'
1125 addDecl ($1,FUNCTION,NULL) ;
1127 funcType = $1->type;
1128 while (funcType && !IS_FUNC(funcType))
1129 funcType = funcType->next;
1133 FUNC_HASVARARGS(funcType) = IS_VARG($4);
1134 FUNC_ARGS(funcType) = reverseVal($4);
1136 /* nest level was incremented to take care of the parms */
1140 // if this was a pointer (to a function)
1141 if (!IS_FUNC($1->type))
1142 cleanUpLevel(SymbolTab,NestLevel+1);
1146 | declarator2 '(' identifier_list ')'
1148 werror(E_OLD_STYLE,$1->name) ;
1149 /* assume it returns an int */
1150 $1->type = $1->etype = newIntLink();
1156 : unqualified_pointer { $$ = $1 ;}
1157 | unqualified_pointer type_specifier_list
1162 DCL_PTR_CONST($1) = SPEC_CONST($2);
1163 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1166 werror (W_PTR_TYPE_INVALID);
1168 | unqualified_pointer pointer
1172 DCL_TYPE($2)=port->unqualified_pointer;
1174 | unqualified_pointer type_specifier_list pointer
1177 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1178 DCL_PTR_CONST($1) = SPEC_CONST($2);
1179 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1180 switch (SPEC_SCLS($2)) {
1182 DCL_TYPE($3) = FPOINTER;
1185 DCL_TYPE($3) = IPOINTER ;
1188 DCL_TYPE($3) = PPOINTER ;
1191 DCL_TYPE($3) = POINTER ;
1194 DCL_TYPE($3) = CPOINTER ;
1197 DCL_TYPE($3) = EEPPOINTER;
1200 // this could be just "constant"
1201 // werror(W_PTR_TYPE_INVALID);
1206 werror (W_PTR_TYPE_INVALID);
1214 $$ = newLink(DECLARATOR);
1215 DCL_TYPE($$)=UPOINTER;
1221 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1222 | type_specifier_list type_specifier {
1223 /* if the decl $2 is not a specifier */
1224 /* find the spec and replace it */
1225 if ( !IS_SPEC($2)) {
1226 sym_link *lnk = $2 ;
1227 while (lnk && !IS_SPEC(lnk->next))
1229 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1233 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1239 | identifier_list ',' identifier
1248 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1252 : parameter_declaration
1253 | parameter_list ',' parameter_declaration
1260 parameter_declaration
1261 : type_specifier_list declarator
1264 pointerTypes($2->type,$1);
1265 if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
1268 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1271 ignoreTypedefType = 0;
1275 if (options.unsigned_char && SPEC_NOUN($1) == V_CHAR && !($1)->select.s.b_signed)
1278 $$->etype = getSpec($$->type);
1279 ignoreTypedefType = 0;
1284 : type_specifier_list { $$ = $1; ignoreTypedefType = 0;}
1285 | type_specifier_list abstract_declarator
1287 /* go to the end of the list */
1289 pointerTypes($2,$1);
1290 for ( p = $2 ; p && p->next ; p=p->next);
1292 werror(E_SYNTAX_ERROR, yytext);
1297 ignoreTypedefType = 0;
1302 : pointer { $$ = reverseLink($1); }
1303 | abstract_declarator2
1304 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1305 if (IS_PTR($1) && IS_FUNC($2))
1306 DCL_TYPE($1) = CPOINTER;
1310 abstract_declarator2
1311 : '(' abstract_declarator ')' { $$ = $2 ; }
1313 $$ = newLink (DECLARATOR);
1314 DCL_TYPE($$) = ARRAY ;
1317 | '[' constant_expr ']' {
1319 $$ = newLink (DECLARATOR);
1320 DCL_TYPE($$) = ARRAY ;
1321 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1323 | abstract_declarator2 '[' ']' {
1324 $$ = newLink (DECLARATOR);
1325 DCL_TYPE($$) = ARRAY ;
1329 | abstract_declarator2 '[' constant_expr ']'
1332 $$ = newLink (DECLARATOR);
1333 DCL_TYPE($$) = ARRAY ;
1334 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1337 | '(' ')' { $$ = NULL;}
1338 | '(' parameter_type_list ')' { $$ = NULL;}
1339 | abstract_declarator2 '(' ')' {
1340 // $1 must be a pointer to a function
1341 sym_link *p=newLink(DECLARATOR);
1342 DCL_TYPE(p) = FUNCTION;
1344 // ((void (code *) ()) 0) ()
1345 $1=newLink(DECLARATOR);
1346 DCL_TYPE($1)=CPOINTER;
1351 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1352 sym_link *p=newLink(DECLARATOR);
1353 DCL_TYPE(p) = FUNCTION;
1355 FUNC_HASVARARGS(p) = IS_VARG($4);
1356 FUNC_ARGS(p) = reverseVal($4);
1358 /* nest level was incremented to take care of the parms */
1362 /* ((void (code *) (void)) 0) () */
1363 $1=newLink(DECLARATOR);
1364 DCL_TYPE($1)=CPOINTER;
1369 // remove the symbol args (if any)
1370 cleanUpLevel(SymbolTab,NestLevel+1);
1375 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1376 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1377 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1382 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1387 | compound_statement
1388 | expression_statement
1389 | selection_statement
1390 | iteration_statement
1392 | critical_statement
1396 ex = newNode(INLINEASM,NULL,NULL);
1397 ex->values.inlineasm = strdup($1);
1406 STACK_PUSH(continueStack,NULL);
1407 STACK_PUSH(breakStack,NULL);
1413 : critical statement {
1414 STACK_POP(breakStack);
1415 STACK_POP(continueStack);
1417 $$ = newNode(CRITICAL,$2,NULL);
1422 // : identifier ':' statement { $$ = createLabel($1,$3); }
1423 : identifier ':' { $$ = createLabel($1,NULL);
1425 | CASE constant_expr ':'
1427 if (STACK_EMPTY(swStk))
1428 $$ = createCase(NULL,$2,NULL);
1430 $$ = createCase(STACK_PEEK(swStk),$2,NULL);
1432 | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
1434 if (STACK_EMPTY(swStk))
1435 $$ = createDefault(NULL,$<asts>2,NULL);
1437 $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL);
1443 STACK_PUSH(blockNum,currBlockno);
1444 currBlockno = ++blockNo ;
1445 ignoreTypedefType = 0;
1449 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1453 : start_block end_block { $$ = createBlock(NULL,NULL); }
1454 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1456 declaration_list { addSymChain(&$2); }
1457 end_block { $$ = createBlock($2,NULL) ; }
1459 declaration_list { addSymChain (&$2); }
1461 end_block {$$ = createBlock($2,$4) ; }
1462 | error ';' { $$ = NULL ; }
1468 /* if this is typedef declare it immediately */
1469 if ( $1 && IS_TYPEDEF($1->etype)) {
1470 allocVariables ($1);
1475 ignoreTypedefType = 0;
1478 | declaration_list declaration
1482 /* if this is a typedef */
1483 if ($2 && IS_TYPEDEF($2->etype)) {
1484 allocVariables ($2);
1488 /* get to the end of the previous decl */
1498 ignoreTypedefType = 0;
1504 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1507 expression_statement
1509 | expr ';' { $$ = $1; seqPointNo++;}
1513 : ELSE statement { $$ = $2 ; }
1519 : IF '(' expr ')' { seqPointNo++;} statement else_statement
1522 $$ = createIf ($3, $6, $7 );
1525 | SWITCH '(' expr ')' {
1527 static int swLabel = 0 ;
1530 /* create a node for expression */
1531 ex = newNode(SWITCH,$3,NULL);
1532 STACK_PUSH(swStk,ex); /* save it in the stack */
1533 ex->values.switchVals.swNum = swLabel ;
1535 /* now create the label */
1536 SNPRINTF(lbuff, sizeof(lbuff),
1537 "_swBrk_%d",swLabel++);
1538 $<sym>$ = newSymbol(lbuff,NestLevel);
1539 /* put label in the break stack */
1540 STACK_PUSH(breakStack,$<sym>$);
1543 /* get back the switch form the stack */
1544 $$ = STACK_POP(swStk) ;
1545 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1546 STACK_POP(breakStack);
1550 while : WHILE { /* create and push the continue , break & body labels */
1551 static int Lblnum = 0 ;
1553 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1554 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1556 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1557 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1559 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1560 $$ = newSymbol(lbuff,NestLevel);
1564 do : DO { /* create and push the continue , break & body Labels */
1565 static int Lblnum = 0 ;
1568 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1569 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1571 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1572 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1574 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1575 $$ = newSymbol (lbuff,NestLevel);
1579 for : FOR { /* create & push continue, break & body labels */
1580 static int Lblnum = 0 ;
1583 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1584 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1586 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1587 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1589 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1590 $$ = newSymbol(lbuff,NestLevel);
1592 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1593 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1598 : while '(' expr ')' { seqPointNo++;} statement
1601 $$ = createWhile ( $1, STACK_POP(continueStack),
1602 STACK_POP(breakStack), $3, $6 );
1603 $$->lineno = $1->lineDef ;
1606 | do statement WHILE '(' expr ')' ';'
1610 $$ = createDo ( $1 , STACK_POP(continueStack),
1611 STACK_POP(breakStack), $5, $2);
1612 $$->lineno = $1->lineDef ;
1615 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1619 /* if break or continue statement present
1620 then create a general case loop */
1621 if (STACK_PEEK(continueStack)->isref ||
1622 STACK_PEEK(breakStack)->isref) {
1623 $$ = createFor ($1, STACK_POP(continueStack),
1624 STACK_POP(breakStack) ,
1625 STACK_POP(forStack) ,
1628 $$ = newNode(FOR,$9,NULL);
1629 AST_FOR($$,trueLabel) = $1;
1630 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1631 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1632 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1633 AST_FOR($$,initExpr) = $3;
1634 AST_FOR($$,condExpr) = $5;
1635 AST_FOR($$,loopExpr) = $7;
1643 : { $$ = NULL ; seqPointNo++; }
1644 | expr { $$ = $1 ; seqPointNo++; }
1648 : GOTO identifier ';' {
1650 $$ = newAst_VALUE(symbolVal($2));
1651 $$ = newNode(GOTO,$$,NULL);
1654 /* make sure continue is in context */
1655 if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1656 werror(E_BREAK_CONTEXT);
1660 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1661 $$ = newNode(GOTO,$$,NULL);
1662 /* mark the continue label as referenced */
1663 STACK_PEEK(continueStack)->isref = 1;
1667 if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1668 werror(E_BREAK_CONTEXT);
1671 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1672 $$ = newNode(GOTO,$$,NULL);
1673 STACK_PEEK(breakStack)->isref = 1;
1679 werror(E_INVALID_CRITICAL);
1682 $$ = newNode(RETURN,NULL,NULL);
1688 werror(E_INVALID_CRITICAL);
1691 $$ = newNode(RETURN,NULL,$2);
1697 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }