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 */
51 char lbuff[1024]; /* local buffer */
53 /* break & continue stacks */
54 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
55 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
56 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
57 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
58 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
60 value *cenum = NULL ; /* current enumeration type chain*/
61 bool uselessDecl = TRUE;
67 symbol *sym ; /* symbol table pointer */
68 structdef *sdef; /* structure definition */
69 char yychar[SDCC_NAME_MAX+1];
70 sym_link *lnk ; /* declarator or specifier */
71 int yyint; /* integer value returned */
72 value *val ; /* for integer constant */
73 initList *ilist; /* initial list */
74 const char *yyinline; /* inlined assembler code */
75 ast *asts; /* expression tree */
78 %token <yychar> IDENTIFIER TYPE_NAME
79 %token <val> CONSTANT STRING_LITERAL
81 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
83 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
84 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
85 %token <yyint> XOR_ASSIGN OR_ASSIGN
86 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
87 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
88 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
89 %token STRUCT UNION ENUM ELIPSIS RANGE FAR
90 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
91 %token NAKED JAVANATIVE OVERLAY
92 %token <yyinline> INLINEASM
93 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
94 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
96 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
97 %token DUMMY_READ_VOLATILE ENDCRITICAL SWAP
99 %type <yyint> Interrupt_storage
100 %type <sym> identifier declarator declarator2 declarator3 enumerator_list enumerator
101 %type <sym> struct_declarator function_declarator function_declarator2
102 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
103 %type <sym> declaration init_declarator_list init_declarator
104 %type <sym> declaration_list identifier_list parameter_identifier_list
105 %type <sym> declarator2_function_attributes while do for critical
106 %type <lnk> pointer type_specifier_list type_specifier type_name
107 %type <lnk> storage_class_specifier struct_or_union_specifier
108 %type <lnk> declaration_specifiers sfr_reg_bit sfr_attributes type_specifier2
109 %type <lnk> function_attribute function_attributes enum_specifier
110 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
111 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
112 %type <sdef> stag opt_stag
113 %type <asts> primary_expr
114 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
115 %type <asts> additive_expr shift_expr relational_expr equality_expr
116 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
117 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
118 %type <asts> expr argument_expr_list function_definition expr_opt
119 %type <asts> statement_list statement labeled_statement compound_statement
120 %type <asts> expression_statement selection_statement iteration_statement
121 %type <asts> jump_statement function_body else_statement string_literal
122 %type <asts> critical_statement
123 %type <ilist> initializer initializer_list
124 %type <yyint> unary_operator assignment_operator struct_or_union
131 : external_definition
132 | file external_definition
136 : function_definition {
141 && IS_FUNC($1->type))
143 /* The only legal storage classes for
144 * a function prototype (declaration)
145 * are extern and static. extern is the
146 * default. Thus, if this function isn't
147 * explicitly marked static, mark it
151 && IS_SPEC($1->etype)
152 && !SPEC_STAT($1->etype))
154 SPEC_EXTR($1->etype) = 1;
158 allocVariables ($1) ;
159 cleanUpLevel (SymbolTab,1);
164 : function_declarator function_body { /* function type not specified */
165 /* assume it to be 'int' */
166 addDecl($1,0,newIntLink());
167 $$ = createFunction($1,$2);
169 | declaration_specifiers function_declarator function_body
171 pointerTypes($2->type,copyLinkChain($1));
173 $$ = createFunction($2,$3);
178 : function_attributes
179 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
184 $$ = newLink(SPECIFIER) ;
185 FUNC_REGBANK($$) = (int) floatFromVal($2);
187 | REENTRANT { $$ = newLink (SPECIFIER);
190 | CRITICAL { $$ = newLink (SPECIFIER);
191 FUNC_ISCRITICAL($$) = 1;
193 | NAKED { $$ = newLink (SPECIFIER);
196 | JAVANATIVE { $$ = newLink (SPECIFIER);
197 FUNC_ISJAVANATIVE($$)=1;
199 | OVERLAY { $$ = newLink (SPECIFIER);
200 FUNC_ISOVERLAY($$)=1;
202 | NONBANKED {$$ = newLink (SPECIFIER);
203 FUNC_NONBANKED($$) = 1;
204 if (FUNC_BANKED($$)) {
205 werror(W_BANKED_WITH_NONBANKED);
208 | BANKED {$$ = newLink (SPECIFIER);
210 if (FUNC_NONBANKED($$)) {
211 werror(W_BANKED_WITH_NONBANKED);
214 werror(W_BANKED_WITH_STATIC);
219 $$ = newLink (SPECIFIER) ;
220 FUNC_INTNO($$) = $1 ;
227 | declaration_list compound_statement
229 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
230 fprintf(stderr, "case 1\n");
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 inclusive_or_expr
378 { $$ = newNode(AND_OP,$1,$3);}
383 | logical_or_expr OR_OP logical_and_expr
384 { $$ = newNode(OR_OP,$1,$3); }
389 | logical_or_expr '?' logical_or_expr ':' conditional_expr
391 $$ = newNode(':',$3,$5) ;
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 ',' assignment_expr { $$ = newNode(',',$1,$3);}
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 duplicate structure members
717 for (sym=$4; sym; sym=sym->next) {
718 for (dsym=sym->next; dsym; dsym=dsym->next) {
719 if (strcmp(sym->name, dsym->name)==0) {
720 werror(E_DUPLICATE_MEMBER,
721 $1==STRUCT ? "struct" : "union", sym->name);
726 /* Create a structdef */
728 sdef->fields = reverseSyms($4) ; /* link the fields */
729 sdef->size = compStructSize($1,sdef); /* update size of */
731 /* Create the specifier */
732 $$ = newLink (SPECIFIER) ;
733 SPEC_NOUN($$) = V_STRUCT;
734 SPEC_STRUCT($$)= sdef ;
736 | struct_or_union stag
738 $$ = newLink(SPECIFIER) ;
739 SPEC_NOUN($$) = V_STRUCT;
740 SPEC_STRUCT($$) = $2 ;
745 : STRUCT { $$ = STRUCT ; }
746 | UNION { $$ = UNION ; }
751 | { /* synthesize a name add to structtable */
752 $$ = newStruct(genSymName(NestLevel)) ;
753 $$->level = NestLevel ;
754 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
758 : identifier { /* add name to structure table */
759 $$ = findSymWithBlock (StructTab,$1,currBlockno);
761 $$ = newStruct($1->name) ;
762 $$->level = NestLevel ;
763 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
768 struct_declaration_list
770 | struct_declaration_list struct_declaration
774 /* go to the end of the chain */
775 while (sym->next) sym=sym->next;
783 : type_specifier_list struct_declarator_list ';'
785 /* add this type to all the symbols */
787 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
789 /* make the symbol one level up */
792 pointerTypes(sym->type,copyLinkChain($1));
794 sym->type = copyLinkChain($1);
795 sym->etype = getSpec(sym->type);
798 addDecl (sym,0,copyLinkChain($1));
799 /* make sure the type is complete and sane */
800 checkTypeSanity(sym->etype, sym->name);
806 struct_declarator_list
808 | struct_declarator_list ',' struct_declarator
817 | ':' constant_expr {
819 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
820 bitsize= (int) floatFromVal(constExprValue($2,TRUE));
821 if (bitsize > (port->s.int_size * 8)) {
822 bitsize = port->s.int_size * 8;
823 werror(E_BITFLD_SIZE, bitsize);
826 bitsize = BITVAR_PAD;
827 $$->bitVar = bitsize;
829 | declarator ':' constant_expr
832 bitsize= (int) floatFromVal(constExprValue($3,TRUE));
833 if (bitsize > (port->s.int_size * 8)) {
834 bitsize = port->s.int_size * 8;
835 werror(E_BITFLD_SIZE, bitsize);
838 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
839 $$->bitVar = BITVAR_PAD;
840 werror(W_BITFLD_NAMED);
843 $1->bitVar = bitsize;
848 : ENUM '{' enumerator_list '}' {
852 // check for duplicate enums
853 for (sym=$3; sym; sym=sym->next) {
854 for (dsym=sym->next; dsym; dsym=dsym->next) {
855 if (strcmp(sym->name, dsym->name)==0) {
856 werror(E_DUPLICATE_MEMBER, "enum", sym->name);
862 $$ = copyLinkChain(cenum->type);
869 | ENUM identifier '{' enumerator_list '}' {
872 $2->type = copyLinkChain(cenum->type);
873 $2->etype = getSpec($2->type);
874 /* add this to the enumerator table */
875 if (!(csym=findSym(enumTab,$2,$2->name)) &&
876 (csym && csym->level == $2->level))
877 werror(E_DUPLICATE_TYPEDEF,csym->name);
879 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
881 //allocVariables (reverseSyms($4));
882 $$ = copyLinkChain(cenum->type);
883 SPEC_SCLS(getSpec($$)) = 0 ;
888 /* check the enumerator table */
889 if ((csym = findSym(enumTab,$2,$2->name)))
890 $$ = copyLinkChain(csym->type);
892 $$ = newLink(SPECIFIER) ;
893 SPEC_NOUN($$) = V_INT ;
896 SPEC_SCLS(getSpec($$)) = 0 ;
902 | enumerator_list ',' {
904 | enumerator_list ',' enumerator {
911 : identifier opt_assign_expr
913 /* make the symbol one level up */
915 $1->type = copyLinkChain($2->type);
916 $1->etype= getSpec($1->type);
917 SPEC_ENUM($1->etype) = 1;
919 // do this now, so we can use it for the next enums in the list
925 : '=' constant_expr {
928 val = constExprValue($2,TRUE);
933 SNPRINTF(lbuff, sizeof(lbuff),
934 "%d",(int) floatFromVal(cenum)+1);
935 $$ = cenum = constVal(lbuff);
938 SNPRINTF(lbuff, sizeof(lbuff),
940 $$ = cenum = constVal(lbuff);
946 : declarator3 { $$ = $1 ; }
947 | pointer declarator3
949 addDecl ($2,0,reverseLink($1));
955 : declarator2_function_attributes { $$ = $1 ; }
956 | declarator2 { $$ = $1 ; }
960 : declarator2_function_attributes { $$ = $1; }
961 | pointer declarator2_function_attributes
963 addDecl ($2,0,reverseLink($1));
968 declarator2_function_attributes
969 : function_declarator2 { $$ = $1 ; }
970 | function_declarator2 function_attribute {
971 // copy the functionAttributes (not the args and hasVargs !!)
972 sym_link *funcType=$1->etype;
973 struct value *args=FUNC_ARGS(funcType);
974 unsigned hasVargs=FUNC_HASVARARGS(funcType);
976 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
977 sizeof($2->funcAttrs));
979 FUNC_ARGS(funcType)=args;
980 FUNC_HASVARARGS(funcType)=hasVargs;
983 memset (&$2->funcAttrs, 0,
984 sizeof($2->funcAttrs));
992 | '(' declarator ')' { $$ = $2; }
993 | declarator3 '[' ']'
997 p = newLink (DECLARATOR);
998 DCL_TYPE(p) = ARRAY ;
1002 | declarator3 '[' constant_expr ']'
1007 tval = constExprValue($3,TRUE);
1008 /* if it is not a constant then Error */
1009 p = newLink (DECLARATOR);
1010 DCL_TYPE(p) = ARRAY ;
1011 if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1012 werror(E_CONST_EXPECTED) ;
1013 /* Assume a single item array to limit the cascade */
1014 /* of additional errors. */
1018 DCL_ELEM(p) = (int) floatFromVal(tval) ;
1024 function_declarator2
1025 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
1026 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
1029 addDecl ($1,FUNCTION,NULL) ;
1031 FUNC_HASVARARGS($1->type) = IS_VARG($4);
1032 FUNC_ARGS($1->type) = reverseVal($4);
1034 /* nest level was incremented to take care of the parms */
1038 // if this was a pointer (to a function)
1039 if (IS_PTR($1->type)) {
1040 // move the args and hasVargs to the function
1041 FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
1042 FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
1043 memset (&$1->type->funcAttrs, 0,
1044 sizeof($1->type->funcAttrs));
1045 // remove the symbol args (if any)
1046 cleanUpLevel(SymbolTab,NestLevel+1);
1051 | declarator2 '(' parameter_identifier_list ')'
1053 werror(E_OLD_STYLE,$1->name) ;
1054 fprintf(stderr, "case 2\n");
1055 /* assume it returns an int */
1056 $1->type = $1->etype = newIntLink();
1062 : unqualified_pointer { $$ = $1 ;}
1063 | unqualified_pointer type_specifier_list
1068 DCL_PTR_CONST($1) = SPEC_CONST($2);
1069 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1072 werror (W_PTR_TYPE_INVALID);
1074 | unqualified_pointer pointer
1078 DCL_TYPE($2)=port->unqualified_pointer;
1080 | unqualified_pointer type_specifier_list pointer
1083 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1084 DCL_PTR_CONST($1) = SPEC_CONST($2);
1085 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1086 switch (SPEC_SCLS($2)) {
1088 DCL_TYPE($3) = FPOINTER;
1091 DCL_TYPE($3) = IPOINTER ;
1094 DCL_TYPE($3) = PPOINTER ;
1097 DCL_TYPE($3) = POINTER ;
1100 DCL_TYPE($3) = CPOINTER ;
1103 DCL_TYPE($3) = EEPPOINTER;
1106 // this could be just "constant"
1107 // werror(W_PTR_TYPE_INVALID);
1112 werror (W_PTR_TYPE_INVALID);
1120 $$ = newLink(DECLARATOR);
1121 DCL_TYPE($$)=UPOINTER;
1127 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1128 | type_specifier_list type_specifier {
1129 /* if the decl $2 is not a specifier */
1130 /* find the spec and replace it */
1131 if ( !IS_SPEC($2)) {
1132 sym_link *lnk = $2 ;
1133 while (lnk && !IS_SPEC(lnk->next))
1135 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1139 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1143 parameter_identifier_list
1145 | identifier_list ',' ELIPSIS
1150 | identifier_list ',' identifier
1159 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1163 : parameter_declaration
1164 | parameter_list ',' parameter_declaration
1171 parameter_declaration
1172 : type_specifier_list declarator
1175 pointerTypes($2->type,$1);
1177 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1184 $$->etype = getSpec($$->type);
1189 : type_specifier_list { $$ = $1 ;}
1190 | type_specifier_list abstract_declarator
1192 /* go to the end of the list */
1194 pointerTypes($2,$1);
1195 for ( p = $2 ; p && p->next ; p=p->next);
1197 werror(E_SYNTAX_ERROR, yytext);
1206 : pointer { $$ = reverseLink($1); }
1207 | abstract_declarator2
1208 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1209 if (IS_PTR($1) && IS_FUNC($2))
1210 DCL_TYPE($1) = CPOINTER;
1214 abstract_declarator2
1215 : '(' abstract_declarator ')' { $$ = $2 ; }
1217 $$ = newLink (DECLARATOR);
1218 DCL_TYPE($$) = ARRAY ;
1221 | '[' constant_expr ']' {
1223 $$ = newLink (DECLARATOR);
1224 DCL_TYPE($$) = ARRAY ;
1225 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1227 | abstract_declarator2 '[' ']' {
1228 $$ = newLink (DECLARATOR);
1229 DCL_TYPE($$) = ARRAY ;
1233 | abstract_declarator2 '[' constant_expr ']'
1236 $$ = newLink (DECLARATOR);
1237 DCL_TYPE($$) = ARRAY ;
1238 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1241 | '(' ')' { $$ = NULL;}
1242 | '(' parameter_type_list ')' { $$ = NULL;}
1243 | abstract_declarator2 '(' ')' {
1244 // $1 must be a pointer to a function
1245 sym_link *p=newLink(DECLARATOR);
1246 DCL_TYPE(p) = FUNCTION;
1248 // ((void (code *) ()) 0) ()
1249 $1=newLink(DECLARATOR);
1250 DCL_TYPE($1)=CPOINTER;
1255 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1256 sym_link *p=newLink(DECLARATOR);
1257 DCL_TYPE(p) = FUNCTION;
1259 FUNC_HASVARARGS(p) = IS_VARG($4);
1260 FUNC_ARGS(p) = reverseVal($4);
1262 /* nest level was incremented to take care of the parms */
1268 // remove the symbol args (if any)
1269 cleanUpLevel(SymbolTab,NestLevel+1);
1274 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1275 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1276 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1281 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1286 | compound_statement
1287 | expression_statement
1288 | selection_statement
1289 | iteration_statement
1291 | critical_statement
1293 ast *ex = newNode(INLINEASM,NULL,NULL);
1294 ex->values.inlineasm = strdup($1);
1302 STACK_PUSH(continueStack,NULL);
1303 STACK_PUSH(breakStack,NULL);
1309 : critical statement {
1310 STACK_POP(breakStack);
1311 STACK_POP(continueStack);
1313 $$ = newNode(CRITICAL,$2,NULL);
1318 // : identifier ':' statement { $$ = createLabel($1,$3); }
1319 : identifier ':' { $$ = createLabel($1,NULL); }
1320 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1321 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1324 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1327 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1331 : start_block end_block { $$ = createBlock(NULL,NULL); }
1332 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1334 declaration_list { addSymChain($2); }
1335 end_block { $$ = createBlock($2,NULL) ; }
1337 declaration_list { addSymChain ($2); }
1339 end_block {$$ = createBlock($2,$4) ; }
1340 | error ';' { $$ = NULL ; }
1346 /* if this is typedef declare it immediately */
1347 if ( $1 && IS_TYPEDEF($1->etype)) {
1348 allocVariables ($1);
1355 | declaration_list declaration
1359 /* if this is a typedef */
1360 if ($2 && IS_TYPEDEF($2->etype)) {
1361 allocVariables ($2);
1365 /* get to the end of the previous decl */
1380 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1383 expression_statement
1389 : ELSE statement { $$ = $2 ; }
1395 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1396 | SWITCH '(' expr ')' {
1398 static int swLabel = 0 ;
1400 /* create a node for expression */
1401 ex = newNode(SWITCH,$3,NULL);
1402 STACK_PUSH(swStk,ex); /* save it in the stack */
1403 ex->values.switchVals.swNum = swLabel ;
1405 /* now create the label */
1406 SNPRINTF(lbuff, sizeof(lbuff),
1407 "_swBrk_%d",swLabel++);
1408 $<sym>$ = newSymbol(lbuff,NestLevel);
1409 /* put label in the break stack */
1410 STACK_PUSH(breakStack,$<sym>$);
1413 /* get back the switch form the stack */
1414 $$ = STACK_POP(swStk) ;
1415 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1416 STACK_POP(breakStack);
1420 while : WHILE { /* create and push the continue , break & body labels */
1421 static int Lblnum = 0 ;
1423 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1424 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1426 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1427 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1429 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1430 $$ = newSymbol(lbuff,NestLevel);
1434 do : DO { /* create and push the continue , break & body Labels */
1435 static int Lblnum = 0 ;
1438 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1439 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1441 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1442 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1444 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1445 $$ = newSymbol (lbuff,NestLevel);
1449 for : FOR { /* create & push continue, break & body labels */
1450 static int Lblnum = 0 ;
1453 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1454 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1456 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1457 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1459 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1460 $$ = newSymbol(lbuff,NestLevel);
1462 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1463 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1468 : while '(' expr ')' statement
1471 $$ = createWhile ( $1, STACK_POP(continueStack),
1472 STACK_POP(breakStack), $3, $5 );
1473 $$->lineno = $1->lineDef ;
1476 | do statement WHILE '(' expr ')' ';'
1479 $$ = createDo ( $1 , STACK_POP(continueStack),
1480 STACK_POP(breakStack), $5, $2);
1481 $$->lineno = $1->lineDef ;
1484 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1488 /* if break or continue statement present
1489 then create a general case loop */
1490 if (STACK_PEEK(continueStack)->isref ||
1491 STACK_PEEK(breakStack)->isref) {
1492 $$ = createFor ($1, STACK_POP(continueStack),
1493 STACK_POP(breakStack) ,
1494 STACK_POP(forStack) ,
1497 $$ = newNode(FOR,$9,NULL);
1498 AST_FOR($$,trueLabel) = $1;
1499 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1500 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1501 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1502 AST_FOR($$,initExpr) = $3;
1503 AST_FOR($$,condExpr) = $5;
1504 AST_FOR($$,loopExpr) = $7;
1517 : GOTO identifier ';' {
1519 $$ = newAst_VALUE(symbolVal($2));
1520 $$ = newNode(GOTO,$$,NULL);
1523 /* make sure continue is in context */
1524 if (STACK_PEEK(continueStack) == NULL) {
1525 werror(E_BREAK_CONTEXT);
1529 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1530 $$ = newNode(GOTO,$$,NULL);
1531 /* mark the continue label as referenced */
1532 STACK_PEEK(continueStack)->isref = 1;
1536 if (STACK_PEEK(breakStack) == NULL) {
1537 werror(E_BREAK_CONTEXT);
1540 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1541 $$ = newNode(GOTO,$$,NULL);
1542 STACK_PEEK(breakStack)->isref = 1;
1547 werror(E_INVALID_CRITICAL);
1550 $$ = newNode(RETURN,NULL,NULL);
1555 werror(E_INVALID_CRITICAL);
1558 $$ = newNode(RETURN,NULL,$2);
1564 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }