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*/
65 symbol *sym ; /* symbol table pointer */
66 structdef *sdef; /* structure definition */
67 char yychar[SDCC_NAME_MAX+1];
68 sym_link *lnk ; /* declarator or specifier */
69 int yyint; /* integer value returned */
70 value *val ; /* for integer constant */
71 initList *ilist; /* initial list */
72 char *yyinline; /* inlined assembler code */
73 ast *asts; /* expression tree */
76 %token <yychar> IDENTIFIER TYPE_NAME
77 %token <val> CONSTANT STRING_LITERAL
79 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
81 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
82 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
83 %token <yyint> XOR_ASSIGN OR_ASSIGN
84 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
85 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
86 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
87 %token STRUCT UNION ENUM ELIPSIS RANGE FAR
88 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
89 %token NAKED JAVANATIVE OVERLAY
90 %token <yyinline> INLINEASM
91 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
92 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
94 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
95 %token DUMMY_READ_VOLATILE
97 %type <yyint> Interrupt_storage
98 %type <sym> identifier declarator declarator2 enumerator_list enumerator
99 %type <sym> struct_declarator
100 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
101 %type <sym> declaration init_declarator_list init_declarator
102 %type <sym> declaration_list identifier_list parameter_identifier_list
103 %type <sym> declarator2_function_attributes while do for
104 %type <lnk> pointer type_specifier_list type_specifier type_name
105 %type <lnk> storage_class_specifier struct_or_union_specifier
106 %type <lnk> declaration_specifiers sfr_reg_bit type_specifier2
107 %type <lnk> function_attribute function_attributes enum_specifier
108 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
109 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
110 %type <sdef> stag opt_stag
111 %type <asts> primary_expr
112 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
113 %type <asts> additive_expr shift_expr relational_expr equality_expr
114 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
115 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
116 %type <asts> expr argument_expr_list function_definition expr_opt
117 %type <asts> statement_list statement labeled_statement compound_statement
118 %type <asts> expression_statement selection_statement iteration_statement
119 %type <asts> jump_statement function_body else_statement string_literal
120 %type <ilist> initializer initializer_list
121 %type <yyint> unary_operator assignment_operator struct_or_union
128 : external_definition
129 | file external_definition
133 : function_definition {
138 && IS_FUNC($1->type))
140 /* The only legal storage classes for
141 * a function prototype (declaration)
142 * are extern and static. extern is the
143 * default. Thus, if this function isn't
144 * explicitly marked static, mark it
148 && IS_SPEC($1->etype)
149 && !SPEC_STAT($1->etype))
151 SPEC_EXTR($1->etype) = 1;
155 allocVariables ($1) ;
156 cleanUpLevel (SymbolTab,1);
161 : declarator function_body { /* function type not specified */
162 /* assume it to be 'int' */
163 addDecl($1,0,newIntLink());
164 $$ = createFunction($1,$2);
166 | declaration_specifiers declarator function_body
168 pointerTypes($2->type,copyLinkChain($1));
170 $$ = createFunction($2,$3);
175 : function_attributes
176 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
181 $$ = newLink(SPECIFIER) ;
182 FUNC_REGBANK($$) = (int) floatFromVal($2);
184 | REENTRANT { $$ = newLink (SPECIFIER);
187 | CRITICAL { $$ = newLink (SPECIFIER);
188 FUNC_ISCRITICAL($$) = 1;
190 | NAKED { $$ = newLink (SPECIFIER);
193 | JAVANATIVE { $$ = newLink (SPECIFIER);
194 FUNC_ISJAVANATIVE($$)=1;
196 | OVERLAY { $$ = newLink (SPECIFIER);
197 FUNC_ISOVERLAY($$)=1;
199 | NONBANKED {$$ = newLink (SPECIFIER);
200 FUNC_NONBANKED($$) = 1;
201 if (FUNC_BANKED($$)) {
202 werror(W_BANKED_WITH_NONBANKED);
205 | BANKED {$$ = newLink (SPECIFIER);
207 if (FUNC_NONBANKED($$)) {
208 werror(W_BANKED_WITH_NONBANKED);
211 werror(W_BANKED_WITH_STATIC);
216 $$ = newLink (SPECIFIER) ;
217 FUNC_INTNO($$) = $1 ;
224 | declaration_list compound_statement
226 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
232 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
233 | CONSTANT { $$ = newAst_VALUE($1); }
235 | '(' expr ')' { $$ = $2 ; }
239 : STRING_LITERAL { $$ = newAst_VALUE($1); }
244 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
245 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
246 $$->left->funcName = 1;}
247 | postfix_expr '(' argument_expr_list ')'
249 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
251 | postfix_expr '.' identifier
253 $3 = newSymbol($3->name,NestLevel);
255 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
256 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
258 | postfix_expr PTR_OP identifier
260 $3 = newSymbol($3->name,NestLevel);
262 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
264 | postfix_expr INC_OP
265 { $$ = newNode(INC_OP,$1,NULL);}
266 | postfix_expr DEC_OP
267 { $$ = newNode(DEC_OP,$1,NULL); }
272 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
277 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
278 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
279 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
280 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
281 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
282 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
296 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
301 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
302 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
303 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
307 : multiplicative_expr
308 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
309 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
314 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
315 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
320 | relational_expr '<' shift_expr {
322 newNode('!',newNode(GE_OP,$1,$3),NULL) :
323 newNode('<', $1,$3));
325 | relational_expr '>' shift_expr {
327 newNode('!',newNode(LE_OP,$1,$3),NULL) :
330 | relational_expr LE_OP shift_expr {
332 newNode('!', newNode('>', $1 , $3 ), NULL) :
333 newNode(LE_OP,$1,$3));
335 | relational_expr GE_OP shift_expr {
337 newNode('!', newNode('<', $1 , $3 ), NULL) :
338 newNode(GE_OP,$1,$3));
344 | equality_expr EQ_OP relational_expr {
346 newNode('!',newNode(NE_OP,$1,$3),NULL) :
347 newNode(EQ_OP,$1,$3));
349 | equality_expr NE_OP relational_expr {
351 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
352 newNode(NE_OP,$1,$3));
358 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
363 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
368 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
373 | logical_and_expr AND_OP inclusive_or_expr
374 { $$ = newNode(AND_OP,$1,$3);}
379 | logical_or_expr OR_OP logical_and_expr
380 { $$ = newNode(OR_OP,$1,$3); }
385 | logical_or_expr '?' logical_or_expr ':' conditional_expr
387 $$ = newNode(':',$3,$5) ;
388 $$ = newNode('?',$1,$$) ;
394 | unary_expr assignment_operator assignment_expr
399 $$ = newNode($2,$1,$3);
402 $$ = newNode('=',$1,newNode('*',removeIncDecOps(copyAst($1)),$3));
405 $$ = newNode('=',$1,newNode('/',removeIncDecOps(copyAst($1)),$3));
408 $$ = newNode('=',$1,newNode('%',removeIncDecOps(copyAst($1)),$3));
411 $$ = newNode('=',$1,newNode('+',removeIncDecOps(copyAst($1)),$3));
414 $$ = newNode('=',$1,newNode('-',removeIncDecOps(copyAst($1)),$3));
417 $$ = newNode('=',$1,newNode(LEFT_OP,removeIncDecOps(copyAst($1)),$3));
420 $$ = newNode('=',$1,newNode(RIGHT_OP,removeIncDecOps(copyAst($1)),$3));
423 $$ = newNode('=',$1,newNode('&',removeIncDecOps(copyAst($1)),$3));
426 $$ = newNode('=',$1,newNode('^',removeIncDecOps(copyAst($1)),$3));
429 $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3));
454 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
462 : declaration_specifiers ';' { $$ = NULL ; }
463 | declaration_specifiers init_declarator_list ';'
465 /* add the specifier list to the id */
468 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
469 sym_link *lnk = copyLinkChain($1);
470 /* do the pointer stuff */
471 pointerTypes(sym->type,lnk);
472 addDecl (sym,0,lnk) ;
479 declaration_specifiers
480 : storage_class_specifier { $$ = $1; }
481 | storage_class_specifier declaration_specifiers {
482 /* if the decl $2 is not a specifier */
483 /* find the spec and replace it */
486 while (lnk && !IS_SPEC(lnk->next))
488 lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
492 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
494 | type_specifier { $$ = $1; }
495 | type_specifier declaration_specifiers {
496 /* if the decl $2 is not a specifier */
497 /* find the spec and replace it */
500 while (lnk && !IS_SPEC(lnk->next))
502 lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
506 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
512 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
516 : declarator { $1->ival = NULL ; }
517 | declarator '=' initializer { $1->ival = $3 ; }
521 storage_class_specifier
523 $$ = newLink (SPECIFIER) ;
524 SPEC_TYPEDEF($$) = 1 ;
527 $$ = newLink(SPECIFIER);
531 $$ = newLink (SPECIFIER);
535 $$ = newLink (SPECIFIER) ;
536 SPEC_SCLS($$) = S_AUTO ;
539 $$ = newLink (SPECIFIER);
540 SPEC_SCLS($$) = S_REGISTER ;
545 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
550 | type_specifier2 AT constant_expr
552 /* add this to the storage class specifier */
553 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
554 /* now get the abs addr from value */
555 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
561 $$=newLink(SPECIFIER);
562 SPEC_NOUN($$) = V_CHAR ;
565 $$=newLink(SPECIFIER);
566 $$->select.s._short = 1 ;
569 $$=newLink(SPECIFIER);
570 SPEC_NOUN($$) = V_INT ;
573 $$=newLink(SPECIFIER);
577 $$=newLink(SPECIFIER);
578 $$->select.s._signed = 1;
581 $$=newLink(SPECIFIER);
585 $$=newLink(SPECIFIER);
586 SPEC_NOUN($$) = V_VOID ;
589 $$=newLink(SPECIFIER);
593 $$=newLink(SPECIFIER);
594 SPEC_VOLATILE($$) = 1 ;
597 $$=newLink(SPECIFIER);
598 SPEC_NOUN($$) = V_FLOAT;
601 $$ = newLink (SPECIFIER);
602 SPEC_SCLS($$) = S_XDATA ;
605 $$ = newLink (SPECIFIER) ;
606 SPEC_SCLS($$) = S_CODE ;
609 $$ = newLink (SPECIFIER) ;
610 SPEC_SCLS($$) = S_EEPROM ;
613 $$ = newLink (SPECIFIER);
614 SPEC_SCLS($$) = S_DATA ;
617 $$ = newLink (SPECIFIER);
618 SPEC_SCLS($$) = S_IDATA ;
621 $$ = newLink (SPECIFIER);
622 SPEC_SCLS($$) = S_PDATA ;
625 $$=newLink(SPECIFIER);
626 SPEC_NOUN($$) = V_BIT ;
627 SPEC_SCLS($$) = S_BIT ;
632 | struct_or_union_specifier
641 sym = findSym(TypedefTab,NULL,$1) ;
642 $$ = p = copyLinkChain(sym->type);
643 SPEC_TYPEDEF(getSpec(p)) = 0;
650 $$ = newLink(SPECIFIER) ;
651 SPEC_NOUN($$) = V_SBIT;
652 SPEC_SCLS($$) = S_SBIT;
655 $$ = newLink(SPECIFIER) ;
656 SPEC_NOUN($$) = V_CHAR;
657 SPEC_SCLS($$) = S_SFR ;
662 struct_or_union_specifier
663 : struct_or_union opt_stag '{' struct_declaration_list '}'
668 // check for duplicate structure members
669 for (sym=$4; sym; sym=sym->next) {
670 for (dsym=sym->next; dsym; dsym=dsym->next) {
671 if (strcmp(sym->name, dsym->name)==0) {
672 werror(E_DUPLICATE_MEMBER,
673 $1==STRUCT ? "struct" : "union", sym->name);
678 /* Create a structdef */
680 sdef->fields = reverseSyms($4) ; /* link the fields */
681 sdef->size = compStructSize($1,sdef); /* update size of */
683 /* Create the specifier */
684 $$ = newLink (SPECIFIER) ;
685 SPEC_NOUN($$) = V_STRUCT;
686 SPEC_STRUCT($$)= sdef ;
688 | struct_or_union stag
690 $$ = newLink(SPECIFIER) ;
691 SPEC_NOUN($$) = V_STRUCT;
692 SPEC_STRUCT($$) = $2 ;
697 : STRUCT { $$ = STRUCT ; }
698 | UNION { $$ = UNION ; }
703 | { /* synthesize a name add to structtable */
704 $$ = newStruct(genSymName(NestLevel)) ;
705 $$->level = NestLevel ;
706 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
710 : identifier { /* add name to structure table */
711 $$ = findSymWithBlock (StructTab,$1,currBlockno);
713 $$ = newStruct($1->name) ;
714 $$->level = NestLevel ;
715 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
720 struct_declaration_list
722 | struct_declaration_list struct_declaration
726 /* go to the end of the chain */
727 while (sym->next) sym=sym->next;
735 : type_specifier_list struct_declarator_list ';'
737 /* add this type to all the symbols */
739 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
741 /* make the symbol one level up */
744 pointerTypes(sym->type,copyLinkChain($1));
746 sym->type = copyLinkChain($1);
747 sym->etype = getSpec(sym->type);
750 addDecl (sym,0,copyLinkChain($1));
751 /* make sure the type is complete and sane */
752 checkTypeSanity(sym->etype, sym->name);
758 struct_declarator_list
760 | struct_declarator_list ',' struct_declarator
769 | ':' constant_expr {
770 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
771 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
773 | declarator ':' constant_expr
775 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
780 : ENUM '{' enumerator_list '}' {
784 // check for duplicate enums
785 for (sym=$3; sym; sym=sym->next) {
786 for (dsym=sym->next; dsym; dsym=dsym->next) {
787 if (strcmp(sym->name, dsym->name)==0) {
788 werror(E_DUPLICATE_MEMBER, "enum", sym->name);
794 $$ = copyLinkChain(cenum->type);
801 | ENUM identifier '{' enumerator_list '}' {
804 $2->type = copyLinkChain(cenum->type);
805 $2->etype = getSpec($2->type);
806 /* add this to the enumerator table */
807 if (!(csym=findSym(enumTab,$2,$2->name)) &&
808 (csym && csym->level == $2->level))
809 werror(E_DUPLICATE_TYPEDEF,csym->name);
811 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
813 //allocVariables (reverseSyms($4));
814 $$ = copyLinkChain(cenum->type);
815 SPEC_SCLS(getSpec($$)) = 0 ;
820 /* check the enumerator table */
821 if ((csym = findSym(enumTab,$2,$2->name)))
822 $$ = copyLinkChain(csym->type);
824 $$ = newLink(SPECIFIER) ;
825 SPEC_NOUN($$) = V_INT ;
828 SPEC_SCLS(getSpec($$)) = 0 ;
834 | enumerator_list ',' {
836 | enumerator_list ',' enumerator {
843 : identifier opt_assign_expr
845 /* make the symbol one level up */
847 $1->type = copyLinkChain($2->type);
848 $1->etype= getSpec($1->type);
849 SPEC_ENUM($1->etype) = 1;
851 // do this now, so we can use it for the next enums in the list
857 : '=' constant_expr {
860 val = constExprValue($2,TRUE);
865 SNPRINTF(lbuff, sizeof(lbuff),
866 "%d",(int) floatFromVal(cenum)+1);
867 $$ = cenum = constVal(lbuff);
870 SNPRINTF(lbuff, sizeof(lbuff),
872 $$ = cenum = constVal(lbuff);
878 : declarator2_function_attributes { $$ = $1; }
879 | pointer declarator2_function_attributes
881 addDecl ($2,0,reverseLink($1));
886 declarator2_function_attributes
887 : declarator2 { $$ = $1 ; }
888 | declarator2 function_attribute {
889 // copy the functionAttributes (not the args and hasVargs !!)
890 sym_link *funcType=$1->etype;
891 struct value *args=FUNC_ARGS(funcType);
892 unsigned hasVargs=FUNC_HASVARARGS(funcType);
894 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
895 sizeof($2->funcAttrs));
897 FUNC_ARGS(funcType)=args;
898 FUNC_HASVARARGS(funcType)=hasVargs;
901 memset (&$2->funcAttrs, 0,
902 sizeof($2->funcAttrs));
910 | '(' declarator ')' { $$ = $2; }
911 | declarator2 '[' ']'
915 p = newLink (DECLARATOR);
916 DCL_TYPE(p) = ARRAY ;
920 | declarator2 '[' constant_expr ']'
925 p = (tval = constExprValue($3,TRUE))->etype;
926 /* if it is not a constant then Error */
927 if ( SPEC_SCLS(p) != S_LITERAL)
928 werror(E_CONST_EXPECTED) ;
930 p = newLink (DECLARATOR);
931 DCL_TYPE(p) = ARRAY ;
932 DCL_ELEM(p) = (int) floatFromVal(tval) ;
936 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
937 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
940 addDecl ($1,FUNCTION,NULL) ;
942 FUNC_HASVARARGS($1->type) = IS_VARG($4);
943 FUNC_ARGS($1->type) = reverseVal($4);
945 /* nest level was incremented to take care of the parms */
949 // if this was a pointer (to a function)
950 if (IS_PTR($1->type)) {
951 // move the args and hasVargs to the function
952 FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
953 FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
954 memset (&$1->type->funcAttrs, 0,
955 sizeof($1->type->funcAttrs));
956 // remove the symbol args (if any)
957 cleanUpLevel(SymbolTab,NestLevel+1);
962 | declarator2 '(' parameter_identifier_list ')'
964 werror(E_OLD_STYLE,$1->name) ;
966 /* assume it returns an int */
967 $1->type = $1->etype = newIntLink();
973 : unqualified_pointer { $$ = $1 ;}
974 | unqualified_pointer type_specifier_list
979 | unqualified_pointer pointer
983 DCL_TYPE($2)=port->unqualified_pointer;
985 | unqualified_pointer type_specifier_list pointer
988 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
989 DCL_PTR_CONST($1) = SPEC_CONST($2);
990 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
991 switch (SPEC_SCLS($2)) {
993 DCL_TYPE($3) = FPOINTER;
996 DCL_TYPE($3) = IPOINTER ;
999 DCL_TYPE($3) = PPOINTER ;
1002 DCL_TYPE($3) = POINTER ;
1005 DCL_PTR_CONST($3) = 1;
1006 DCL_TYPE($3) = CPOINTER ;
1009 DCL_TYPE($3) = EEPPOINTER;
1012 // this could be just "constant"
1013 // werror(W_PTR_TYPE_INVALID);
1018 werror (W_PTR_TYPE_INVALID);
1026 $$ = newLink(DECLARATOR);
1027 DCL_TYPE($$)=UPOINTER;
1033 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1034 | type_specifier_list type_specifier {
1035 /* if the decl $2 is not a specifier */
1036 /* find the spec and replace it */
1037 if ( !IS_SPEC($2)) {
1038 sym_link *lnk = $2 ;
1039 while (lnk && !IS_SPEC(lnk->next))
1041 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1045 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1049 parameter_identifier_list
1051 | identifier_list ',' ELIPSIS
1056 | identifier_list ',' identifier
1065 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1069 : parameter_declaration
1070 | parameter_list ',' parameter_declaration
1077 parameter_declaration
1078 : type_specifier_list declarator
1081 pointerTypes($2->type,$1);
1083 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1090 $$->etype = getSpec($$->type);
1095 : type_specifier_list { $$ = $1 ;}
1096 | type_specifier_list abstract_declarator
1098 /* go to the end of the list */
1100 pointerTypes($2,$1);
1101 for ( p = $2 ; p && p->next ; p=p->next);
1103 werror(E_SYNTAX_ERROR, yytext);
1112 : pointer { $$ = reverseLink($1); }
1113 | abstract_declarator2
1114 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1117 abstract_declarator2
1118 : '(' abstract_declarator ')' { $$ = $2 ; }
1120 $$ = newLink (DECLARATOR);
1121 DCL_TYPE($$) = ARRAY ;
1124 | '[' constant_expr ']' {
1126 $$ = newLink (DECLARATOR);
1127 DCL_TYPE($$) = ARRAY ;
1128 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1130 | abstract_declarator2 '[' ']' {
1131 $$ = newLink (DECLARATOR);
1132 DCL_TYPE($$) = ARRAY ;
1136 | abstract_declarator2 '[' constant_expr ']'
1139 $$ = newLink (DECLARATOR);
1140 DCL_TYPE($$) = ARRAY ;
1141 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1144 | '(' ')' { $$ = NULL;}
1145 | '(' parameter_type_list ')' { $$ = NULL;}
1146 | abstract_declarator2 '(' ')' {
1147 // $1 must be a pointer to a function
1148 sym_link *p=newLink(DECLARATOR);
1149 DCL_TYPE(p) = FUNCTION;
1151 // ((void (code *) ()) 0) ()
1152 $1=newLink(DECLARATOR);
1153 DCL_TYPE($1)=CPOINTER;
1158 | abstract_declarator2 '(' parameter_type_list ')' {
1159 if (!IS_VOID($3->etype)) {
1160 // this is nonsense, so let's just burp something
1161 werror(E_TOO_FEW_PARMS);
1163 // $1 must be a pointer to a function
1164 sym_link *p=newLink(DECLARATOR);
1165 DCL_TYPE(p) = FUNCTION;
1167 // ((void (code *) (void)) 0) ()
1168 $1=newLink(DECLARATOR);
1169 DCL_TYPE($1)=CPOINTER;
1178 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1179 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1180 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1185 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1190 | compound_statement
1191 | expression_statement
1192 | selection_statement
1193 | iteration_statement
1196 ast *ex = newNode(INLINEASM,NULL,NULL);
1197 ex->values.inlineasm = strdup($1);
1203 // : identifier ':' statement { $$ = createLabel($1,$3); }
1204 : identifier ':' { $$ = createLabel($1,NULL); }
1205 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1206 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1209 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1212 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1216 : start_block end_block { $$ = createBlock(NULL,NULL); }
1217 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1219 declaration_list { addSymChain($2); }
1220 end_block { $$ = createBlock($2,NULL) ; }
1222 declaration_list { addSymChain ($2); }
1224 end_block {$$ = createBlock($2,$4) ; }
1225 | error ';' { $$ = NULL ; }
1231 /* if this is typedef declare it immediately */
1232 if ( $1 && IS_TYPEDEF($1->etype)) {
1233 allocVariables ($1);
1240 | declaration_list declaration
1244 /* if this is a typedef */
1245 if ($2 && IS_TYPEDEF($2->etype)) {
1246 allocVariables ($2);
1250 /* get to the end of the previous decl */
1265 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1268 expression_statement
1274 : ELSE statement { $$ = $2 ; }
1280 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1281 | SWITCH '(' expr ')' {
1283 static int swLabel = 0 ;
1285 /* create a node for expression */
1286 ex = newNode(SWITCH,$3,NULL);
1287 STACK_PUSH(swStk,ex); /* save it in the stack */
1288 ex->values.switchVals.swNum = swLabel ;
1290 /* now create the label */
1291 SNPRINTF(lbuff, sizeof(lbuff),
1292 "_swBrk_%d",swLabel++);
1293 $<sym>$ = newSymbol(lbuff,NestLevel);
1294 /* put label in the break stack */
1295 STACK_PUSH(breakStack,$<sym>$);
1298 /* get back the switch form the stack */
1299 $$ = STACK_POP(swStk) ;
1300 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1301 STACK_POP(breakStack);
1305 while : WHILE { /* create and push the continue , break & body labels */
1306 static int Lblnum = 0 ;
1308 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1309 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1311 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1312 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1314 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1315 $$ = newSymbol(lbuff,NestLevel);
1319 do : DO { /* create and push the continue , break & body Labels */
1320 static int Lblnum = 0 ;
1323 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1324 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1326 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1327 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1329 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1330 $$ = newSymbol (lbuff,NestLevel);
1334 for : FOR { /* create & push continue, break & body labels */
1335 static int Lblnum = 0 ;
1338 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1339 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1341 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1342 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1344 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1345 $$ = newSymbol(lbuff,NestLevel);
1347 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1348 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1353 : while '(' expr ')' statement
1356 $$ = createWhile ( $1, STACK_POP(continueStack),
1357 STACK_POP(breakStack), $3, $5 );
1358 $$->lineno = $1->lineDef ;
1361 | do statement WHILE '(' expr ')' ';'
1364 $$ = createDo ( $1 , STACK_POP(continueStack),
1365 STACK_POP(breakStack), $5, $2);
1366 $$->lineno = $1->lineDef ;
1369 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1373 /* if break or continue statement present
1374 then create a general case loop */
1375 if (STACK_PEEK(continueStack)->isref ||
1376 STACK_PEEK(breakStack)->isref) {
1377 $$ = createFor ($1, STACK_POP(continueStack),
1378 STACK_POP(breakStack) ,
1379 STACK_POP(forStack) ,
1382 $$ = newNode(FOR,$9,NULL);
1383 AST_FOR($$,trueLabel) = $1;
1384 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1385 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1386 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1387 AST_FOR($$,initExpr) = $3;
1388 AST_FOR($$,condExpr) = $5;
1389 AST_FOR($$,loopExpr) = $7;
1402 : GOTO identifier ';' {
1404 $$ = newAst_VALUE(symbolVal($2));
1405 $$ = newNode(GOTO,$$,NULL);
1408 /* make sure continue is in context */
1409 if (STACK_PEEK(continueStack) == NULL) {
1410 werror(E_BREAK_CONTEXT);
1414 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1415 $$ = newNode(GOTO,$$,NULL);
1416 /* mark the continue label as referenced */
1417 STACK_PEEK(continueStack)->isref = 1;
1421 if (STACK_PEEK(breakStack) == NULL) {
1422 werror(E_BREAK_CONTEXT);
1425 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1426 $$ = newNode(GOTO,$$,NULL);
1427 STACK_PEEK(breakStack)->isref = 1;
1430 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1431 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1435 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }