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 '{' struct_declaration_list '}'
735 // check for errors in structure members
736 for (sym=$4; sym; sym=sym->next) {
737 if (IS_ABSOLUTE(sym->etype)) {
738 werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "'at'");
739 SPEC_ABSA(sym->etype) = 0;
741 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
742 werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "storage class");
743 SPEC_SCLS(sym->etype) = 0;
745 for (dsym=sym->next; dsym; dsym=dsym->next) {
746 if (strcmp(sym->name, dsym->name)==0) {
747 werrorfl(filename, sym->lineDef, E_DUPLICATE_MEMBER,
748 $1==STRUCT ? "struct" : "union", sym->name);
753 /* Create a structdef */
755 sdef->fields = reverseSyms($4) ; /* link the fields */
756 sdef->size = compStructSize($1,sdef); /* update size of */
758 /* Create the specifier */
759 $$ = newLink (SPECIFIER) ;
760 SPEC_NOUN($$) = V_STRUCT;
761 SPEC_STRUCT($$)= sdef ;
763 | struct_or_union stag
765 $$ = newLink(SPECIFIER) ;
766 SPEC_NOUN($$) = V_STRUCT;
767 SPEC_STRUCT($$) = $2 ;
772 : STRUCT { $$ = STRUCT ; }
773 | UNION { $$ = UNION ; }
778 | { /* synthesize a name add to structtable */
779 $$ = newStruct(genSymName(NestLevel)) ;
780 $$->level = NestLevel ;
781 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
785 : identifier { /* add name to structure table */
786 $$ = findSymWithBlock (StructTab,$1,currBlockno);
788 $$ = newStruct($1->name) ;
789 $$->level = NestLevel ;
790 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
795 struct_declaration_list
797 | struct_declaration_list struct_declaration
801 /* go to the end of the chain */
802 while (sym->next) sym=sym->next;
810 : type_specifier_list struct_declarator_list ';'
812 /* add this type to all the symbols */
814 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
815 sym_link *btype = copyLinkChain($1);
817 /* make the symbol one level up */
820 pointerTypes(sym->type,btype);
823 sym->etype = getSpec(sym->type);
826 addDecl (sym,0,btype);
827 /* make sure the type is complete and sane */
828 checkTypeSanity(sym->etype, sym->name);
830 ignoreTypedefType = 0;
835 struct_declarator_list
837 | struct_declarator_list ',' struct_declarator
846 | ':' constant_expr {
848 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
849 bitsize= (int) floatFromVal(constExprValue($2,TRUE));
850 if (bitsize > (port->s.int_size * 8)) {
851 bitsize = port->s.int_size * 8;
852 werror(E_BITFLD_SIZE, bitsize);
855 bitsize = BITVAR_PAD;
856 $$->bitVar = bitsize;
858 | declarator ':' constant_expr
861 bitsize= (int) floatFromVal(constExprValue($3,TRUE));
862 if (bitsize > (port->s.int_size * 8)) {
863 bitsize = port->s.int_size * 8;
864 werror(E_BITFLD_SIZE, bitsize);
867 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
868 $$->bitVar = BITVAR_PAD;
869 werror(W_BITFLD_NAMED);
872 $1->bitVar = bitsize;
877 : ENUM '{' enumerator_list '}' {
881 // check for duplicate enums
882 for (sym=$3; sym; sym=sym->next) {
883 for (dsym=sym->next; dsym; dsym=dsym->next) {
884 if (strcmp(sym->name, dsym->name)==0) {
885 werrorfl(filename, sym->lineDef, E_DUPLICATE_MEMBER, "enum", sym->name);
891 $$ = copyLinkChain(cenum->type);
898 | ENUM identifier '{' enumerator_list '}' {
901 $2->type = copyLinkChain(cenum->type);
902 $2->etype = getSpec($2->type);
903 /* add this to the enumerator table */
904 if (!(csym=findSym(enumTab,$2,$2->name)) &&
905 (csym && csym->level == $2->level))
906 werror(E_DUPLICATE_TYPEDEF,csym->name);
908 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
910 //allocVariables (reverseSyms($4));
911 $$ = copyLinkChain(cenum->type);
912 SPEC_SCLS(getSpec($$)) = 0 ;
917 /* check the enumerator table */
918 if ((csym = findSym(enumTab,$2,$2->name)))
919 $$ = copyLinkChain(csym->type);
921 $$ = newLink(SPECIFIER) ;
922 SPEC_NOUN($$) = V_INT ;
925 SPEC_SCLS(getSpec($$)) = 0 ;
931 | enumerator_list ',' {
933 | enumerator_list ',' enumerator {
940 : identifier opt_assign_expr
942 /* make the symbol one level up */
944 $1->type = copyLinkChain($2->type);
945 $1->etype= getSpec($1->type);
946 SPEC_ENUM($1->etype) = 1;
948 // do this now, so we can use it for the next enums in the list
954 : '=' constant_expr {
957 val = constExprValue($2,TRUE);
962 SNPRINTF(lbuff, sizeof(lbuff),
963 "%d",(int) floatFromVal(cenum)+1);
964 $$ = cenum = constVal(lbuff);
967 SNPRINTF(lbuff, sizeof(lbuff),
969 $$ = cenum = constVal(lbuff);
975 : declarator3 { $$ = $1 ; }
976 | pointer declarator3
978 addDecl ($2,0,reverseLink($1));
984 : declarator2_function_attributes { $$ = $1 ; }
985 | declarator2 { $$ = $1 ; }
989 : declarator2_function_attributes { $$ = $1; }
990 | pointer declarator2_function_attributes
992 addDecl ($2,0,reverseLink($1));
997 declarator2_function_attributes
998 : function_declarator2 { $$ = $1 ; }
999 | function_declarator2 function_attribute {
1000 // copy the functionAttributes (not the args and hasVargs !!)
1001 sym_link *funcType=$1->etype;
1002 struct value *args=FUNC_ARGS(funcType);
1003 unsigned hasVargs=FUNC_HASVARARGS(funcType);
1005 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
1006 sizeof($2->funcAttrs));
1008 FUNC_ARGS(funcType)=args;
1009 FUNC_HASVARARGS(funcType)=hasVargs;
1012 memset (&$2->funcAttrs, 0,
1013 sizeof($2->funcAttrs));
1021 | '(' declarator ')' { $$ = $2; }
1022 | declarator3 '[' ']'
1026 p = newLink (DECLARATOR);
1027 DCL_TYPE(p) = ARRAY ;
1031 | declarator3 '[' constant_expr ']'
1036 tval = constExprValue($3,TRUE);
1037 /* if it is not a constant then Error */
1038 p = newLink (DECLARATOR);
1039 DCL_TYPE(p) = ARRAY ;
1040 if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1041 werror(E_CONST_EXPECTED) ;
1042 /* Assume a single item array to limit the cascade */
1043 /* of additional errors. */
1047 DCL_ELEM(p) = (int) floatFromVal(tval) ;
1053 function_declarator2
1054 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
1055 | declarator2 '(' { NestLevel++ ; currBlockno++; }
1056 parameter_type_list ')'
1059 addDecl ($1,FUNCTION,NULL) ;
1061 FUNC_HASVARARGS($1->type) = IS_VARG($4);
1062 FUNC_ARGS($1->type) = reverseVal($4);
1064 /* nest level was incremented to take care of the parms */
1068 // if this was a pointer (to a function)
1069 if (IS_PTR($1->type)) {
1070 // move the args and hasVargs to the function
1071 FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
1072 FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
1073 memset (&$1->type->funcAttrs, 0,
1074 sizeof($1->type->funcAttrs));
1075 // remove the symbol args (if any)
1076 cleanUpLevel(SymbolTab,NestLevel+1);
1081 | declarator2 '(' parameter_identifier_list ')'
1083 werror(E_OLD_STYLE,$1->name) ;
1084 /* assume it returns an int */
1085 $1->type = $1->etype = newIntLink();
1091 : unqualified_pointer { $$ = $1 ;}
1092 | unqualified_pointer type_specifier_list
1097 DCL_PTR_CONST($1) = SPEC_CONST($2);
1098 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1101 werror (W_PTR_TYPE_INVALID);
1103 | unqualified_pointer pointer
1107 DCL_TYPE($2)=port->unqualified_pointer;
1109 | unqualified_pointer type_specifier_list pointer
1112 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1113 DCL_PTR_CONST($1) = SPEC_CONST($2);
1114 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1115 switch (SPEC_SCLS($2)) {
1117 DCL_TYPE($3) = FPOINTER;
1120 DCL_TYPE($3) = IPOINTER ;
1123 DCL_TYPE($3) = PPOINTER ;
1126 DCL_TYPE($3) = POINTER ;
1129 DCL_TYPE($3) = CPOINTER ;
1132 DCL_TYPE($3) = EEPPOINTER;
1135 // this could be just "constant"
1136 // werror(W_PTR_TYPE_INVALID);
1141 werror (W_PTR_TYPE_INVALID);
1149 $$ = newLink(DECLARATOR);
1150 DCL_TYPE($$)=UPOINTER;
1156 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1157 | type_specifier_list type_specifier {
1158 /* if the decl $2 is not a specifier */
1159 /* find the spec and replace it */
1160 if ( !IS_SPEC($2)) {
1161 sym_link *lnk = $2 ;
1162 while (lnk && !IS_SPEC(lnk->next))
1164 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1168 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1172 parameter_identifier_list
1174 | identifier_list ',' ELIPSIS
1179 | identifier_list ',' identifier
1188 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1192 : parameter_declaration
1193 | parameter_list ',' parameter_declaration
1200 parameter_declaration
1201 : type_specifier_list declarator
1204 pointerTypes($2->type,$1);
1206 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1209 ignoreTypedefType = 0;
1214 $$->etype = getSpec($$->type);
1215 ignoreTypedefType = 0;
1220 : type_specifier_list { $$ = $1; ignoreTypedefType = 0;}
1221 | type_specifier_list abstract_declarator
1223 /* go to the end of the list */
1225 pointerTypes($2,$1);
1226 for ( p = $2 ; p && p->next ; p=p->next);
1228 werror(E_SYNTAX_ERROR, yytext);
1233 ignoreTypedefType = 0;
1238 : pointer { $$ = reverseLink($1); }
1239 | abstract_declarator2
1240 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1241 if (IS_PTR($1) && IS_FUNC($2))
1242 DCL_TYPE($1) = CPOINTER;
1246 abstract_declarator2
1247 : '(' abstract_declarator ')' { $$ = $2 ; }
1249 $$ = newLink (DECLARATOR);
1250 DCL_TYPE($$) = ARRAY ;
1253 | '[' constant_expr ']' {
1255 $$ = newLink (DECLARATOR);
1256 DCL_TYPE($$) = ARRAY ;
1257 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1259 | abstract_declarator2 '[' ']' {
1260 $$ = newLink (DECLARATOR);
1261 DCL_TYPE($$) = ARRAY ;
1265 | abstract_declarator2 '[' constant_expr ']'
1268 $$ = newLink (DECLARATOR);
1269 DCL_TYPE($$) = ARRAY ;
1270 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1273 | '(' ')' { $$ = NULL;}
1274 | '(' parameter_type_list ')' { $$ = NULL;}
1275 | abstract_declarator2 '(' ')' {
1276 // $1 must be a pointer to a function
1277 sym_link *p=newLink(DECLARATOR);
1278 DCL_TYPE(p) = FUNCTION;
1280 // ((void (code *) ()) 0) ()
1281 $1=newLink(DECLARATOR);
1282 DCL_TYPE($1)=CPOINTER;
1287 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1288 sym_link *p=newLink(DECLARATOR);
1289 DCL_TYPE(p) = FUNCTION;
1291 FUNC_HASVARARGS(p) = IS_VARG($4);
1292 FUNC_ARGS(p) = reverseVal($4);
1294 /* nest level was incremented to take care of the parms */
1300 // remove the symbol args (if any)
1301 cleanUpLevel(SymbolTab,NestLevel+1);
1306 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1307 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1308 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1313 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1318 | compound_statement
1319 | expression_statement
1320 | selection_statement
1321 | iteration_statement
1323 | critical_statement
1327 ex = newNode(INLINEASM,NULL,NULL);
1328 ex->values.inlineasm = strdup($1);
1337 STACK_PUSH(continueStack,NULL);
1338 STACK_PUSH(breakStack,NULL);
1344 : critical statement {
1345 STACK_POP(breakStack);
1346 STACK_POP(continueStack);
1348 $$ = newNode(CRITICAL,$2,NULL);
1353 // : identifier ':' statement { $$ = createLabel($1,$3); }
1354 : identifier ':' { $$ = createLabel($1,NULL); }
1355 | CASE constant_expr ':' statement
1357 if (STACK_EMPTY(swStk))
1358 $$ = createCase(NULL,$2,$4);
1360 $$ = createCase(STACK_PEEK(swStk),$2,$4);
1362 | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':' statement
1364 if (STACK_EMPTY(swStk))
1365 $$ = createDefault(NULL,$<asts>2,$4);
1367 $$ = createDefault(STACK_PEEK(swStk),$<asts>2,$4);
1373 STACK_PUSH(blockNum,currBlockno);
1374 currBlockno = ++blockNo ;
1375 ignoreTypedefType = 0;
1379 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1383 : start_block end_block { $$ = createBlock(NULL,NULL); }
1384 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1386 declaration_list { addSymChain($2); }
1387 end_block { $$ = createBlock($2,NULL) ; }
1389 declaration_list { addSymChain ($2); }
1391 end_block {$$ = createBlock($2,$4) ; }
1392 | error ';' { $$ = NULL ; }
1398 /* if this is typedef declare it immediately */
1399 if ( $1 && IS_TYPEDEF($1->etype)) {
1400 allocVariables ($1);
1405 ignoreTypedefType = 0;
1408 | declaration_list declaration
1412 /* if this is a typedef */
1413 if ($2 && IS_TYPEDEF($2->etype)) {
1414 allocVariables ($2);
1418 /* get to the end of the previous decl */
1428 ignoreTypedefType = 0;
1434 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1437 expression_statement
1439 | expr ';' { $$ = $1; seqPointNo++;}
1443 : ELSE statement { $$ = $2 ; }
1449 : IF '(' expr ')' { seqPointNo++;} statement else_statement
1452 $$ = createIf ($3, $6, $7 );
1455 | SWITCH '(' expr ')' {
1457 static int swLabel = 0 ;
1460 /* create a node for expression */
1461 ex = newNode(SWITCH,$3,NULL);
1462 STACK_PUSH(swStk,ex); /* save it in the stack */
1463 ex->values.switchVals.swNum = swLabel ;
1465 /* now create the label */
1466 SNPRINTF(lbuff, sizeof(lbuff),
1467 "_swBrk_%d",swLabel++);
1468 $<sym>$ = newSymbol(lbuff,NestLevel);
1469 /* put label in the break stack */
1470 STACK_PUSH(breakStack,$<sym>$);
1473 /* get back the switch form the stack */
1474 $$ = STACK_POP(swStk) ;
1475 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1476 STACK_POP(breakStack);
1480 while : WHILE { /* create and push the continue , break & body labels */
1481 static int Lblnum = 0 ;
1483 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1484 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1486 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1487 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1489 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1490 $$ = newSymbol(lbuff,NestLevel);
1494 do : DO { /* create and push the continue , break & body Labels */
1495 static int Lblnum = 0 ;
1498 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1499 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1501 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1502 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1504 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1505 $$ = newSymbol (lbuff,NestLevel);
1509 for : FOR { /* create & push continue, break & body labels */
1510 static int Lblnum = 0 ;
1513 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1514 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1516 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1517 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1519 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1520 $$ = newSymbol(lbuff,NestLevel);
1522 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1523 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1528 : while '(' expr ')' { seqPointNo++;} statement
1531 $$ = createWhile ( $1, STACK_POP(continueStack),
1532 STACK_POP(breakStack), $3, $6 );
1533 $$->lineno = $1->lineDef ;
1536 | do statement WHILE '(' expr ')' ';'
1540 $$ = createDo ( $1 , STACK_POP(continueStack),
1541 STACK_POP(breakStack), $5, $2);
1542 $$->lineno = $1->lineDef ;
1545 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1549 /* if break or continue statement present
1550 then create a general case loop */
1551 if (STACK_PEEK(continueStack)->isref ||
1552 STACK_PEEK(breakStack)->isref) {
1553 $$ = createFor ($1, STACK_POP(continueStack),
1554 STACK_POP(breakStack) ,
1555 STACK_POP(forStack) ,
1558 $$ = newNode(FOR,$9,NULL);
1559 AST_FOR($$,trueLabel) = $1;
1560 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1561 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1562 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1563 AST_FOR($$,initExpr) = $3;
1564 AST_FOR($$,condExpr) = $5;
1565 AST_FOR($$,loopExpr) = $7;
1573 : { $$ = NULL ; seqPointNo++; }
1574 | expr { $$ = $1 ; seqPointNo++; }
1578 : GOTO identifier ';' {
1580 $$ = newAst_VALUE(symbolVal($2));
1581 $$ = newNode(GOTO,$$,NULL);
1584 /* make sure continue is in context */
1585 if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1586 werror(E_BREAK_CONTEXT);
1590 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1591 $$ = newNode(GOTO,$$,NULL);
1592 /* mark the continue label as referenced */
1593 STACK_PEEK(continueStack)->isref = 1;
1597 if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1598 werror(E_BREAK_CONTEXT);
1601 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1602 $$ = newNode(GOTO,$$,NULL);
1603 STACK_PEEK(breakStack)->isref = 1;
1609 werror(E_INVALID_CRITICAL);
1612 $$ = newNode(RETURN,NULL,NULL);
1618 werror(E_INVALID_CRITICAL);
1621 $$ = newNode(RETURN,NULL,$2);
1627 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }