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 */
50 char lbuff[1024]; /* local buffer */
52 /* break & continue stacks */
53 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
54 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
55 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
56 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
57 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
59 value *cenum = NULL ; /* current enumeration type chain*/
60 bool uselessDecl = TRUE;
66 symbol *sym ; /* symbol table pointer */
67 structdef *sdef; /* structure definition */
68 char yychar[SDCC_NAME_MAX+1];
69 sym_link *lnk ; /* declarator or specifier */
70 int yyint; /* integer value returned */
71 value *val ; /* for integer constant */
72 initList *ilist; /* initial list */
73 char *yyinline; /* inlined assembler code */
74 ast *asts; /* expression tree */
77 %token <yychar> IDENTIFIER TYPE_NAME
78 %token <val> CONSTANT STRING_LITERAL
80 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
82 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
83 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
84 %token <yyint> XOR_ASSIGN OR_ASSIGN
85 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
86 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
87 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
88 %token STRUCT UNION ENUM ELIPSIS RANGE FAR
89 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
90 %token NAKED JAVANATIVE OVERLAY
91 %token <yyinline> INLINEASM
92 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
93 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
95 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
96 %token DUMMY_READ_VOLATILE
98 %type <yyint> Interrupt_storage
99 %type <sym> identifier declarator declarator2 enumerator_list enumerator
100 %type <sym> struct_declarator
101 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
102 %type <sym> declaration init_declarator_list init_declarator
103 %type <sym> declaration_list identifier_list parameter_identifier_list
104 %type <sym> declarator2_function_attributes while do for
105 %type <lnk> pointer type_specifier_list type_specifier type_name
106 %type <lnk> storage_class_specifier struct_or_union_specifier
107 %type <lnk> declaration_specifiers sfr_reg_bit type_specifier2
108 %type <lnk> function_attribute function_attributes enum_specifier
109 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
110 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
111 %type <sdef> stag opt_stag
112 %type <asts> primary_expr
113 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
114 %type <asts> additive_expr shift_expr relational_expr equality_expr
115 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
116 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
117 %type <asts> expr argument_expr_list function_definition expr_opt
118 %type <asts> statement_list statement labeled_statement compound_statement
119 %type <asts> expression_statement selection_statement iteration_statement
120 %type <asts> jump_statement function_body else_statement string_literal
121 %type <ilist> initializer initializer_list
122 %type <yyint> unary_operator assignment_operator struct_or_union
129 : external_definition
130 | file external_definition
134 : function_definition {
139 && IS_FUNC($1->type))
141 /* The only legal storage classes for
142 * a function prototype (declaration)
143 * are extern and static. extern is the
144 * default. Thus, if this function isn't
145 * explicitly marked static, mark it
149 && IS_SPEC($1->etype)
150 && !SPEC_STAT($1->etype))
152 SPEC_EXTR($1->etype) = 1;
156 allocVariables ($1) ;
157 cleanUpLevel (SymbolTab,1);
162 : declarator function_body { /* function type not specified */
163 /* assume it to be 'int' */
164 addDecl($1,0,newIntLink());
165 $$ = createFunction($1,$2);
167 | declaration_specifiers declarator function_body
169 pointerTypes($2->type,copyLinkChain($1));
171 $$ = createFunction($2,$3);
176 : function_attributes
177 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
182 $$ = newLink(SPECIFIER) ;
183 FUNC_REGBANK($$) = (int) floatFromVal($2);
185 | REENTRANT { $$ = newLink (SPECIFIER);
188 | CRITICAL { $$ = newLink (SPECIFIER);
189 FUNC_ISCRITICAL($$) = 1;
191 | NAKED { $$ = newLink (SPECIFIER);
194 | JAVANATIVE { $$ = newLink (SPECIFIER);
195 FUNC_ISJAVANATIVE($$)=1;
197 | OVERLAY { $$ = newLink (SPECIFIER);
198 FUNC_ISOVERLAY($$)=1;
200 | NONBANKED {$$ = newLink (SPECIFIER);
201 FUNC_NONBANKED($$) = 1;
202 if (FUNC_BANKED($$)) {
203 werror(W_BANKED_WITH_NONBANKED);
206 | BANKED {$$ = newLink (SPECIFIER);
208 if (FUNC_NONBANKED($$)) {
209 werror(W_BANKED_WITH_NONBANKED);
212 werror(W_BANKED_WITH_STATIC);
217 $$ = newLink (SPECIFIER) ;
218 FUNC_INTNO($$) = $1 ;
225 | declaration_list compound_statement
227 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
233 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
234 | CONSTANT { $$ = newAst_VALUE($1); }
236 | '(' expr ')' { $$ = $2 ; }
240 : STRING_LITERAL { $$ = newAst_VALUE($1); }
245 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
246 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
247 $$->left->funcName = 1;}
248 | postfix_expr '(' argument_expr_list ')'
250 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
252 | postfix_expr '.' identifier
254 $3 = newSymbol($3->name,NestLevel);
256 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
257 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
259 | postfix_expr PTR_OP identifier
261 $3 = newSymbol($3->name,NestLevel);
263 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
265 | postfix_expr INC_OP
266 { $$ = newNode(INC_OP,$1,NULL);}
267 | postfix_expr DEC_OP
268 { $$ = newNode(DEC_OP,$1,NULL); }
273 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
278 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
279 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
280 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
281 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
282 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
283 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
297 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
302 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
303 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
304 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
308 : multiplicative_expr
309 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
310 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
315 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
316 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
321 | relational_expr '<' shift_expr {
323 newNode('!',newNode(GE_OP,$1,$3),NULL) :
324 newNode('<', $1,$3));
326 | relational_expr '>' shift_expr {
328 newNode('!',newNode(LE_OP,$1,$3),NULL) :
331 | relational_expr LE_OP shift_expr {
333 newNode('!', newNode('>', $1 , $3 ), NULL) :
334 newNode(LE_OP,$1,$3));
336 | relational_expr GE_OP shift_expr {
338 newNode('!', newNode('<', $1 , $3 ), NULL) :
339 newNode(GE_OP,$1,$3));
345 | equality_expr EQ_OP relational_expr {
347 newNode('!',newNode(NE_OP,$1,$3),NULL) :
348 newNode(EQ_OP,$1,$3));
350 | equality_expr NE_OP relational_expr {
352 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
353 newNode(NE_OP,$1,$3));
359 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
364 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
369 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
374 | logical_and_expr AND_OP inclusive_or_expr
375 { $$ = newNode(AND_OP,$1,$3);}
380 | logical_or_expr OR_OP logical_and_expr
381 { $$ = newNode(OR_OP,$1,$3); }
386 | logical_or_expr '?' logical_or_expr ':' conditional_expr
388 $$ = newNode(':',$3,$5) ;
389 $$ = newNode('?',$1,$$) ;
395 | unary_expr assignment_operator assignment_expr
400 $$ = newNode($2,$1,$3);
403 $$ = newNode('=',$1,newNode('*',removeIncDecOps(copyAst($1)),$3));
406 $$ = newNode('=',$1,newNode('/',removeIncDecOps(copyAst($1)),$3));
409 $$ = newNode('=',$1,newNode('%',removeIncDecOps(copyAst($1)),$3));
412 $$ = newNode('=',$1,newNode('+',removeIncDecOps(copyAst($1)),$3));
415 $$ = newNode('=',$1,newNode('-',removeIncDecOps(copyAst($1)),$3));
418 $$ = newNode('=',$1,newNode(LEFT_OP,removeIncDecOps(copyAst($1)),$3));
421 $$ = newNode('=',$1,newNode(RIGHT_OP,removeIncDecOps(copyAst($1)),$3));
424 $$ = newNode('=',$1,newNode('&',removeIncDecOps(copyAst($1)),$3));
427 $$ = newNode('=',$1,newNode('^',removeIncDecOps(copyAst($1)),$3));
430 $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3));
455 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
463 : declaration_specifiers ';'
466 werror(W_USELESS_DECL);
470 | declaration_specifiers init_declarator_list ';'
472 /* add the specifier list to the id */
475 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
476 sym_link *lnk = copyLinkChain($1);
477 /* do the pointer stuff */
478 pointerTypes(sym->type,lnk);
479 addDecl (sym,0,lnk) ;
487 declaration_specifiers
488 : storage_class_specifier { $$ = $1; }
489 | storage_class_specifier declaration_specifiers {
490 /* if the decl $2 is not a specifier */
491 /* find the spec and replace it */
494 while (lnk && !IS_SPEC(lnk->next))
496 lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
500 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
502 | type_specifier { $$ = $1; }
503 | type_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, "type_specifier declaration_specifiers - skipped");
514 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
520 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
524 : declarator { $1->ival = NULL ; }
525 | declarator '=' initializer { $1->ival = $3 ; }
529 storage_class_specifier
531 $$ = newLink (SPECIFIER) ;
532 SPEC_TYPEDEF($$) = 1 ;
535 $$ = newLink(SPECIFIER);
539 $$ = newLink (SPECIFIER);
543 $$ = newLink (SPECIFIER) ;
544 SPEC_SCLS($$) = S_AUTO ;
547 $$ = newLink (SPECIFIER);
548 SPEC_SCLS($$) = S_REGISTER ;
553 : INTERRUPT { $$ = INTNO_UNSPEC ; }
555 { int intno = (int) floatFromVal($2);
556 if ((intno >= 0) && (intno <= INTNO_MAX))
560 werror(E_INT_BAD_INTNO, intno);
568 | type_specifier2 AT constant_expr
570 /* add this to the storage class specifier */
571 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
572 /* now get the abs addr from value */
573 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
579 $$=newLink(SPECIFIER);
580 SPEC_NOUN($$) = V_CHAR ;
583 $$=newLink(SPECIFIER);
584 $$->select.s._short = 1 ;
587 $$=newLink(SPECIFIER);
588 SPEC_NOUN($$) = V_INT ;
591 $$=newLink(SPECIFIER);
595 $$=newLink(SPECIFIER);
596 $$->select.s._signed = 1;
599 $$=newLink(SPECIFIER);
603 $$=newLink(SPECIFIER);
604 SPEC_NOUN($$) = V_VOID ;
607 $$=newLink(SPECIFIER);
611 $$=newLink(SPECIFIER);
612 SPEC_VOLATILE($$) = 1 ;
615 $$=newLink(SPECIFIER);
616 SPEC_NOUN($$) = V_FLOAT;
619 $$ = newLink (SPECIFIER);
620 SPEC_SCLS($$) = S_XDATA ;
623 $$ = newLink (SPECIFIER) ;
624 SPEC_SCLS($$) = S_CODE ;
627 $$ = newLink (SPECIFIER) ;
628 SPEC_SCLS($$) = S_EEPROM ;
631 $$ = newLink (SPECIFIER);
632 SPEC_SCLS($$) = S_DATA ;
635 $$ = newLink (SPECIFIER);
636 SPEC_SCLS($$) = S_IDATA ;
639 $$ = newLink (SPECIFIER);
640 SPEC_SCLS($$) = S_PDATA ;
643 $$=newLink(SPECIFIER);
644 SPEC_NOUN($$) = V_BIT ;
645 SPEC_SCLS($$) = S_BIT ;
650 | struct_or_union_specifier {
663 sym = findSym(TypedefTab,NULL,$1) ;
664 $$ = p = copyLinkChain(sym->type);
665 SPEC_TYPEDEF(getSpec(p)) = 0;
672 $$ = newLink(SPECIFIER) ;
673 SPEC_NOUN($$) = V_SBIT;
674 SPEC_SCLS($$) = S_SBIT;
677 $$ = newLink(SPECIFIER) ;
678 SPEC_NOUN($$) = V_CHAR;
679 SPEC_SCLS($$) = S_SFR ;
684 struct_or_union_specifier
685 : struct_or_union opt_stag '{' struct_declaration_list '}'
690 // check for duplicate structure members
691 for (sym=$4; sym; sym=sym->next) {
692 for (dsym=sym->next; dsym; dsym=dsym->next) {
693 if (strcmp(sym->name, dsym->name)==0) {
694 werror(E_DUPLICATE_MEMBER,
695 $1==STRUCT ? "struct" : "union", sym->name);
700 /* Create a structdef */
702 sdef->fields = reverseSyms($4) ; /* link the fields */
703 sdef->size = compStructSize($1,sdef); /* update size of */
705 /* Create the specifier */
706 $$ = newLink (SPECIFIER) ;
707 SPEC_NOUN($$) = V_STRUCT;
708 SPEC_STRUCT($$)= sdef ;
710 | struct_or_union stag
712 $$ = newLink(SPECIFIER) ;
713 SPEC_NOUN($$) = V_STRUCT;
714 SPEC_STRUCT($$) = $2 ;
719 : STRUCT { $$ = STRUCT ; }
720 | UNION { $$ = UNION ; }
725 | { /* synthesize a name add to structtable */
726 $$ = newStruct(genSymName(NestLevel)) ;
727 $$->level = NestLevel ;
728 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
732 : identifier { /* add name to structure table */
733 $$ = findSymWithBlock (StructTab,$1,currBlockno);
735 $$ = newStruct($1->name) ;
736 $$->level = NestLevel ;
737 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
742 struct_declaration_list
744 | struct_declaration_list struct_declaration
748 /* go to the end of the chain */
749 while (sym->next) sym=sym->next;
757 : type_specifier_list struct_declarator_list ';'
759 /* add this type to all the symbols */
761 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
763 /* make the symbol one level up */
766 pointerTypes(sym->type,copyLinkChain($1));
768 sym->type = copyLinkChain($1);
769 sym->etype = getSpec(sym->type);
772 addDecl (sym,0,copyLinkChain($1));
773 /* make sure the type is complete and sane */
774 checkTypeSanity(sym->etype, sym->name);
780 struct_declarator_list
782 | struct_declarator_list ',' struct_declarator
791 | ':' constant_expr {
793 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
794 bitsize= (int) floatFromVal(constExprValue($2,TRUE));
795 if (bitsize > (port->s.int_size * 8)) {
796 bitsize = port->s.int_size * 8;
797 werror(E_BITFLD_SIZE, bitsize);
800 bitsize = BITVAR_PAD;
801 $$->bitVar = bitsize;
803 | declarator ':' constant_expr
806 bitsize= (int) floatFromVal(constExprValue($3,TRUE));
807 if (bitsize > (port->s.int_size * 8)) {
808 bitsize = port->s.int_size * 8;
809 werror(E_BITFLD_SIZE, bitsize);
812 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
813 $$->bitVar = BITVAR_PAD;
814 werror(W_BITFLD_NAMED);
817 $1->bitVar = bitsize;
822 : ENUM '{' enumerator_list '}' {
826 // check for duplicate enums
827 for (sym=$3; sym; sym=sym->next) {
828 for (dsym=sym->next; dsym; dsym=dsym->next) {
829 if (strcmp(sym->name, dsym->name)==0) {
830 werror(E_DUPLICATE_MEMBER, "enum", sym->name);
836 $$ = copyLinkChain(cenum->type);
843 | ENUM identifier '{' enumerator_list '}' {
846 $2->type = copyLinkChain(cenum->type);
847 $2->etype = getSpec($2->type);
848 /* add this to the enumerator table */
849 if (!(csym=findSym(enumTab,$2,$2->name)) &&
850 (csym && csym->level == $2->level))
851 werror(E_DUPLICATE_TYPEDEF,csym->name);
853 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
855 //allocVariables (reverseSyms($4));
856 $$ = copyLinkChain(cenum->type);
857 SPEC_SCLS(getSpec($$)) = 0 ;
862 /* check the enumerator table */
863 if ((csym = findSym(enumTab,$2,$2->name)))
864 $$ = copyLinkChain(csym->type);
866 $$ = newLink(SPECIFIER) ;
867 SPEC_NOUN($$) = V_INT ;
870 SPEC_SCLS(getSpec($$)) = 0 ;
876 | enumerator_list ',' {
878 | enumerator_list ',' enumerator {
885 : identifier opt_assign_expr
887 /* make the symbol one level up */
889 $1->type = copyLinkChain($2->type);
890 $1->etype= getSpec($1->type);
891 SPEC_ENUM($1->etype) = 1;
893 // do this now, so we can use it for the next enums in the list
899 : '=' constant_expr {
902 val = constExprValue($2,TRUE);
907 SNPRINTF(lbuff, sizeof(lbuff),
908 "%d",(int) floatFromVal(cenum)+1);
909 $$ = cenum = constVal(lbuff);
912 SNPRINTF(lbuff, sizeof(lbuff),
914 $$ = cenum = constVal(lbuff);
920 : declarator2_function_attributes { $$ = $1; }
921 | pointer declarator2_function_attributes
923 addDecl ($2,0,reverseLink($1));
928 declarator2_function_attributes
929 : declarator2 { $$ = $1 ; }
930 | declarator2 function_attribute {
931 if ((! $1) || (! IS_FUNC($1->etype)))
933 // function_attribute is only allowed if declarator2 was
934 // an actual function
940 // copy the functionAttributes (not the args and hasVargs !!)
941 sym_link *funcType=$1->etype;
942 struct value *args=FUNC_ARGS(funcType);
943 unsigned hasVargs=FUNC_HASVARARGS(funcType);
945 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
946 sizeof($2->funcAttrs));
948 FUNC_ARGS(funcType)=args;
949 FUNC_HASVARARGS(funcType)=hasVargs;
952 memset (&$2->funcAttrs, 0,
953 sizeof($2->funcAttrs));
962 | '(' declarator ')' { $$ = $2; }
963 | declarator2 '[' ']'
967 p = newLink (DECLARATOR);
968 DCL_TYPE(p) = ARRAY ;
972 | declarator2 '[' constant_expr ']'
977 p = (tval = constExprValue($3,TRUE))->etype;
978 /* if it is not a constant then Error */
979 if ( SPEC_SCLS(p) != S_LITERAL)
980 werror(E_CONST_EXPECTED) ;
982 p = newLink (DECLARATOR);
983 DCL_TYPE(p) = ARRAY ;
984 DCL_ELEM(p) = (int) floatFromVal(tval) ;
988 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
989 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
992 addDecl ($1,FUNCTION,NULL) ;
994 FUNC_HASVARARGS($1->type) = IS_VARG($4);
995 FUNC_ARGS($1->type) = reverseVal($4);
997 /* nest level was incremented to take care of the parms */
1001 // if this was a pointer (to a function)
1002 if (IS_PTR($1->type)) {
1003 // move the args and hasVargs to the function
1004 FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
1005 FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
1006 memset (&$1->type->funcAttrs, 0,
1007 sizeof($1->type->funcAttrs));
1008 // remove the symbol args (if any)
1009 cleanUpLevel(SymbolTab,NestLevel+1);
1014 | declarator2 '(' parameter_identifier_list ')'
1016 werror(E_OLD_STYLE,$1->name) ;
1018 /* assume it returns an int */
1019 $1->type = $1->etype = newIntLink();
1025 : unqualified_pointer { $$ = $1 ;}
1026 | unqualified_pointer type_specifier_list
1031 | unqualified_pointer pointer
1035 DCL_TYPE($2)=port->unqualified_pointer;
1037 | unqualified_pointer type_specifier_list pointer
1040 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1041 DCL_PTR_CONST($1) = SPEC_CONST($2);
1042 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1043 switch (SPEC_SCLS($2)) {
1045 DCL_TYPE($3) = FPOINTER;
1048 DCL_TYPE($3) = IPOINTER ;
1051 DCL_TYPE($3) = PPOINTER ;
1054 DCL_TYPE($3) = POINTER ;
1057 DCL_PTR_CONST($3) = 1;
1058 DCL_TYPE($3) = CPOINTER ;
1061 DCL_TYPE($3) = EEPPOINTER;
1064 // this could be just "constant"
1065 // werror(W_PTR_TYPE_INVALID);
1070 werror (W_PTR_TYPE_INVALID);
1078 $$ = newLink(DECLARATOR);
1079 DCL_TYPE($$)=UPOINTER;
1085 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1086 | type_specifier_list type_specifier {
1087 /* if the decl $2 is not a specifier */
1088 /* find the spec and replace it */
1089 if ( !IS_SPEC($2)) {
1090 sym_link *lnk = $2 ;
1091 while (lnk && !IS_SPEC(lnk->next))
1093 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1097 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1101 parameter_identifier_list
1103 | identifier_list ',' ELIPSIS
1108 | identifier_list ',' identifier
1117 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1121 : parameter_declaration
1122 | parameter_list ',' parameter_declaration
1129 parameter_declaration
1130 : type_specifier_list declarator
1133 pointerTypes($2->type,$1);
1135 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1142 $$->etype = getSpec($$->type);
1147 : type_specifier_list { $$ = $1 ;}
1148 | type_specifier_list abstract_declarator
1150 /* go to the end of the list */
1152 pointerTypes($2,$1);
1153 for ( p = $2 ; p && p->next ; p=p->next);
1155 werror(E_SYNTAX_ERROR, yytext);
1164 : pointer { $$ = reverseLink($1); }
1165 | abstract_declarator2
1166 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1167 if (IS_PTR($1) && IS_FUNC($2))
1168 DCL_TYPE($1) = CPOINTER;
1172 abstract_declarator2
1173 : '(' abstract_declarator ')' { $$ = $2 ; }
1175 $$ = newLink (DECLARATOR);
1176 DCL_TYPE($$) = ARRAY ;
1179 | '[' constant_expr ']' {
1181 $$ = newLink (DECLARATOR);
1182 DCL_TYPE($$) = ARRAY ;
1183 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1185 | abstract_declarator2 '[' ']' {
1186 $$ = newLink (DECLARATOR);
1187 DCL_TYPE($$) = ARRAY ;
1191 | abstract_declarator2 '[' constant_expr ']'
1194 $$ = newLink (DECLARATOR);
1195 DCL_TYPE($$) = ARRAY ;
1196 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1199 | '(' ')' { $$ = NULL;}
1200 | '(' parameter_type_list ')' { $$ = NULL;}
1201 | abstract_declarator2 '(' ')' {
1202 // $1 must be a pointer to a function
1203 sym_link *p=newLink(DECLARATOR);
1204 DCL_TYPE(p) = FUNCTION;
1206 // ((void (code *) ()) 0) ()
1207 $1=newLink(DECLARATOR);
1208 DCL_TYPE($1)=CPOINTER;
1213 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1214 sym_link *p=newLink(DECLARATOR);
1215 DCL_TYPE(p) = FUNCTION;
1217 FUNC_HASVARARGS(p) = IS_VARG($4);
1218 FUNC_ARGS(p) = reverseVal($4);
1220 /* nest level was incremented to take care of the parms */
1226 // remove the symbol args (if any)
1227 cleanUpLevel(SymbolTab,NestLevel+1);
1232 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1233 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1234 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1239 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1244 | compound_statement
1245 | expression_statement
1246 | selection_statement
1247 | iteration_statement
1250 ast *ex = newNode(INLINEASM,NULL,NULL);
1251 ex->values.inlineasm = strdup($1);
1257 // : identifier ':' statement { $$ = createLabel($1,$3); }
1258 : identifier ':' { $$ = createLabel($1,NULL); }
1259 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1260 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1263 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1266 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1270 : start_block end_block { $$ = createBlock(NULL,NULL); }
1271 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1273 declaration_list { addSymChain($2); }
1274 end_block { $$ = createBlock($2,NULL) ; }
1276 declaration_list { addSymChain ($2); }
1278 end_block {$$ = createBlock($2,$4) ; }
1279 | error ';' { $$ = NULL ; }
1285 /* if this is typedef declare it immediately */
1286 if ( $1 && IS_TYPEDEF($1->etype)) {
1287 allocVariables ($1);
1294 | declaration_list declaration
1298 /* if this is a typedef */
1299 if ($2 && IS_TYPEDEF($2->etype)) {
1300 allocVariables ($2);
1304 /* get to the end of the previous decl */
1319 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1322 expression_statement
1328 : ELSE statement { $$ = $2 ; }
1334 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1335 | SWITCH '(' expr ')' {
1337 static int swLabel = 0 ;
1339 /* create a node for expression */
1340 ex = newNode(SWITCH,$3,NULL);
1341 STACK_PUSH(swStk,ex); /* save it in the stack */
1342 ex->values.switchVals.swNum = swLabel ;
1344 /* now create the label */
1345 SNPRINTF(lbuff, sizeof(lbuff),
1346 "_swBrk_%d",swLabel++);
1347 $<sym>$ = newSymbol(lbuff,NestLevel);
1348 /* put label in the break stack */
1349 STACK_PUSH(breakStack,$<sym>$);
1352 /* get back the switch form the stack */
1353 $$ = STACK_POP(swStk) ;
1354 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1355 STACK_POP(breakStack);
1359 while : WHILE { /* create and push the continue , break & body labels */
1360 static int Lblnum = 0 ;
1362 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1363 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1365 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1366 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1368 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1369 $$ = newSymbol(lbuff,NestLevel);
1373 do : DO { /* create and push the continue , break & body Labels */
1374 static int Lblnum = 0 ;
1377 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1378 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1380 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1381 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1383 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1384 $$ = newSymbol (lbuff,NestLevel);
1388 for : FOR { /* create & push continue, break & body labels */
1389 static int Lblnum = 0 ;
1392 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1393 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1395 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1396 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1398 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1399 $$ = newSymbol(lbuff,NestLevel);
1401 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1402 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1407 : while '(' expr ')' statement
1410 $$ = createWhile ( $1, STACK_POP(continueStack),
1411 STACK_POP(breakStack), $3, $5 );
1412 $$->lineno = $1->lineDef ;
1415 | do statement WHILE '(' expr ')' ';'
1418 $$ = createDo ( $1 , STACK_POP(continueStack),
1419 STACK_POP(breakStack), $5, $2);
1420 $$->lineno = $1->lineDef ;
1423 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1427 /* if break or continue statement present
1428 then create a general case loop */
1429 if (STACK_PEEK(continueStack)->isref ||
1430 STACK_PEEK(breakStack)->isref) {
1431 $$ = createFor ($1, STACK_POP(continueStack),
1432 STACK_POP(breakStack) ,
1433 STACK_POP(forStack) ,
1436 $$ = newNode(FOR,$9,NULL);
1437 AST_FOR($$,trueLabel) = $1;
1438 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1439 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1440 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1441 AST_FOR($$,initExpr) = $3;
1442 AST_FOR($$,condExpr) = $5;
1443 AST_FOR($$,loopExpr) = $7;
1456 : GOTO identifier ';' {
1458 $$ = newAst_VALUE(symbolVal($2));
1459 $$ = newNode(GOTO,$$,NULL);
1462 /* make sure continue is in context */
1463 if (STACK_PEEK(continueStack) == NULL) {
1464 werror(E_BREAK_CONTEXT);
1468 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1469 $$ = newNode(GOTO,$$,NULL);
1470 /* mark the continue label as referenced */
1471 STACK_PEEK(continueStack)->isref = 1;
1475 if (STACK_PEEK(breakStack) == NULL) {
1476 werror(E_BREAK_CONTEXT);
1479 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1480 $$ = newNode(GOTO,$$,NULL);
1481 STACK_PEEK(breakStack)->isref = 1;
1484 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1485 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1489 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }