1 /*-----------------------------------------------------------------------
3 SDCC.y - parser definition file for sdcc :
4 Written By : Sandeep Dutta . sandeep.dutta@usa.net (1997)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
28 #include "SDCCglobl.h"
30 #include "SDCChasht.h"
39 extern int yyerror (char *);
41 int NestLevel = 0 ; /* current NestLevel */
42 int stackPtr = 1 ; /* stack pointer */
43 int xstackPtr = 0 ; /* xstack pointer */
45 int blockNo = 0 ; /* sequential block number */
48 int seqPointNo= 1 ; /* sequence point number */
49 int ignoreTypedefType=0;
53 char lbuff[1024]; /* local buffer */
55 /* break & continue stacks */
56 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
57 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
58 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
59 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
60 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
62 value *cenum = NULL ; /* current enumeration type chain*/
63 bool uselessDecl = TRUE;
71 symbol *sym ; /* symbol table pointer */
72 structdef *sdef; /* structure definition */
73 char yychar[SDCC_NAME_MAX+1];
74 sym_link *lnk ; /* declarator or specifier */
75 int yyint; /* integer value returned */
76 value *val ; /* for integer constant */
77 initList *ilist; /* initial list */
78 const char *yyinline; /* inlined assembler code */
79 ast *asts; /* expression tree */
82 %token <yychar> IDENTIFIER TYPE_NAME
83 %token <val> CONSTANT STRING_LITERAL
85 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
87 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
88 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
89 %token <yyint> XOR_ASSIGN OR_ASSIGN
90 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
91 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
92 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
93 %token STRUCT UNION ENUM ELIPSIS RANGE FAR
94 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
95 %token NAKED JAVANATIVE OVERLAY
96 %token <yyinline> INLINEASM
97 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
98 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
100 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
101 %token DUMMY_READ_VOLATILE ENDCRITICAL SWAP
103 %type <yyint> Interrupt_storage
104 %type <sym> identifier declarator declarator2 declarator3 enumerator_list enumerator
105 %type <sym> struct_declarator function_declarator function_declarator2
106 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
107 %type <sym> declaration init_declarator_list init_declarator
108 %type <sym> declaration_list identifier_list parameter_identifier_list
109 %type <sym> declarator2_function_attributes while do for critical
110 %type <lnk> pointer type_specifier_list type_specifier type_name
111 %type <lnk> storage_class_specifier struct_or_union_specifier
112 %type <lnk> declaration_specifiers sfr_reg_bit sfr_attributes type_specifier2
113 %type <lnk> function_attribute function_attributes enum_specifier
114 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
115 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
116 %type <sdef> stag opt_stag
117 %type <asts> primary_expr
118 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
119 %type <asts> additive_expr shift_expr relational_expr equality_expr
120 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
121 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
122 %type <asts> expr argument_expr_list function_definition expr_opt
123 %type <asts> statement_list statement labeled_statement compound_statement
124 %type <asts> expression_statement selection_statement iteration_statement
125 %type <asts> jump_statement function_body else_statement string_literal
126 %type <asts> critical_statement
127 %type <ilist> initializer initializer_list
128 %type <yyint> unary_operator assignment_operator struct_or_union
135 : external_definition
136 | file external_definition
140 : function_definition {
144 ignoreTypedefType = 0;
146 && IS_FUNC($1->type))
148 /* The only legal storage classes for
149 * a function prototype (declaration)
150 * are extern and static. extern is the
151 * default. Thus, if this function isn't
152 * explicitly marked static, mark it
156 && IS_SPEC($1->etype)
157 && !SPEC_STAT($1->etype))
159 SPEC_EXTR($1->etype) = 1;
163 allocVariables ($1) ;
164 cleanUpLevel (SymbolTab,1);
169 : function_declarator function_body { /* function type not specified */
170 /* assume it to be 'int' */
171 addDecl($1,0,newIntLink());
172 $$ = createFunction($1,$2);
174 | declaration_specifiers function_declarator function_body
176 pointerTypes($2->type,copyLinkChain($1));
178 $$ = createFunction($2,$3);
183 : function_attributes
184 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
189 $$ = newLink(SPECIFIER) ;
190 FUNC_REGBANK($$) = (int) floatFromVal($2);
192 | REENTRANT { $$ = newLink (SPECIFIER);
195 | CRITICAL { $$ = newLink (SPECIFIER);
196 FUNC_ISCRITICAL($$) = 1;
198 | NAKED { $$ = newLink (SPECIFIER);
201 | JAVANATIVE { $$ = newLink (SPECIFIER);
202 FUNC_ISJAVANATIVE($$)=1;
204 | OVERLAY { $$ = newLink (SPECIFIER);
205 FUNC_ISOVERLAY($$)=1;
207 | NONBANKED {$$ = newLink (SPECIFIER);
208 FUNC_NONBANKED($$) = 1;
209 if (FUNC_BANKED($$)) {
210 werror(W_BANKED_WITH_NONBANKED);
213 | BANKED {$$ = newLink (SPECIFIER);
215 if (FUNC_NONBANKED($$)) {
216 werror(W_BANKED_WITH_NONBANKED);
219 werror(W_BANKED_WITH_STATIC);
224 $$ = newLink (SPECIFIER) ;
225 FUNC_INTNO($$) = $1 ;
232 | declaration_list compound_statement
234 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
240 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
241 | CONSTANT { $$ = newAst_VALUE($1); }
243 | '(' expr ')' { $$ = $2 ; }
247 : STRING_LITERAL { $$ = newAst_VALUE($1); }
252 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
253 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
254 $$->left->funcName = 1;}
255 | postfix_expr '(' argument_expr_list ')'
257 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
259 | postfix_expr '.' identifier
261 $3 = newSymbol($3->name,NestLevel);
263 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
264 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
266 | postfix_expr PTR_OP identifier
268 $3 = newSymbol($3->name,NestLevel);
270 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
272 | postfix_expr INC_OP
273 { $$ = newNode(INC_OP,$1,NULL);}
274 | postfix_expr DEC_OP
275 { $$ = newNode(DEC_OP,$1,NULL); }
280 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
285 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
286 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
287 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
288 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
289 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
290 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
304 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
309 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
310 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
311 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
315 : multiplicative_expr
316 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
317 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
322 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
323 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
328 | relational_expr '<' shift_expr {
330 newNode('!',newNode(GE_OP,$1,$3),NULL) :
331 newNode('<', $1,$3));
333 | relational_expr '>' shift_expr {
335 newNode('!',newNode(LE_OP,$1,$3),NULL) :
338 | relational_expr LE_OP shift_expr {
340 newNode('!', newNode('>', $1 , $3 ), NULL) :
341 newNode(LE_OP,$1,$3));
343 | relational_expr GE_OP shift_expr {
345 newNode('!', newNode('<', $1 , $3 ), NULL) :
346 newNode(GE_OP,$1,$3));
352 | equality_expr EQ_OP relational_expr {
354 newNode('!',newNode(NE_OP,$1,$3),NULL) :
355 newNode(EQ_OP,$1,$3));
357 | equality_expr NE_OP relational_expr {
359 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
360 newNode(NE_OP,$1,$3));
366 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
371 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
376 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
381 | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expr
382 { $$ = newNode(AND_OP,$1,$4);}
387 | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr
388 { $$ = newNode(OR_OP,$1,$4); }
393 | logical_or_expr '?' { seqPointNo++;} logical_or_expr ':' conditional_expr
395 $$ = newNode(':',$4,$6) ;
396 $$ = newNode('?',$1,$$) ;
402 | unary_expr assignment_operator assignment_expr
407 $$ = newNode($2,$1,$3);
410 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
411 newNode('*',removePreIncDecOps(copyAst($1)),$3));
414 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
415 newNode('/',removePreIncDecOps(copyAst($1)),$3));
418 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
419 newNode('%',removePreIncDecOps(copyAst($1)),$3));
422 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
423 newNode('+',removePreIncDecOps(copyAst($1)),$3));
426 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
427 newNode('-',removePreIncDecOps(copyAst($1)),$3));
430 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
431 newNode(LEFT_OP,removePreIncDecOps(copyAst($1)),$3));
434 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
435 newNode(RIGHT_OP,removePreIncDecOps(copyAst($1)),$3));
438 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
439 newNode('&',removePreIncDecOps(copyAst($1)),$3));
442 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
443 newNode('^',removePreIncDecOps(copyAst($1)),$3));
446 /* $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); */
447 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
448 newNode('|',removePreIncDecOps(copyAst($1)),$3));
473 | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);}
481 : declaration_specifiers ';'
484 werror(W_USELESS_DECL);
488 | declaration_specifiers init_declarator_list ';'
490 /* add the specifier list to the id */
493 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
494 sym_link *lnk = copyLinkChain($1);
495 /* do the pointer stuff */
496 pointerTypes(sym->type,lnk);
497 addDecl (sym,0,lnk) ;
505 declaration_specifiers
506 : storage_class_specifier { $$ = $1; }
507 | storage_class_specifier declaration_specifiers {
508 /* if the decl $2 is not a specifier */
509 /* find the spec and replace it */
512 while (lnk && !IS_SPEC(lnk->next))
514 lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
518 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
520 | type_specifier { $$ = $1; }
521 | type_specifier declaration_specifiers {
522 /* if the decl $2 is not a specifier */
523 /* find the spec and replace it */
526 while (lnk && !IS_SPEC(lnk->next))
528 lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
532 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
538 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
542 : declarator { $1->ival = NULL ; }
543 | declarator '=' initializer { $1->ival = $3 ; }
547 storage_class_specifier
549 $$ = newLink (SPECIFIER) ;
550 SPEC_TYPEDEF($$) = 1 ;
553 $$ = newLink(SPECIFIER);
557 $$ = newLink (SPECIFIER);
561 $$ = newLink (SPECIFIER) ;
562 SPEC_SCLS($$) = S_AUTO ;
565 $$ = newLink (SPECIFIER);
566 SPEC_SCLS($$) = S_REGISTER ;
571 : INTERRUPT { $$ = INTNO_UNSPEC ; }
573 { int intno = (int) floatFromVal($2);
574 if ((intno >= 0) && (intno <= INTNO_MAX))
578 werror(E_INT_BAD_INTNO, intno);
586 | type_specifier2 AT constant_expr
588 /* add this to the storage class specifier */
589 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
590 /* now get the abs addr from value */
591 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
597 $$=newLink(SPECIFIER);
598 SPEC_NOUN($$) = V_CHAR ;
599 ignoreTypedefType = 1;
602 $$=newLink(SPECIFIER);
603 $$->select.s._short = 1 ;
604 ignoreTypedefType = 1;
607 $$=newLink(SPECIFIER);
608 SPEC_NOUN($$) = V_INT ;
609 ignoreTypedefType = 1;
612 $$=newLink(SPECIFIER);
614 ignoreTypedefType = 1;
617 $$=newLink(SPECIFIER);
618 $$->select.s._signed = 1;
619 ignoreTypedefType = 1;
622 $$=newLink(SPECIFIER);
624 ignoreTypedefType = 1;
627 $$=newLink(SPECIFIER);
628 SPEC_NOUN($$) = V_VOID ;
629 ignoreTypedefType = 1;
632 $$=newLink(SPECIFIER);
636 $$=newLink(SPECIFIER);
637 SPEC_VOLATILE($$) = 1 ;
640 $$=newLink(SPECIFIER);
641 SPEC_NOUN($$) = V_FLOAT;
642 ignoreTypedefType = 1;
645 $$ = newLink (SPECIFIER);
646 SPEC_SCLS($$) = S_XDATA ;
649 $$ = newLink (SPECIFIER) ;
650 SPEC_SCLS($$) = S_CODE ;
653 $$ = newLink (SPECIFIER) ;
654 SPEC_SCLS($$) = S_EEPROM ;
657 $$ = newLink (SPECIFIER);
658 SPEC_SCLS($$) = S_DATA ;
661 $$ = newLink (SPECIFIER);
662 SPEC_SCLS($$) = S_IDATA ;
665 $$ = newLink (SPECIFIER);
666 SPEC_SCLS($$) = S_PDATA ;
669 $$=newLink(SPECIFIER);
670 SPEC_NOUN($$) = V_BIT ;
671 SPEC_SCLS($$) = S_BIT ;
674 ignoreTypedefType = 1;
677 | struct_or_union_specifier {
680 ignoreTypedefType = 1;
685 ignoreTypedefType = 1;
692 sym = findSym(TypedefTab,NULL,$1) ;
693 $$ = p = copyLinkChain(sym->type);
694 SPEC_TYPEDEF(getSpec(p)) = 0;
695 ignoreTypedefType = 1;
702 $$ = newLink(SPECIFIER) ;
703 SPEC_NOUN($$) = V_SBIT;
704 SPEC_SCLS($$) = S_SBIT;
705 ignoreTypedefType = 1;
712 $$ = newLink(SPECIFIER) ;
713 FUNC_REGBANK($$) = 0;
714 SPEC_NOUN($$) = V_CHAR;
715 SPEC_SCLS($$) = S_SFR ;
717 ignoreTypedefType = 1;
720 $$ = newLink(SPECIFIER) ;
721 FUNC_REGBANK($$) = 1;
722 SPEC_NOUN($$) = V_CHAR;
723 SPEC_SCLS($$) = S_SFR ;
725 ignoreTypedefType = 1;
729 struct_or_union_specifier
730 : struct_or_union opt_stag
739 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
743 '{' struct_declaration_list '}'
748 // check for errors in structure members
749 for (sym=$5; sym; sym=sym->next) {
750 if (IS_ABSOLUTE(sym->etype)) {
751 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'");
752 SPEC_ABSA(sym->etype) = 0;
754 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
755 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class");
756 printTypeChainRaw (sym->type,NULL);
757 SPEC_SCLS(sym->etype) = 0;
759 for (dsym=sym->next; dsym; dsym=dsym->next) {
760 if (*dsym->name && strcmp(sym->name, dsym->name)==0) {
761 werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER,
762 $1==STRUCT ? "struct" : "union", sym->name);
763 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
768 /* Create a structdef */
770 sdef->fields = reverseSyms($5) ; /* link the fields */
771 sdef->size = compStructSize($1,sdef); /* update size of */
772 promoteAnonStructs ($1, sdef);
774 /* Create the specifier */
775 $$ = newLink (SPECIFIER) ;
776 SPEC_NOUN($$) = V_STRUCT;
777 SPEC_STRUCT($$)= sdef ;
779 | struct_or_union stag
781 $$ = newLink(SPECIFIER) ;
782 SPEC_NOUN($$) = V_STRUCT;
783 SPEC_STRUCT($$) = $2;
792 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
798 : STRUCT { $$ = STRUCT ; }
799 | UNION { $$ = UNION ; }
804 | { /* synthesize a name add to structtable */
805 $$ = newStruct(genSymName(NestLevel)) ;
806 $$->level = NestLevel ;
807 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
811 : identifier { /* add name to structure table */
812 $$ = findSymWithBlock (StructTab,$1,currBlockno);
814 $$ = newStruct($1->name) ;
815 $$->level = NestLevel ;
816 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
821 struct_declaration_list
823 | struct_declaration_list struct_declaration
827 /* go to the end of the chain */
828 while (sym->next) sym=sym->next;
836 : type_specifier_list struct_declarator_list ';'
838 /* add this type to all the symbols */
840 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
841 sym_link *btype = copyLinkChain($1);
843 /* make the symbol one level up */
846 pointerTypes(sym->type,btype);
849 sym->etype = getSpec(sym->type);
852 addDecl (sym,0,btype);
853 /* make sure the type is complete and sane */
854 checkTypeSanity(sym->etype, sym->name);
856 ignoreTypedefType = 0;
861 struct_declarator_list
863 | struct_declarator_list ',' struct_declarator
872 | ':' constant_expr {
874 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
875 bitsize= (int) floatFromVal(constExprValue($2,TRUE));
876 if (bitsize > (port->s.int_size * 8)) {
877 bitsize = port->s.int_size * 8;
878 werror(E_BITFLD_SIZE, bitsize);
881 bitsize = BITVAR_PAD;
882 $$->bitVar = bitsize;
884 | declarator ':' constant_expr
887 bitsize= (int) floatFromVal(constExprValue($3,TRUE));
888 if (bitsize > (port->s.int_size * 8)) {
889 bitsize = port->s.int_size * 8;
890 werror(E_BITFLD_SIZE, bitsize);
893 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
894 $$->bitVar = BITVAR_PAD;
895 werror(W_BITFLD_NAMED);
898 $1->bitVar = bitsize;
900 | { $$ = newSymbol ("", NestLevel) ; }
905 : ENUM '{' enumerator_list '}' {
906 $$ = newEnumType ($3); //copyLinkChain(cenum->type);
907 SPEC_SCLS(getSpec($$)) = 0;
910 | ENUM identifier '{' enumerator_list '}' {
914 csym=findSym(enumTab,$2,$2->name);
915 if ((csym && csym->level == $2->level))
917 werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
918 werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF);
921 enumtype = newEnumType ($4); //copyLinkChain(cenum->type);
922 SPEC_SCLS(getSpec(enumtype)) = 0;
925 /* add this to the enumerator table */
927 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
928 $$ = copyLinkChain(enumtype);
933 /* check the enumerator table */
934 if ((csym = findSym(enumTab,$2,$2->name)))
935 $$ = copyLinkChain(csym->type);
937 $$ = newLink(SPECIFIER) ;
938 SPEC_NOUN($$) = V_INT ;
945 | enumerator_list ',' {
947 | enumerator_list ',' enumerator
951 for (dsym=$1; dsym; dsym=dsym->next)
953 if (strcmp($3->name, dsym->name)==0)
955 werrorfl($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
956 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF);
966 : identifier opt_assign_expr
968 /* make the symbol one level up */
970 $1->type = copyLinkChain($2->type);
971 $1->etype= getSpec($1->type);
972 SPEC_ENUM($1->etype) = 1;
974 // do this now, so we can use it for the next enums in the list
980 : '=' constant_expr {
983 val = constExprValue($2,TRUE);
984 if (!IS_INT(val->type) && !IS_CHAR(val->type))
986 werror(E_ENUM_NON_INTEGER);
987 SNPRINTF(lbuff, sizeof(lbuff),
988 "%d",(int) floatFromVal(val));
989 val = constVal(lbuff);
995 SNPRINTF(lbuff, sizeof(lbuff),
996 "%d",(int) floatFromVal(cenum)+1);
997 $$ = cenum = constVal(lbuff);
1000 SNPRINTF(lbuff, sizeof(lbuff),
1002 $$ = cenum = constVal(lbuff);
1008 : declarator3 { $$ = $1 ; }
1009 | pointer declarator3
1011 addDecl ($2,0,reverseLink($1));
1017 : declarator2_function_attributes { $$ = $1 ; }
1018 | declarator2 { $$ = $1 ; }
1022 : declarator2_function_attributes { $$ = $1; }
1023 | pointer declarator2_function_attributes
1025 addDecl ($2,0,reverseLink($1));
1030 declarator2_function_attributes
1031 : function_declarator2 { $$ = $1 ; }
1032 | function_declarator2 function_attribute {
1033 // copy the functionAttributes (not the args and hasVargs !!)
1036 sym_link *funcType=$1->type;
1038 while (funcType && !IS_FUNC(funcType))
1039 funcType = funcType->next;
1042 werror (E_FUNC_ATTR);
1045 args=FUNC_ARGS(funcType);
1046 hasVargs=FUNC_HASVARARGS(funcType);
1048 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
1049 sizeof($2->funcAttrs));
1051 FUNC_ARGS(funcType)=args;
1052 FUNC_HASVARARGS(funcType)=hasVargs;
1055 memset (&$2->funcAttrs, 0,
1056 sizeof($2->funcAttrs));
1065 | '(' declarator ')' { $$ = $2; }
1066 | declarator3 '[' ']'
1070 p = newLink (DECLARATOR);
1071 DCL_TYPE(p) = ARRAY ;
1075 | declarator3 '[' constant_expr ']'
1080 tval = constExprValue($3,TRUE);
1081 /* if it is not a constant then Error */
1082 p = newLink (DECLARATOR);
1083 DCL_TYPE(p) = ARRAY ;
1084 if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1085 werror(E_CONST_EXPECTED) ;
1086 /* Assume a single item array to limit the cascade */
1087 /* of additional errors. */
1091 DCL_ELEM(p) = (int) floatFromVal(tval) ;
1097 function_declarator2
1098 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
1099 | declarator2 '(' { NestLevel++ ; currBlockno++; }
1100 parameter_type_list ')'
1104 addDecl ($1,FUNCTION,NULL) ;
1106 funcType = $1->type;
1107 while (funcType && !IS_FUNC(funcType))
1108 funcType = funcType->next;
1112 FUNC_HASVARARGS(funcType) = IS_VARG($4);
1113 FUNC_ARGS(funcType) = reverseVal($4);
1115 /* nest level was incremented to take care of the parms */
1119 // if this was a pointer (to a function)
1120 if (!IS_FUNC($1->type))
1121 cleanUpLevel(SymbolTab,NestLevel+1);
1125 | declarator2 '(' parameter_identifier_list ')'
1127 werror(E_OLD_STYLE,$1->name) ;
1128 /* assume it returns an int */
1129 $1->type = $1->etype = newIntLink();
1135 : unqualified_pointer { $$ = $1 ;}
1136 | unqualified_pointer type_specifier_list
1141 DCL_PTR_CONST($1) = SPEC_CONST($2);
1142 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1145 werror (W_PTR_TYPE_INVALID);
1147 | unqualified_pointer pointer
1151 DCL_TYPE($2)=port->unqualified_pointer;
1153 | unqualified_pointer type_specifier_list pointer
1156 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1157 DCL_PTR_CONST($1) = SPEC_CONST($2);
1158 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1159 switch (SPEC_SCLS($2)) {
1161 DCL_TYPE($3) = FPOINTER;
1164 DCL_TYPE($3) = IPOINTER ;
1167 DCL_TYPE($3) = PPOINTER ;
1170 DCL_TYPE($3) = POINTER ;
1173 DCL_TYPE($3) = CPOINTER ;
1176 DCL_TYPE($3) = EEPPOINTER;
1179 // this could be just "constant"
1180 // werror(W_PTR_TYPE_INVALID);
1185 werror (W_PTR_TYPE_INVALID);
1193 $$ = newLink(DECLARATOR);
1194 DCL_TYPE($$)=UPOINTER;
1200 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1201 | type_specifier_list type_specifier {
1202 /* if the decl $2 is not a specifier */
1203 /* find the spec and replace it */
1204 if ( !IS_SPEC($2)) {
1205 sym_link *lnk = $2 ;
1206 while (lnk && !IS_SPEC(lnk->next))
1208 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1212 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1216 parameter_identifier_list
1218 | identifier_list ',' ELIPSIS
1223 | identifier_list ',' identifier
1232 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1236 : parameter_declaration
1237 | parameter_list ',' parameter_declaration
1244 parameter_declaration
1245 : type_specifier_list declarator
1248 pointerTypes($2->type,$1);
1250 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1253 ignoreTypedefType = 0;
1258 $$->etype = getSpec($$->type);
1259 ignoreTypedefType = 0;
1264 : type_specifier_list { $$ = $1; ignoreTypedefType = 0;}
1265 | type_specifier_list abstract_declarator
1267 /* go to the end of the list */
1269 pointerTypes($2,$1);
1270 for ( p = $2 ; p && p->next ; p=p->next);
1272 werror(E_SYNTAX_ERROR, yytext);
1277 ignoreTypedefType = 0;
1282 : pointer { $$ = reverseLink($1); }
1283 | abstract_declarator2
1284 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1285 if (IS_PTR($1) && IS_FUNC($2))
1286 DCL_TYPE($1) = CPOINTER;
1290 abstract_declarator2
1291 : '(' abstract_declarator ')' { $$ = $2 ; }
1293 $$ = newLink (DECLARATOR);
1294 DCL_TYPE($$) = ARRAY ;
1297 | '[' constant_expr ']' {
1299 $$ = newLink (DECLARATOR);
1300 DCL_TYPE($$) = ARRAY ;
1301 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1303 | abstract_declarator2 '[' ']' {
1304 $$ = newLink (DECLARATOR);
1305 DCL_TYPE($$) = ARRAY ;
1309 | abstract_declarator2 '[' constant_expr ']'
1312 $$ = newLink (DECLARATOR);
1313 DCL_TYPE($$) = ARRAY ;
1314 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1317 | '(' ')' { $$ = NULL;}
1318 | '(' parameter_type_list ')' { $$ = NULL;}
1319 | abstract_declarator2 '(' ')' {
1320 // $1 must be a pointer to a function
1321 sym_link *p=newLink(DECLARATOR);
1322 DCL_TYPE(p) = FUNCTION;
1324 // ((void (code *) ()) 0) ()
1325 $1=newLink(DECLARATOR);
1326 DCL_TYPE($1)=CPOINTER;
1331 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1332 sym_link *p=newLink(DECLARATOR);
1333 DCL_TYPE(p) = FUNCTION;
1335 FUNC_HASVARARGS(p) = IS_VARG($4);
1336 FUNC_ARGS(p) = reverseVal($4);
1338 /* nest level was incremented to take care of the parms */
1344 // remove the symbol args (if any)
1345 cleanUpLevel(SymbolTab,NestLevel+1);
1350 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1351 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1352 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1357 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1362 | compound_statement
1363 | expression_statement
1364 | selection_statement
1365 | iteration_statement
1367 | critical_statement
1371 ex = newNode(INLINEASM,NULL,NULL);
1372 ex->values.inlineasm = strdup($1);
1381 STACK_PUSH(continueStack,NULL);
1382 STACK_PUSH(breakStack,NULL);
1388 : critical statement {
1389 STACK_POP(breakStack);
1390 STACK_POP(continueStack);
1392 $$ = newNode(CRITICAL,$2,NULL);
1397 // : identifier ':' statement { $$ = createLabel($1,$3); }
1398 : identifier ':' { $$ = createLabel($1,NULL); }
1399 | CASE constant_expr ':' statement
1401 if (STACK_EMPTY(swStk))
1402 $$ = createCase(NULL,$2,$4);
1404 $$ = createCase(STACK_PEEK(swStk),$2,$4);
1406 | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':' statement
1408 if (STACK_EMPTY(swStk))
1409 $$ = createDefault(NULL,$<asts>2,$4);
1411 $$ = createDefault(STACK_PEEK(swStk),$<asts>2,$4);
1417 STACK_PUSH(blockNum,currBlockno);
1418 currBlockno = ++blockNo ;
1419 ignoreTypedefType = 0;
1423 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1427 : start_block end_block { $$ = createBlock(NULL,NULL); }
1428 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1430 declaration_list { addSymChain($2); }
1431 end_block { $$ = createBlock($2,NULL) ; }
1433 declaration_list { addSymChain ($2); }
1435 end_block {$$ = createBlock($2,$4) ; }
1436 | error ';' { $$ = NULL ; }
1442 /* if this is typedef declare it immediately */
1443 if ( $1 && IS_TYPEDEF($1->etype)) {
1444 allocVariables ($1);
1449 ignoreTypedefType = 0;
1452 | declaration_list declaration
1456 /* if this is a typedef */
1457 if ($2 && IS_TYPEDEF($2->etype)) {
1458 allocVariables ($2);
1462 /* get to the end of the previous decl */
1472 ignoreTypedefType = 0;
1478 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1481 expression_statement
1483 | expr ';' { $$ = $1; seqPointNo++;}
1487 : ELSE statement { $$ = $2 ; }
1493 : IF '(' expr ')' { seqPointNo++;} statement else_statement
1496 $$ = createIf ($3, $6, $7 );
1499 | SWITCH '(' expr ')' {
1501 static int swLabel = 0 ;
1504 /* create a node for expression */
1505 ex = newNode(SWITCH,$3,NULL);
1506 STACK_PUSH(swStk,ex); /* save it in the stack */
1507 ex->values.switchVals.swNum = swLabel ;
1509 /* now create the label */
1510 SNPRINTF(lbuff, sizeof(lbuff),
1511 "_swBrk_%d",swLabel++);
1512 $<sym>$ = newSymbol(lbuff,NestLevel);
1513 /* put label in the break stack */
1514 STACK_PUSH(breakStack,$<sym>$);
1517 /* get back the switch form the stack */
1518 $$ = STACK_POP(swStk) ;
1519 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1520 STACK_POP(breakStack);
1524 while : WHILE { /* create and push the continue , break & body labels */
1525 static int Lblnum = 0 ;
1527 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1528 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1530 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1531 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1533 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1534 $$ = newSymbol(lbuff,NestLevel);
1538 do : DO { /* create and push the continue , break & body Labels */
1539 static int Lblnum = 0 ;
1542 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1543 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1545 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1546 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1548 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1549 $$ = newSymbol (lbuff,NestLevel);
1553 for : FOR { /* create & push continue, break & body labels */
1554 static int Lblnum = 0 ;
1557 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1558 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1560 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1561 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1563 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1564 $$ = newSymbol(lbuff,NestLevel);
1566 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1567 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1572 : while '(' expr ')' { seqPointNo++;} statement
1575 $$ = createWhile ( $1, STACK_POP(continueStack),
1576 STACK_POP(breakStack), $3, $6 );
1577 $$->lineno = $1->lineDef ;
1580 | do statement WHILE '(' expr ')' ';'
1584 $$ = createDo ( $1 , STACK_POP(continueStack),
1585 STACK_POP(breakStack), $5, $2);
1586 $$->lineno = $1->lineDef ;
1589 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1593 /* if break or continue statement present
1594 then create a general case loop */
1595 if (STACK_PEEK(continueStack)->isref ||
1596 STACK_PEEK(breakStack)->isref) {
1597 $$ = createFor ($1, STACK_POP(continueStack),
1598 STACK_POP(breakStack) ,
1599 STACK_POP(forStack) ,
1602 $$ = newNode(FOR,$9,NULL);
1603 AST_FOR($$,trueLabel) = $1;
1604 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1605 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1606 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1607 AST_FOR($$,initExpr) = $3;
1608 AST_FOR($$,condExpr) = $5;
1609 AST_FOR($$,loopExpr) = $7;
1617 : { $$ = NULL ; seqPointNo++; }
1618 | expr { $$ = $1 ; seqPointNo++; }
1622 : GOTO identifier ';' {
1624 $$ = newAst_VALUE(symbolVal($2));
1625 $$ = newNode(GOTO,$$,NULL);
1628 /* make sure continue is in context */
1629 if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1630 werror(E_BREAK_CONTEXT);
1634 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1635 $$ = newNode(GOTO,$$,NULL);
1636 /* mark the continue label as referenced */
1637 STACK_PEEK(continueStack)->isref = 1;
1641 if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1642 werror(E_BREAK_CONTEXT);
1645 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1646 $$ = newNode(GOTO,$$,NULL);
1647 STACK_PEEK(breakStack)->isref = 1;
1653 werror(E_INVALID_CRITICAL);
1656 $$ = newNode(RETURN,NULL,NULL);
1662 werror(E_INVALID_CRITICAL);
1665 $$ = newNode(RETURN,NULL,$2);
1671 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }