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 */
52 char lbuff[1024]; /* local buffer */
54 /* break & continue stacks */
55 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
56 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
57 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
58 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
59 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
61 value *cenum = NULL ; /* current enumeration type chain*/
62 bool uselessDecl = TRUE;
68 symbol *sym ; /* symbol table pointer */
69 structdef *sdef; /* structure definition */
70 char yychar[SDCC_NAME_MAX+1];
71 sym_link *lnk ; /* declarator or specifier */
72 int yyint; /* integer value returned */
73 value *val ; /* for integer constant */
74 initList *ilist; /* initial list */
75 const char *yyinline; /* inlined assembler code */
76 ast *asts; /* expression tree */
79 %token <yychar> IDENTIFIER TYPE_NAME
80 %token <val> CONSTANT STRING_LITERAL
82 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
84 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
85 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
86 %token <yyint> XOR_ASSIGN OR_ASSIGN
87 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
88 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
89 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
90 %token STRUCT UNION ENUM ELIPSIS RANGE FAR
91 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
92 %token NAKED JAVANATIVE OVERLAY
93 %token <yyinline> INLINEASM
94 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
95 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
97 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
98 %token DUMMY_READ_VOLATILE ENDCRITICAL SWAP
100 %type <yyint> Interrupt_storage
101 %type <sym> identifier declarator declarator2 declarator3 enumerator_list enumerator
102 %type <sym> struct_declarator function_declarator function_declarator2
103 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
104 %type <sym> declaration init_declarator_list init_declarator
105 %type <sym> declaration_list identifier_list parameter_identifier_list
106 %type <sym> declarator2_function_attributes while do for critical
107 %type <lnk> pointer type_specifier_list type_specifier type_name
108 %type <lnk> storage_class_specifier struct_or_union_specifier
109 %type <lnk> declaration_specifiers sfr_reg_bit sfr_attributes type_specifier2
110 %type <lnk> function_attribute function_attributes enum_specifier
111 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
112 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
113 %type <sdef> stag opt_stag
114 %type <asts> primary_expr
115 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
116 %type <asts> additive_expr shift_expr relational_expr equality_expr
117 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
118 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
119 %type <asts> expr argument_expr_list function_definition expr_opt
120 %type <asts> statement_list statement labeled_statement compound_statement
121 %type <asts> expression_statement selection_statement iteration_statement
122 %type <asts> jump_statement function_body else_statement string_literal
123 %type <asts> critical_statement
124 %type <ilist> initializer initializer_list
125 %type <yyint> unary_operator assignment_operator struct_or_union
132 : external_definition
133 | file external_definition
137 : function_definition {
142 && IS_FUNC($1->type))
144 /* The only legal storage classes for
145 * a function prototype (declaration)
146 * are extern and static. extern is the
147 * default. Thus, if this function isn't
148 * explicitly marked static, mark it
152 && IS_SPEC($1->etype)
153 && !SPEC_STAT($1->etype))
155 SPEC_EXTR($1->etype) = 1;
159 allocVariables ($1) ;
160 cleanUpLevel (SymbolTab,1);
165 : function_declarator function_body { /* function type not specified */
166 /* assume it to be 'int' */
167 addDecl($1,0,newIntLink());
168 $$ = createFunction($1,$2);
170 | declaration_specifiers function_declarator function_body
172 pointerTypes($2->type,copyLinkChain($1));
174 $$ = createFunction($2,$3);
179 : function_attributes
180 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
185 $$ = newLink(SPECIFIER) ;
186 FUNC_REGBANK($$) = (int) floatFromVal($2);
188 | REENTRANT { $$ = newLink (SPECIFIER);
191 | CRITICAL { $$ = newLink (SPECIFIER);
192 FUNC_ISCRITICAL($$) = 1;
194 | NAKED { $$ = newLink (SPECIFIER);
197 | JAVANATIVE { $$ = newLink (SPECIFIER);
198 FUNC_ISJAVANATIVE($$)=1;
200 | OVERLAY { $$ = newLink (SPECIFIER);
201 FUNC_ISOVERLAY($$)=1;
203 | NONBANKED {$$ = newLink (SPECIFIER);
204 FUNC_NONBANKED($$) = 1;
205 if (FUNC_BANKED($$)) {
206 werror(W_BANKED_WITH_NONBANKED);
209 | BANKED {$$ = newLink (SPECIFIER);
211 if (FUNC_NONBANKED($$)) {
212 werror(W_BANKED_WITH_NONBANKED);
215 werror(W_BANKED_WITH_STATIC);
220 $$ = newLink (SPECIFIER) ;
221 FUNC_INTNO($$) = $1 ;
228 | declaration_list compound_statement
230 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
236 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
237 | CONSTANT { $$ = newAst_VALUE($1); }
239 | '(' expr ')' { $$ = $2 ; }
243 : STRING_LITERAL { $$ = newAst_VALUE($1); }
248 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
249 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
250 $$->left->funcName = 1;}
251 | postfix_expr '(' argument_expr_list ')'
253 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
255 | postfix_expr '.' identifier
257 $3 = newSymbol($3->name,NestLevel);
259 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
260 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
262 | postfix_expr PTR_OP identifier
264 $3 = newSymbol($3->name,NestLevel);
266 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
268 | postfix_expr INC_OP
269 { $$ = newNode(INC_OP,$1,NULL);}
270 | postfix_expr DEC_OP
271 { $$ = newNode(DEC_OP,$1,NULL); }
276 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
281 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
282 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
283 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
284 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
285 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
286 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
300 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
305 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
306 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
307 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
311 : multiplicative_expr
312 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
313 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
318 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
319 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
324 | relational_expr '<' shift_expr {
326 newNode('!',newNode(GE_OP,$1,$3),NULL) :
327 newNode('<', $1,$3));
329 | relational_expr '>' shift_expr {
331 newNode('!',newNode(LE_OP,$1,$3),NULL) :
334 | relational_expr LE_OP shift_expr {
336 newNode('!', newNode('>', $1 , $3 ), NULL) :
337 newNode(LE_OP,$1,$3));
339 | relational_expr GE_OP shift_expr {
341 newNode('!', newNode('<', $1 , $3 ), NULL) :
342 newNode(GE_OP,$1,$3));
348 | equality_expr EQ_OP relational_expr {
350 newNode('!',newNode(NE_OP,$1,$3),NULL) :
351 newNode(EQ_OP,$1,$3));
353 | equality_expr NE_OP relational_expr {
355 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
356 newNode(NE_OP,$1,$3));
362 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
367 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
372 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
377 | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expr
378 { $$ = newNode(AND_OP,$1,$4);}
383 | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr
384 { $$ = newNode(OR_OP,$1,$4); }
389 | logical_or_expr '?' { seqPointNo++;} logical_or_expr ':' conditional_expr
391 $$ = newNode(':',$4,$6) ;
392 $$ = newNode('?',$1,$$) ;
398 | unary_expr assignment_operator assignment_expr
403 $$ = newNode($2,$1,$3);
406 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
407 newNode('*',removePreIncDecOps(copyAst($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(LEFT_OP,removePreIncDecOps(copyAst($1)),$3));
430 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
431 newNode(RIGHT_OP,removePreIncDecOps(copyAst($1)),$3));
434 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
435 newNode('&',removePreIncDecOps(copyAst($1)),$3));
438 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
439 newNode('^',removePreIncDecOps(copyAst($1)),$3));
442 /* $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); */
443 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
444 newNode('|',removePreIncDecOps(copyAst($1)),$3));
469 | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);}
477 : declaration_specifiers ';'
480 werror(W_USELESS_DECL);
484 | declaration_specifiers init_declarator_list ';'
486 /* add the specifier list to the id */
489 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
490 sym_link *lnk = copyLinkChain($1);
491 /* do the pointer stuff */
492 pointerTypes(sym->type,lnk);
493 addDecl (sym,0,lnk) ;
501 declaration_specifiers
502 : storage_class_specifier { $$ = $1; }
503 | storage_class_specifier declaration_specifiers {
504 /* if the decl $2 is not a specifier */
505 /* find the spec and replace it */
508 while (lnk && !IS_SPEC(lnk->next))
510 lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
514 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
516 | type_specifier { $$ = $1; }
517 | type_specifier declaration_specifiers {
518 /* if the decl $2 is not a specifier */
519 /* find the spec and replace it */
522 while (lnk && !IS_SPEC(lnk->next))
524 lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
528 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
534 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
538 : declarator { $1->ival = NULL ; }
539 | declarator '=' initializer { $1->ival = $3 ; }
543 storage_class_specifier
545 $$ = newLink (SPECIFIER) ;
546 SPEC_TYPEDEF($$) = 1 ;
549 $$ = newLink(SPECIFIER);
553 $$ = newLink (SPECIFIER);
557 $$ = newLink (SPECIFIER) ;
558 SPEC_SCLS($$) = S_AUTO ;
561 $$ = newLink (SPECIFIER);
562 SPEC_SCLS($$) = S_REGISTER ;
567 : INTERRUPT { $$ = INTNO_UNSPEC ; }
569 { int intno = (int) floatFromVal($2);
570 if ((intno >= 0) && (intno <= INTNO_MAX))
574 werror(E_INT_BAD_INTNO, intno);
582 | type_specifier2 AT constant_expr
584 /* add this to the storage class specifier */
585 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
586 /* now get the abs addr from value */
587 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
593 $$=newLink(SPECIFIER);
594 SPEC_NOUN($$) = V_CHAR ;
597 $$=newLink(SPECIFIER);
598 $$->select.s._short = 1 ;
601 $$=newLink(SPECIFIER);
602 SPEC_NOUN($$) = V_INT ;
605 $$=newLink(SPECIFIER);
609 $$=newLink(SPECIFIER);
610 $$->select.s._signed = 1;
613 $$=newLink(SPECIFIER);
617 $$=newLink(SPECIFIER);
618 SPEC_NOUN($$) = V_VOID ;
621 $$=newLink(SPECIFIER);
625 $$=newLink(SPECIFIER);
626 SPEC_VOLATILE($$) = 1 ;
629 $$=newLink(SPECIFIER);
630 SPEC_NOUN($$) = V_FLOAT;
633 $$ = newLink (SPECIFIER);
634 SPEC_SCLS($$) = S_XDATA ;
637 $$ = newLink (SPECIFIER) ;
638 SPEC_SCLS($$) = S_CODE ;
641 $$ = newLink (SPECIFIER) ;
642 SPEC_SCLS($$) = S_EEPROM ;
645 $$ = newLink (SPECIFIER);
646 SPEC_SCLS($$) = S_DATA ;
649 $$ = newLink (SPECIFIER);
650 SPEC_SCLS($$) = S_IDATA ;
653 $$ = newLink (SPECIFIER);
654 SPEC_SCLS($$) = S_PDATA ;
657 $$=newLink(SPECIFIER);
658 SPEC_NOUN($$) = V_BIT ;
659 SPEC_SCLS($$) = S_BIT ;
664 | struct_or_union_specifier {
677 sym = findSym(TypedefTab,NULL,$1) ;
678 $$ = p = copyLinkChain(sym->type);
679 SPEC_TYPEDEF(getSpec(p)) = 0;
686 $$ = newLink(SPECIFIER) ;
687 SPEC_NOUN($$) = V_SBIT;
688 SPEC_SCLS($$) = S_SBIT;
695 $$ = newLink(SPECIFIER) ;
696 FUNC_REGBANK($$) = 0;
697 SPEC_NOUN($$) = V_CHAR;
698 SPEC_SCLS($$) = S_SFR ;
702 $$ = newLink(SPECIFIER) ;
703 FUNC_REGBANK($$) = 1;
704 SPEC_NOUN($$) = V_CHAR;
705 SPEC_SCLS($$) = S_SFR ;
710 struct_or_union_specifier
711 : struct_or_union opt_stag '{' struct_declaration_list '}'
716 // check for errors in structure members
717 for (sym=$4; sym; sym=sym->next) {
718 if (IS_ABSOLUTE(sym->etype)) {
719 werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "'at'");
720 SPEC_ABSA(sym->etype) = 0;
722 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
723 werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "storage class");
724 SPEC_SCLS(sym->etype) = 0;
726 for (dsym=sym->next; dsym; dsym=dsym->next) {
727 if (strcmp(sym->name, dsym->name)==0) {
728 werrorfl(filename, sym->lineDef, E_DUPLICATE_MEMBER,
729 $1==STRUCT ? "struct" : "union", sym->name);
734 /* Create a structdef */
736 sdef->fields = reverseSyms($4) ; /* link the fields */
737 sdef->size = compStructSize($1,sdef); /* update size of */
739 /* Create the specifier */
740 $$ = newLink (SPECIFIER) ;
741 SPEC_NOUN($$) = V_STRUCT;
742 SPEC_STRUCT($$)= sdef ;
744 | struct_or_union stag
746 $$ = newLink(SPECIFIER) ;
747 SPEC_NOUN($$) = V_STRUCT;
748 SPEC_STRUCT($$) = $2 ;
753 : STRUCT { $$ = STRUCT ; }
754 | UNION { $$ = UNION ; }
759 | { /* synthesize a name add to structtable */
760 $$ = newStruct(genSymName(NestLevel)) ;
761 $$->level = NestLevel ;
762 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
766 : identifier { /* add name to structure table */
767 $$ = findSymWithBlock (StructTab,$1,currBlockno);
769 $$ = newStruct($1->name) ;
770 $$->level = NestLevel ;
771 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
776 struct_declaration_list
778 | struct_declaration_list struct_declaration
782 /* go to the end of the chain */
783 while (sym->next) sym=sym->next;
791 : type_specifier_list struct_declarator_list ';'
793 /* add this type to all the symbols */
795 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
796 sym_link *btype = copyLinkChain($1);
798 /* make the symbol one level up */
801 pointerTypes(sym->type,btype);
804 sym->etype = getSpec(sym->type);
807 addDecl (sym,0,btype);
808 /* make sure the type is complete and sane */
809 checkTypeSanity(sym->etype, sym->name);
815 struct_declarator_list
817 | struct_declarator_list ',' struct_declarator
826 | ':' constant_expr {
828 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
829 bitsize= (int) floatFromVal(constExprValue($2,TRUE));
830 if (bitsize > (port->s.int_size * 8)) {
831 bitsize = port->s.int_size * 8;
832 werror(E_BITFLD_SIZE, bitsize);
835 bitsize = BITVAR_PAD;
836 $$->bitVar = bitsize;
838 | declarator ':' constant_expr
841 bitsize= (int) floatFromVal(constExprValue($3,TRUE));
842 if (bitsize > (port->s.int_size * 8)) {
843 bitsize = port->s.int_size * 8;
844 werror(E_BITFLD_SIZE, bitsize);
847 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
848 $$->bitVar = BITVAR_PAD;
849 werror(W_BITFLD_NAMED);
852 $1->bitVar = bitsize;
857 : ENUM '{' enumerator_list '}' {
861 // check for duplicate enums
862 for (sym=$3; sym; sym=sym->next) {
863 for (dsym=sym->next; dsym; dsym=dsym->next) {
864 if (strcmp(sym->name, dsym->name)==0) {
865 werrorfl(filename, sym->lineDef, E_DUPLICATE_MEMBER, "enum", sym->name);
871 $$ = copyLinkChain(cenum->type);
878 | ENUM identifier '{' enumerator_list '}' {
881 $2->type = copyLinkChain(cenum->type);
882 $2->etype = getSpec($2->type);
883 /* add this to the enumerator table */
884 if (!(csym=findSym(enumTab,$2,$2->name)) &&
885 (csym && csym->level == $2->level))
886 werror(E_DUPLICATE_TYPEDEF,csym->name);
888 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
890 //allocVariables (reverseSyms($4));
891 $$ = copyLinkChain(cenum->type);
892 SPEC_SCLS(getSpec($$)) = 0 ;
897 /* check the enumerator table */
898 if ((csym = findSym(enumTab,$2,$2->name)))
899 $$ = copyLinkChain(csym->type);
901 $$ = newLink(SPECIFIER) ;
902 SPEC_NOUN($$) = V_INT ;
905 SPEC_SCLS(getSpec($$)) = 0 ;
911 | enumerator_list ',' {
913 | enumerator_list ',' enumerator {
920 : identifier opt_assign_expr
922 /* make the symbol one level up */
924 $1->type = copyLinkChain($2->type);
925 $1->etype= getSpec($1->type);
926 SPEC_ENUM($1->etype) = 1;
928 // do this now, so we can use it for the next enums in the list
934 : '=' constant_expr {
937 val = constExprValue($2,TRUE);
942 SNPRINTF(lbuff, sizeof(lbuff),
943 "%d",(int) floatFromVal(cenum)+1);
944 $$ = cenum = constVal(lbuff);
947 SNPRINTF(lbuff, sizeof(lbuff),
949 $$ = cenum = constVal(lbuff);
955 : declarator3 { $$ = $1 ; }
956 | pointer declarator3
958 addDecl ($2,0,reverseLink($1));
964 : declarator2_function_attributes { $$ = $1 ; }
965 | declarator2 { $$ = $1 ; }
969 : declarator2_function_attributes { $$ = $1; }
970 | pointer declarator2_function_attributes
972 addDecl ($2,0,reverseLink($1));
977 declarator2_function_attributes
978 : function_declarator2 { $$ = $1 ; }
979 | function_declarator2 function_attribute {
980 // copy the functionAttributes (not the args and hasVargs !!)
981 sym_link *funcType=$1->etype;
982 struct value *args=FUNC_ARGS(funcType);
983 unsigned hasVargs=FUNC_HASVARARGS(funcType);
985 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
986 sizeof($2->funcAttrs));
988 FUNC_ARGS(funcType)=args;
989 FUNC_HASVARARGS(funcType)=hasVargs;
992 memset (&$2->funcAttrs, 0,
993 sizeof($2->funcAttrs));
1001 | '(' declarator ')' { $$ = $2; }
1002 | declarator3 '[' ']'
1006 p = newLink (DECLARATOR);
1007 DCL_TYPE(p) = ARRAY ;
1011 | declarator3 '[' constant_expr ']'
1016 tval = constExprValue($3,TRUE);
1017 /* if it is not a constant then Error */
1018 p = newLink (DECLARATOR);
1019 DCL_TYPE(p) = ARRAY ;
1020 if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1021 werror(E_CONST_EXPECTED) ;
1022 /* Assume a single item array to limit the cascade */
1023 /* of additional errors. */
1027 DCL_ELEM(p) = (int) floatFromVal(tval) ;
1033 function_declarator2
1034 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
1035 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
1038 addDecl ($1,FUNCTION,NULL) ;
1040 FUNC_HASVARARGS($1->type) = IS_VARG($4);
1041 FUNC_ARGS($1->type) = reverseVal($4);
1043 /* nest level was incremented to take care of the parms */
1047 // if this was a pointer (to a function)
1048 if (IS_PTR($1->type)) {
1049 // move the args and hasVargs to the function
1050 FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
1051 FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
1052 memset (&$1->type->funcAttrs, 0,
1053 sizeof($1->type->funcAttrs));
1054 // remove the symbol args (if any)
1055 cleanUpLevel(SymbolTab,NestLevel+1);
1060 | declarator2 '(' parameter_identifier_list ')'
1062 werror(E_OLD_STYLE,$1->name) ;
1063 /* assume it returns an int */
1064 $1->type = $1->etype = newIntLink();
1070 : unqualified_pointer { $$ = $1 ;}
1071 | unqualified_pointer type_specifier_list
1076 DCL_PTR_CONST($1) = SPEC_CONST($2);
1077 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1080 werror (W_PTR_TYPE_INVALID);
1082 | unqualified_pointer pointer
1086 DCL_TYPE($2)=port->unqualified_pointer;
1088 | unqualified_pointer type_specifier_list pointer
1091 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1092 DCL_PTR_CONST($1) = SPEC_CONST($2);
1093 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1094 switch (SPEC_SCLS($2)) {
1096 DCL_TYPE($3) = FPOINTER;
1099 DCL_TYPE($3) = IPOINTER ;
1102 DCL_TYPE($3) = PPOINTER ;
1105 DCL_TYPE($3) = POINTER ;
1108 DCL_TYPE($3) = CPOINTER ;
1111 DCL_TYPE($3) = EEPPOINTER;
1114 // this could be just "constant"
1115 // werror(W_PTR_TYPE_INVALID);
1120 werror (W_PTR_TYPE_INVALID);
1128 $$ = newLink(DECLARATOR);
1129 DCL_TYPE($$)=UPOINTER;
1135 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1136 | type_specifier_list type_specifier {
1137 /* if the decl $2 is not a specifier */
1138 /* find the spec and replace it */
1139 if ( !IS_SPEC($2)) {
1140 sym_link *lnk = $2 ;
1141 while (lnk && !IS_SPEC(lnk->next))
1143 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1147 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1151 parameter_identifier_list
1153 | identifier_list ',' ELIPSIS
1158 | identifier_list ',' identifier
1167 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1171 : parameter_declaration
1172 | parameter_list ',' parameter_declaration
1179 parameter_declaration
1180 : type_specifier_list declarator
1183 pointerTypes($2->type,$1);
1185 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1192 $$->etype = getSpec($$->type);
1197 : type_specifier_list { $$ = $1 ;}
1198 | type_specifier_list abstract_declarator
1200 /* go to the end of the list */
1202 pointerTypes($2,$1);
1203 for ( p = $2 ; p && p->next ; p=p->next);
1205 werror(E_SYNTAX_ERROR, yytext);
1214 : pointer { $$ = reverseLink($1); }
1215 | abstract_declarator2
1216 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1217 if (IS_PTR($1) && IS_FUNC($2))
1218 DCL_TYPE($1) = CPOINTER;
1222 abstract_declarator2
1223 : '(' abstract_declarator ')' { $$ = $2 ; }
1225 $$ = newLink (DECLARATOR);
1226 DCL_TYPE($$) = ARRAY ;
1229 | '[' constant_expr ']' {
1231 $$ = newLink (DECLARATOR);
1232 DCL_TYPE($$) = ARRAY ;
1233 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1235 | abstract_declarator2 '[' ']' {
1236 $$ = newLink (DECLARATOR);
1237 DCL_TYPE($$) = ARRAY ;
1241 | abstract_declarator2 '[' constant_expr ']'
1244 $$ = newLink (DECLARATOR);
1245 DCL_TYPE($$) = ARRAY ;
1246 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1249 | '(' ')' { $$ = NULL;}
1250 | '(' parameter_type_list ')' { $$ = NULL;}
1251 | abstract_declarator2 '(' ')' {
1252 // $1 must be a pointer to a function
1253 sym_link *p=newLink(DECLARATOR);
1254 DCL_TYPE(p) = FUNCTION;
1256 // ((void (code *) ()) 0) ()
1257 $1=newLink(DECLARATOR);
1258 DCL_TYPE($1)=CPOINTER;
1263 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1264 sym_link *p=newLink(DECLARATOR);
1265 DCL_TYPE(p) = FUNCTION;
1267 FUNC_HASVARARGS(p) = IS_VARG($4);
1268 FUNC_ARGS(p) = reverseVal($4);
1270 /* nest level was incremented to take care of the parms */
1276 // remove the symbol args (if any)
1277 cleanUpLevel(SymbolTab,NestLevel+1);
1282 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1283 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1284 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1289 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1294 | compound_statement
1295 | expression_statement
1296 | selection_statement
1297 | iteration_statement
1299 | critical_statement
1303 ex = newNode(INLINEASM,NULL,NULL);
1304 ex->values.inlineasm = strdup($1);
1313 STACK_PUSH(continueStack,NULL);
1314 STACK_PUSH(breakStack,NULL);
1320 : critical statement {
1321 STACK_POP(breakStack);
1322 STACK_POP(continueStack);
1324 $$ = newNode(CRITICAL,$2,NULL);
1329 // : identifier ':' statement { $$ = createLabel($1,$3); }
1330 : identifier ':' { $$ = createLabel($1,NULL); }
1331 | CASE constant_expr ':' statement
1333 if (STACK_EMPTY(swStk))
1334 $$ = createCase(NULL,$2,$4);
1336 $$ = createCase(STACK_PEEK(swStk),$2,$4);
1338 | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':' statement
1340 if (STACK_EMPTY(swStk))
1341 $$ = createDefault(NULL,$<asts>2,$4);
1343 $$ = createDefault(STACK_PEEK(swStk),$<asts>2,$4);
1347 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1350 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1354 : start_block end_block { $$ = createBlock(NULL,NULL); }
1355 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1357 declaration_list { addSymChain($2); }
1358 end_block { $$ = createBlock($2,NULL) ; }
1360 declaration_list { addSymChain ($2); }
1362 end_block {$$ = createBlock($2,$4) ; }
1363 | error ';' { $$ = NULL ; }
1369 /* if this is typedef declare it immediately */
1370 if ( $1 && IS_TYPEDEF($1->etype)) {
1371 allocVariables ($1);
1378 | declaration_list declaration
1382 /* if this is a typedef */
1383 if ($2 && IS_TYPEDEF($2->etype)) {
1384 allocVariables ($2);
1388 /* get to the end of the previous decl */
1403 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1406 expression_statement
1408 | expr ';' { $$ = $1; seqPointNo++;}
1412 : ELSE statement { $$ = $2 ; }
1418 : IF '(' expr ')' { seqPointNo++;} statement else_statement
1421 $$ = createIf ($3, $6, $7 );
1424 | SWITCH '(' expr ')' {
1426 static int swLabel = 0 ;
1429 /* create a node for expression */
1430 ex = newNode(SWITCH,$3,NULL);
1431 STACK_PUSH(swStk,ex); /* save it in the stack */
1432 ex->values.switchVals.swNum = swLabel ;
1434 /* now create the label */
1435 SNPRINTF(lbuff, sizeof(lbuff),
1436 "_swBrk_%d",swLabel++);
1437 $<sym>$ = newSymbol(lbuff,NestLevel);
1438 /* put label in the break stack */
1439 STACK_PUSH(breakStack,$<sym>$);
1442 /* get back the switch form the stack */
1443 $$ = STACK_POP(swStk) ;
1444 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1445 STACK_POP(breakStack);
1449 while : WHILE { /* create and push the continue , break & body labels */
1450 static int Lblnum = 0 ;
1452 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1453 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1455 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1456 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1458 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1459 $$ = newSymbol(lbuff,NestLevel);
1463 do : DO { /* create and push the continue , break & body Labels */
1464 static int Lblnum = 0 ;
1467 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1468 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1470 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1471 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1473 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1474 $$ = newSymbol (lbuff,NestLevel);
1478 for : FOR { /* create & push continue, break & body labels */
1479 static int Lblnum = 0 ;
1482 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1483 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1485 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1486 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1488 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1489 $$ = newSymbol(lbuff,NestLevel);
1491 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1492 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1497 : while '(' expr ')' { seqPointNo++;} statement
1500 $$ = createWhile ( $1, STACK_POP(continueStack),
1501 STACK_POP(breakStack), $3, $6 );
1502 $$->lineno = $1->lineDef ;
1505 | do statement WHILE '(' expr ')' ';'
1509 $$ = createDo ( $1 , STACK_POP(continueStack),
1510 STACK_POP(breakStack), $5, $2);
1511 $$->lineno = $1->lineDef ;
1514 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1518 /* if break or continue statement present
1519 then create a general case loop */
1520 if (STACK_PEEK(continueStack)->isref ||
1521 STACK_PEEK(breakStack)->isref) {
1522 $$ = createFor ($1, STACK_POP(continueStack),
1523 STACK_POP(breakStack) ,
1524 STACK_POP(forStack) ,
1527 $$ = newNode(FOR,$9,NULL);
1528 AST_FOR($$,trueLabel) = $1;
1529 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1530 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1531 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1532 AST_FOR($$,initExpr) = $3;
1533 AST_FOR($$,condExpr) = $5;
1534 AST_FOR($$,loopExpr) = $7;
1542 : { $$ = NULL ; seqPointNo++; }
1543 | expr { $$ = $1 ; seqPointNo++; }
1547 : GOTO identifier ';' {
1549 $$ = newAst_VALUE(symbolVal($2));
1550 $$ = newNode(GOTO,$$,NULL);
1553 /* make sure continue is in context */
1554 if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1555 werror(E_BREAK_CONTEXT);
1559 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1560 $$ = newNode(GOTO,$$,NULL);
1561 /* mark the continue label as referenced */
1562 STACK_PEEK(continueStack)->isref = 1;
1566 if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1567 werror(E_BREAK_CONTEXT);
1570 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1571 $$ = newNode(GOTO,$$,NULL);
1572 STACK_PEEK(breakStack)->isref = 1;
1578 werror(E_INVALID_CRITICAL);
1581 $$ = newNode(RETURN,NULL,NULL);
1587 werror(E_INVALID_CRITICAL);
1590 $$ = newNode(RETURN,NULL,$2);
1596 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }