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 SHADOWREGS WPARAM
93 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE 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
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
104 %type <yyint> Interrupt_storage
105 %type <sym> identifier declarator declarator2 declarator3 enumerator_list enumerator
106 %type <sym> struct_declarator function_declarator function_declarator2
107 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
108 %type <sym> declaration init_declarator_list init_declarator
109 %type <sym> declaration_list identifier_list parameter_identifier_list
110 %type <sym> declarator2_function_attributes while do for critical
111 %type <lnk> pointer type_specifier_list type_specifier type_name
112 %type <lnk> storage_class_specifier struct_or_union_specifier
113 %type <lnk> declaration_specifiers sfr_reg_bit sfr_attributes type_specifier2
114 %type <lnk> function_attribute function_attributes enum_specifier
115 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
116 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
117 %type <sdef> stag opt_stag
118 %type <asts> primary_expr
119 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
120 %type <asts> additive_expr shift_expr relational_expr equality_expr
121 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
122 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
123 %type <asts> expr argument_expr_list function_definition expr_opt
124 %type <asts> statement_list statement labeled_statement compound_statement
125 %type <asts> expression_statement selection_statement iteration_statement
126 %type <asts> jump_statement function_body else_statement string_literal
127 %type <asts> critical_statement
128 %type <ilist> initializer initializer_list
129 %type <yyint> unary_operator assignment_operator struct_or_union
136 : external_definition
137 | file external_definition
141 : function_definition {
145 ignoreTypedefType = 0;
147 && IS_FUNC($1->type))
149 /* The only legal storage classes for
150 * a function prototype (declaration)
151 * are extern and static. extern is the
152 * default. Thus, if this function isn't
153 * explicitly marked static, mark it
157 && IS_SPEC($1->etype)
158 && !SPEC_STAT($1->etype))
160 SPEC_EXTR($1->etype) = 1;
164 allocVariables ($1) ;
165 cleanUpLevel (SymbolTab,1);
170 : function_declarator function_body { /* function type not specified */
171 /* assume it to be 'int' */
172 addDecl($1,0,newIntLink());
173 $$ = createFunction($1,$2);
175 | declaration_specifiers function_declarator function_body
177 pointerTypes($2->type,copyLinkChain($1));
179 $$ = createFunction($2,$3);
184 : function_attributes
185 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
190 $$ = newLink(SPECIFIER) ;
191 FUNC_REGBANK($$) = (int) floatFromVal($2);
193 | REENTRANT { $$ = newLink (SPECIFIER);
196 | CRITICAL { $$ = newLink (SPECIFIER);
197 FUNC_ISCRITICAL($$) = 1;
199 | NAKED { $$ = newLink (SPECIFIER);
202 | JAVANATIVE { $$ = newLink (SPECIFIER);
203 FUNC_ISJAVANATIVE($$)=1;
205 | OVERLAY { $$ = newLink (SPECIFIER);
206 FUNC_ISOVERLAY($$)=1;
208 | NONBANKED {$$ = newLink (SPECIFIER);
209 FUNC_NONBANKED($$) = 1;
210 if (FUNC_BANKED($$)) {
211 werror(W_BANKED_WITH_NONBANKED);
214 | SHADOWREGS {$$ = newLink (SPECIFIER);
215 FUNC_ISSHADOWREGS($$) = 1;
217 | WPARAM {$$ = newLink (SPECIFIER);
218 FUNC_ISWPARAM($$) = 1;
220 | BANKED {$$ = newLink (SPECIFIER);
222 if (FUNC_NONBANKED($$)) {
223 werror(W_BANKED_WITH_NONBANKED);
226 werror(W_BANKED_WITH_STATIC);
231 $$ = newLink (SPECIFIER) ;
232 FUNC_INTNO($$) = $1 ;
239 | declaration_list compound_statement
241 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
247 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
248 | CONSTANT { $$ = newAst_VALUE($1); }
250 | '(' expr ')' { $$ = $2 ; }
254 : STRING_LITERAL { $$ = newAst_VALUE($1); }
259 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
260 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
261 $$->left->funcName = 1;}
262 | postfix_expr '(' argument_expr_list ')'
264 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
266 | postfix_expr '.' { ignoreTypedefType = 1; } identifier
268 ignoreTypedefType = 0;
269 $4 = newSymbol($4->name,NestLevel);
271 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($4)));
272 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($4))) ; */
274 | postfix_expr PTR_OP { ignoreTypedefType = 1; } identifier
276 ignoreTypedefType = 0;
277 $4 = newSymbol($4->name,NestLevel);
279 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($4)));
281 | postfix_expr INC_OP
282 { $$ = newNode(INC_OP,$1,NULL);}
283 | postfix_expr DEC_OP
284 { $$ = newNode(DEC_OP,$1,NULL); }
289 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
294 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
295 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
296 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
297 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
298 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
299 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
313 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
318 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
319 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
320 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
324 : multiplicative_expr
325 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
326 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
331 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
332 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
337 | relational_expr '<' shift_expr {
339 newNode('!',newNode(GE_OP,$1,$3),NULL) :
340 newNode('<', $1,$3));
342 | relational_expr '>' shift_expr {
344 newNode('!',newNode(LE_OP,$1,$3),NULL) :
347 | relational_expr LE_OP shift_expr {
349 newNode('!', newNode('>', $1 , $3 ), NULL) :
350 newNode(LE_OP,$1,$3));
352 | relational_expr GE_OP shift_expr {
354 newNode('!', newNode('<', $1 , $3 ), NULL) :
355 newNode(GE_OP,$1,$3));
361 | equality_expr EQ_OP relational_expr {
363 newNode('!',newNode(NE_OP,$1,$3),NULL) :
364 newNode(EQ_OP,$1,$3));
366 | equality_expr NE_OP relational_expr {
368 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
369 newNode(NE_OP,$1,$3));
375 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
380 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
385 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
390 | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expr
391 { $$ = newNode(AND_OP,$1,$4);}
396 | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr
397 { $$ = newNode(OR_OP,$1,$4); }
402 | logical_or_expr '?' { seqPointNo++;} logical_or_expr ':' conditional_expr
404 $$ = newNode(':',$4,$6) ;
405 $$ = newNode('?',$1,$$) ;
411 | cast_expr assignment_operator assignment_expr
416 $$ = newNode($2,$1,$3);
419 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
420 newNode('*',removePreIncDecOps(copyAst($1)),$3));
423 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
424 newNode('/',removePreIncDecOps(copyAst($1)),$3));
427 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
428 newNode('%',removePreIncDecOps(copyAst($1)),$3));
431 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
432 newNode('+',removePreIncDecOps(copyAst($1)),$3));
435 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
436 newNode('-',removePreIncDecOps(copyAst($1)),$3));
439 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
440 newNode(LEFT_OP,removePreIncDecOps(copyAst($1)),$3));
443 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
444 newNode(RIGHT_OP,removePreIncDecOps(copyAst($1)),$3));
447 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
448 newNode('&',removePreIncDecOps(copyAst($1)),$3));
451 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
452 newNode('^',removePreIncDecOps(copyAst($1)),$3));
455 /* $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); */
456 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
457 newNode('|',removePreIncDecOps(copyAst($1)),$3));
482 | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);}
490 : declaration_specifiers ';'
493 werror(W_USELESS_DECL);
497 | declaration_specifiers init_declarator_list ';'
499 /* add the specifier list to the id */
502 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
503 sym_link *lnk = copyLinkChain($1);
504 /* do the pointer stuff */
505 pointerTypes(sym->type,lnk);
506 addDecl (sym,0,lnk) ;
514 declaration_specifiers
515 : storage_class_specifier { $$ = $1; }
516 | storage_class_specifier declaration_specifiers {
517 /* if the decl $2 is not a specifier */
518 /* find the spec and replace it */
521 while (lnk && !IS_SPEC(lnk->next))
523 lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
527 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
529 | type_specifier { $$ = $1; }
530 | type_specifier declaration_specifiers {
531 /* if the decl $2 is not a specifier */
532 /* find the spec and replace it */
535 while (lnk && !IS_SPEC(lnk->next))
537 lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
541 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
547 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
551 : declarator { $1->ival = NULL ; }
552 | declarator '=' initializer { $1->ival = $3 ; }
556 storage_class_specifier
558 $$ = newLink (SPECIFIER) ;
559 SPEC_TYPEDEF($$) = 1 ;
562 $$ = newLink(SPECIFIER);
566 $$ = newLink (SPECIFIER);
570 $$ = newLink (SPECIFIER) ;
571 SPEC_SCLS($$) = S_AUTO ;
574 $$ = newLink (SPECIFIER);
575 SPEC_SCLS($$) = S_REGISTER ;
580 : INTERRUPT { $$ = INTNO_UNSPEC ; }
582 { int intno = (int) floatFromVal($2);
583 if ((intno >= 0) && (intno <= INTNO_MAX))
587 werror(E_INT_BAD_INTNO, intno);
595 | type_specifier2 AT constant_expr
597 /* add this to the storage class specifier */
598 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
599 /* now get the abs addr from value */
600 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
606 $$=newLink(SPECIFIER);
607 SPEC_NOUN($$) = V_CHAR ;
608 ignoreTypedefType = 1;
611 $$=newLink(SPECIFIER);
612 $$->select.s._short = 1 ;
613 ignoreTypedefType = 1;
616 $$=newLink(SPECIFIER);
617 SPEC_NOUN($$) = V_INT ;
618 ignoreTypedefType = 1;
621 $$=newLink(SPECIFIER);
623 ignoreTypedefType = 1;
626 $$=newLink(SPECIFIER);
627 $$->select.s._signed = 1;
628 ignoreTypedefType = 1;
631 $$=newLink(SPECIFIER);
633 ignoreTypedefType = 1;
636 $$=newLink(SPECIFIER);
637 SPEC_NOUN($$) = V_VOID ;
638 ignoreTypedefType = 1;
641 $$=newLink(SPECIFIER);
645 $$=newLink(SPECIFIER);
646 SPEC_VOLATILE($$) = 1 ;
649 $$=newLink(SPECIFIER);
650 SPEC_NOUN($$) = V_FLOAT;
651 ignoreTypedefType = 1;
654 $$ = newLink (SPECIFIER);
655 SPEC_SCLS($$) = S_XDATA ;
658 $$ = newLink (SPECIFIER) ;
659 SPEC_SCLS($$) = S_CODE ;
662 $$ = newLink (SPECIFIER) ;
663 SPEC_SCLS($$) = S_EEPROM ;
666 $$ = newLink (SPECIFIER);
667 SPEC_SCLS($$) = S_DATA ;
670 $$ = newLink (SPECIFIER);
671 SPEC_SCLS($$) = S_IDATA ;
674 $$ = newLink (SPECIFIER);
675 SPEC_SCLS($$) = S_PDATA ;
678 $$=newLink(SPECIFIER);
679 SPEC_NOUN($$) = V_BIT ;
680 SPEC_SCLS($$) = S_BIT ;
683 ignoreTypedefType = 1;
686 | struct_or_union_specifier {
689 ignoreTypedefType = 1;
694 ignoreTypedefType = 1;
701 sym = findSym(TypedefTab,NULL,$1) ;
702 $$ = p = copyLinkChain(sym->type);
703 SPEC_TYPEDEF(getSpec(p)) = 0;
704 ignoreTypedefType = 1;
711 $$ = newLink(SPECIFIER) ;
712 SPEC_NOUN($$) = V_SBIT;
713 SPEC_SCLS($$) = S_SBIT;
716 ignoreTypedefType = 1;
723 $$ = newLink(SPECIFIER) ;
724 FUNC_REGBANK($$) = 0;
725 SPEC_NOUN($$) = V_CHAR;
726 SPEC_SCLS($$) = S_SFR ;
728 ignoreTypedefType = 1;
731 $$ = newLink(SPECIFIER) ;
732 FUNC_REGBANK($$) = 1;
733 SPEC_NOUN($$) = V_CHAR;
734 SPEC_SCLS($$) = S_SFR ;
736 ignoreTypedefType = 1;
740 struct_or_union_specifier
741 : struct_or_union opt_stag
750 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
754 '{' struct_declaration_list '}'
759 // check for errors in structure members
760 for (sym=$5; sym; sym=sym->next) {
761 if (IS_ABSOLUTE(sym->etype)) {
762 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'");
763 SPEC_ABSA(sym->etype) = 0;
765 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
766 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class");
767 printTypeChainRaw (sym->type,NULL);
768 SPEC_SCLS(sym->etype) = 0;
770 for (dsym=sym->next; dsym; dsym=dsym->next) {
771 if (*dsym->name && strcmp(sym->name, dsym->name)==0) {
772 werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER,
773 $1==STRUCT ? "struct" : "union", sym->name);
774 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
779 /* Create a structdef */
781 sdef->fields = reverseSyms($5) ; /* link the fields */
782 sdef->size = compStructSize($1,sdef); /* update size of */
783 promoteAnonStructs ($1, sdef);
785 /* Create the specifier */
786 $$ = newLink (SPECIFIER) ;
787 SPEC_NOUN($$) = V_STRUCT;
788 SPEC_STRUCT($$)= sdef ;
790 | struct_or_union stag
792 $$ = newLink(SPECIFIER) ;
793 SPEC_NOUN($$) = V_STRUCT;
794 SPEC_STRUCT($$) = $2;
803 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
809 : STRUCT { $$ = STRUCT ; }
810 | UNION { $$ = UNION ; }
815 | { /* synthesize a name add to structtable */
816 $$ = newStruct(genSymName(NestLevel)) ;
817 $$->level = NestLevel ;
818 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
822 : identifier { /* add name to structure table */
823 $$ = findSymWithBlock (StructTab,$1,currBlockno);
825 $$ = newStruct($1->name) ;
826 $$->level = NestLevel ;
827 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
832 struct_declaration_list
834 | struct_declaration_list struct_declaration
838 /* go to the end of the chain */
839 while (sym->next) sym=sym->next;
847 : type_specifier_list struct_declarator_list ';'
849 /* add this type to all the symbols */
851 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
852 sym_link *btype = copyLinkChain($1);
854 /* make the symbol one level up */
857 pointerTypes(sym->type,btype);
860 sym->etype = getSpec(sym->type);
863 addDecl (sym,0,btype);
864 /* make sure the type is complete and sane */
865 checkTypeSanity(sym->etype, sym->name);
867 ignoreTypedefType = 0;
872 struct_declarator_list
874 | struct_declarator_list ',' struct_declarator
883 | ':' constant_expr {
885 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
886 bitsize= (int) floatFromVal(constExprValue($2,TRUE));
887 if (bitsize > (port->s.int_size * 8)) {
888 bitsize = port->s.int_size * 8;
889 werror(E_BITFLD_SIZE, bitsize);
892 bitsize = BITVAR_PAD;
893 $$->bitVar = bitsize;
895 | declarator ':' constant_expr
898 bitsize= (int) floatFromVal(constExprValue($3,TRUE));
899 if (bitsize > (port->s.int_size * 8)) {
900 bitsize = port->s.int_size * 8;
901 werror(E_BITFLD_SIZE, bitsize);
904 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
905 $$->bitVar = BITVAR_PAD;
906 werror(W_BITFLD_NAMED);
909 $1->bitVar = bitsize;
911 | { $$ = newSymbol ("", NestLevel) ; }
916 : ENUM '{' enumerator_list '}' {
917 $$ = newEnumType ($3); //copyLinkChain(cenum->type);
918 SPEC_SCLS(getSpec($$)) = 0;
921 | ENUM identifier '{' enumerator_list '}' {
925 csym=findSym(enumTab,$2,$2->name);
926 if ((csym && csym->level == $2->level))
928 werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
929 werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
932 enumtype = newEnumType ($4); //copyLinkChain(cenum->type);
933 SPEC_SCLS(getSpec(enumtype)) = 0;
936 /* add this to the enumerator table */
938 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
939 $$ = copyLinkChain(enumtype);
944 /* check the enumerator table */
945 if ((csym = findSym(enumTab,$2,$2->name)))
946 $$ = copyLinkChain(csym->type);
948 $$ = newLink(SPECIFIER) ;
949 SPEC_NOUN($$) = V_INT ;
956 | enumerator_list ',' {
958 | enumerator_list ',' enumerator
962 for (dsym=$1; dsym; dsym=dsym->next)
964 if (strcmp($3->name, dsym->name)==0)
966 werrorfl($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
967 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
977 : identifier opt_assign_expr
979 /* make the symbol one level up */
981 $1->type = copyLinkChain($2->type);
982 $1->etype= getSpec($1->type);
983 SPEC_ENUM($1->etype) = 1;
985 // do this now, so we can use it for the next enums in the list
991 : '=' constant_expr {
994 val = constExprValue($2,TRUE);
995 if (!IS_INT(val->type) && !IS_CHAR(val->type))
997 werror(E_ENUM_NON_INTEGER);
998 SNPRINTF(lbuff, sizeof(lbuff),
999 "%d",(int) floatFromVal(val));
1000 val = constVal(lbuff);
1006 SNPRINTF(lbuff, sizeof(lbuff),
1007 "%d",(int) floatFromVal(cenum)+1);
1008 $$ = cenum = constVal(lbuff);
1011 SNPRINTF(lbuff, sizeof(lbuff),
1013 $$ = cenum = constVal(lbuff);
1019 : declarator3 { $$ = $1 ; }
1020 | pointer declarator3
1022 addDecl ($2,0,reverseLink($1));
1028 : declarator2_function_attributes { $$ = $1 ; }
1029 | declarator2 { $$ = $1 ; }
1033 : declarator2_function_attributes { $$ = $1; }
1034 | pointer declarator2_function_attributes
1036 addDecl ($2,0,reverseLink($1));
1041 declarator2_function_attributes
1042 : function_declarator2 { $$ = $1 ; }
1043 | function_declarator2 function_attribute {
1044 // copy the functionAttributes (not the args and hasVargs !!)
1047 sym_link *funcType=$1->type;
1049 while (funcType && !IS_FUNC(funcType))
1050 funcType = funcType->next;
1053 werror (E_FUNC_ATTR);
1056 args=FUNC_ARGS(funcType);
1057 hasVargs=FUNC_HASVARARGS(funcType);
1059 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
1060 sizeof($2->funcAttrs));
1062 FUNC_ARGS(funcType)=args;
1063 FUNC_HASVARARGS(funcType)=hasVargs;
1066 memset (&$2->funcAttrs, 0,
1067 sizeof($2->funcAttrs));
1076 | '(' declarator ')' { $$ = $2; }
1077 | declarator3 '[' ']'
1081 p = newLink (DECLARATOR);
1082 DCL_TYPE(p) = ARRAY ;
1086 | declarator3 '[' constant_expr ']'
1091 tval = constExprValue($3,TRUE);
1092 /* if it is not a constant then Error */
1093 p = newLink (DECLARATOR);
1094 DCL_TYPE(p) = ARRAY ;
1095 if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1096 werror(E_CONST_EXPECTED) ;
1097 /* Assume a single item array to limit the cascade */
1098 /* of additional errors. */
1102 DCL_ELEM(p) = (int) floatFromVal(tval) ;
1108 function_declarator2
1109 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
1110 | declarator2 '(' { NestLevel++ ; currBlockno++; }
1111 parameter_type_list ')'
1115 addDecl ($1,FUNCTION,NULL) ;
1117 funcType = $1->type;
1118 while (funcType && !IS_FUNC(funcType))
1119 funcType = funcType->next;
1123 FUNC_HASVARARGS(funcType) = IS_VARG($4);
1124 FUNC_ARGS(funcType) = reverseVal($4);
1126 /* nest level was incremented to take care of the parms */
1130 // if this was a pointer (to a function)
1131 if (!IS_FUNC($1->type))
1132 cleanUpLevel(SymbolTab,NestLevel+1);
1136 | declarator2 '(' parameter_identifier_list ')'
1138 werror(E_OLD_STYLE,$1->name) ;
1139 /* assume it returns an int */
1140 $1->type = $1->etype = newIntLink();
1146 : unqualified_pointer { $$ = $1 ;}
1147 | unqualified_pointer type_specifier_list
1152 DCL_PTR_CONST($1) = SPEC_CONST($2);
1153 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1156 werror (W_PTR_TYPE_INVALID);
1158 | unqualified_pointer pointer
1162 DCL_TYPE($2)=port->unqualified_pointer;
1164 | unqualified_pointer type_specifier_list pointer
1167 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1168 DCL_PTR_CONST($1) = SPEC_CONST($2);
1169 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1170 switch (SPEC_SCLS($2)) {
1172 DCL_TYPE($3) = FPOINTER;
1175 DCL_TYPE($3) = IPOINTER ;
1178 DCL_TYPE($3) = PPOINTER ;
1181 DCL_TYPE($3) = POINTER ;
1184 DCL_TYPE($3) = CPOINTER ;
1187 DCL_TYPE($3) = EEPPOINTER;
1190 // this could be just "constant"
1191 // werror(W_PTR_TYPE_INVALID);
1196 werror (W_PTR_TYPE_INVALID);
1204 $$ = newLink(DECLARATOR);
1205 DCL_TYPE($$)=UPOINTER;
1211 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1212 | type_specifier_list type_specifier {
1213 /* if the decl $2 is not a specifier */
1214 /* find the spec and replace it */
1215 if ( !IS_SPEC($2)) {
1216 sym_link *lnk = $2 ;
1217 while (lnk && !IS_SPEC(lnk->next))
1219 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1223 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1227 parameter_identifier_list
1229 | identifier_list ',' ELIPSIS
1234 | identifier_list ',' identifier
1243 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1247 : parameter_declaration
1248 | parameter_list ',' parameter_declaration
1255 parameter_declaration
1256 : type_specifier_list declarator
1259 pointerTypes($2->type,$1);
1261 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1264 ignoreTypedefType = 0;
1269 $$->etype = getSpec($$->type);
1270 ignoreTypedefType = 0;
1275 : type_specifier_list { $$ = $1; ignoreTypedefType = 0;}
1276 | type_specifier_list abstract_declarator
1278 /* go to the end of the list */
1280 pointerTypes($2,$1);
1281 for ( p = $2 ; p && p->next ; p=p->next);
1283 werror(E_SYNTAX_ERROR, yytext);
1288 ignoreTypedefType = 0;
1293 : pointer { $$ = reverseLink($1); }
1294 | abstract_declarator2
1295 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1296 if (IS_PTR($1) && IS_FUNC($2))
1297 DCL_TYPE($1) = CPOINTER;
1301 abstract_declarator2
1302 : '(' abstract_declarator ')' { $$ = $2 ; }
1304 $$ = newLink (DECLARATOR);
1305 DCL_TYPE($$) = ARRAY ;
1308 | '[' constant_expr ']' {
1310 $$ = newLink (DECLARATOR);
1311 DCL_TYPE($$) = ARRAY ;
1312 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1314 | abstract_declarator2 '[' ']' {
1315 $$ = newLink (DECLARATOR);
1316 DCL_TYPE($$) = ARRAY ;
1320 | abstract_declarator2 '[' constant_expr ']'
1323 $$ = newLink (DECLARATOR);
1324 DCL_TYPE($$) = ARRAY ;
1325 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1328 | '(' ')' { $$ = NULL;}
1329 | '(' parameter_type_list ')' { $$ = NULL;}
1330 | abstract_declarator2 '(' ')' {
1331 // $1 must be a pointer to a function
1332 sym_link *p=newLink(DECLARATOR);
1333 DCL_TYPE(p) = FUNCTION;
1335 // ((void (code *) ()) 0) ()
1336 $1=newLink(DECLARATOR);
1337 DCL_TYPE($1)=CPOINTER;
1342 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1343 sym_link *p=newLink(DECLARATOR);
1344 DCL_TYPE(p) = FUNCTION;
1346 FUNC_HASVARARGS(p) = IS_VARG($4);
1347 FUNC_ARGS(p) = reverseVal($4);
1349 /* nest level was incremented to take care of the parms */
1355 // remove the symbol args (if any)
1356 cleanUpLevel(SymbolTab,NestLevel+1);
1361 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1362 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1363 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1368 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1373 | compound_statement
1374 | expression_statement
1375 | selection_statement
1376 | iteration_statement
1378 | critical_statement
1382 ex = newNode(INLINEASM,NULL,NULL);
1383 ex->values.inlineasm = strdup($1);
1392 STACK_PUSH(continueStack,NULL);
1393 STACK_PUSH(breakStack,NULL);
1399 : critical statement {
1400 STACK_POP(breakStack);
1401 STACK_POP(continueStack);
1403 $$ = newNode(CRITICAL,$2,NULL);
1408 // : identifier ':' statement { $$ = createLabel($1,$3); }
1409 : identifier ':' { $$ = createLabel($1,NULL);
1411 | CASE constant_expr ':'
1413 if (STACK_EMPTY(swStk))
1414 $$ = createCase(NULL,$2,NULL);
1416 $$ = createCase(STACK_PEEK(swStk),$2,NULL);
1418 | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':'
1420 if (STACK_EMPTY(swStk))
1421 $$ = createDefault(NULL,$<asts>2,NULL);
1423 $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL);
1429 STACK_PUSH(blockNum,currBlockno);
1430 currBlockno = ++blockNo ;
1431 ignoreTypedefType = 0;
1435 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1439 : start_block end_block { $$ = createBlock(NULL,NULL); }
1440 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1442 declaration_list { addSymChain($2); }
1443 end_block { $$ = createBlock($2,NULL) ; }
1445 declaration_list { addSymChain ($2); }
1447 end_block {$$ = createBlock($2,$4) ; }
1448 | error ';' { $$ = NULL ; }
1454 /* if this is typedef declare it immediately */
1455 if ( $1 && IS_TYPEDEF($1->etype)) {
1456 allocVariables ($1);
1461 ignoreTypedefType = 0;
1464 | declaration_list declaration
1468 /* if this is a typedef */
1469 if ($2 && IS_TYPEDEF($2->etype)) {
1470 allocVariables ($2);
1474 /* get to the end of the previous decl */
1484 ignoreTypedefType = 0;
1490 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1493 expression_statement
1495 | expr ';' { $$ = $1; seqPointNo++;}
1499 : ELSE statement { $$ = $2 ; }
1505 : IF '(' expr ')' { seqPointNo++;} statement else_statement
1508 $$ = createIf ($3, $6, $7 );
1511 | SWITCH '(' expr ')' {
1513 static int swLabel = 0 ;
1516 /* create a node for expression */
1517 ex = newNode(SWITCH,$3,NULL);
1518 STACK_PUSH(swStk,ex); /* save it in the stack */
1519 ex->values.switchVals.swNum = swLabel ;
1521 /* now create the label */
1522 SNPRINTF(lbuff, sizeof(lbuff),
1523 "_swBrk_%d",swLabel++);
1524 $<sym>$ = newSymbol(lbuff,NestLevel);
1525 /* put label in the break stack */
1526 STACK_PUSH(breakStack,$<sym>$);
1529 /* get back the switch form the stack */
1530 $$ = STACK_POP(swStk) ;
1531 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1532 STACK_POP(breakStack);
1536 while : WHILE { /* create and push the continue , break & body labels */
1537 static int Lblnum = 0 ;
1539 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1540 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1542 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1543 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1545 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1546 $$ = newSymbol(lbuff,NestLevel);
1550 do : DO { /* create and push the continue , break & body Labels */
1551 static int Lblnum = 0 ;
1554 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1555 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1557 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1558 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1560 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1561 $$ = newSymbol (lbuff,NestLevel);
1565 for : FOR { /* create & push continue, break & body labels */
1566 static int Lblnum = 0 ;
1569 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1570 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1572 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1573 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1575 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1576 $$ = newSymbol(lbuff,NestLevel);
1578 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1579 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1584 : while '(' expr ')' { seqPointNo++;} statement
1587 $$ = createWhile ( $1, STACK_POP(continueStack),
1588 STACK_POP(breakStack), $3, $6 );
1589 $$->lineno = $1->lineDef ;
1592 | do statement WHILE '(' expr ')' ';'
1596 $$ = createDo ( $1 , STACK_POP(continueStack),
1597 STACK_POP(breakStack), $5, $2);
1598 $$->lineno = $1->lineDef ;
1601 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1605 /* if break or continue statement present
1606 then create a general case loop */
1607 if (STACK_PEEK(continueStack)->isref ||
1608 STACK_PEEK(breakStack)->isref) {
1609 $$ = createFor ($1, STACK_POP(continueStack),
1610 STACK_POP(breakStack) ,
1611 STACK_POP(forStack) ,
1614 $$ = newNode(FOR,$9,NULL);
1615 AST_FOR($$,trueLabel) = $1;
1616 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1617 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1618 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1619 AST_FOR($$,initExpr) = $3;
1620 AST_FOR($$,condExpr) = $5;
1621 AST_FOR($$,loopExpr) = $7;
1629 : { $$ = NULL ; seqPointNo++; }
1630 | expr { $$ = $1 ; seqPointNo++; }
1634 : GOTO identifier ';' {
1636 $$ = newAst_VALUE(symbolVal($2));
1637 $$ = newNode(GOTO,$$,NULL);
1640 /* make sure continue is in context */
1641 if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1642 werror(E_BREAK_CONTEXT);
1646 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1647 $$ = newNode(GOTO,$$,NULL);
1648 /* mark the continue label as referenced */
1649 STACK_PEEK(continueStack)->isref = 1;
1653 if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1654 werror(E_BREAK_CONTEXT);
1657 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1658 $$ = newNode(GOTO,$$,NULL);
1659 STACK_PEEK(breakStack)->isref = 1;
1665 werror(E_INVALID_CRITICAL);
1668 $$ = newNode(RETURN,NULL,NULL);
1674 werror(E_INVALID_CRITICAL);
1677 $$ = newNode(RETURN,NULL,$2);
1683 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }