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
96 %type <yyint> Interrupt_storage
97 %type <sym> identifier declarator declarator2 enumerator_list enumerator
98 %type <sym> struct_declarator
99 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
100 %type <sym> declaration init_declarator_list init_declarator
101 %type <sym> declaration_list identifier_list parameter_identifier_list
102 %type <sym> declarator2_function_attributes while do for
103 %type <lnk> pointer type_specifier_list type_specifier type_name
104 %type <lnk> storage_class_specifier struct_or_union_specifier
105 %type <lnk> declaration_specifiers sfr_reg_bit type_specifier2
106 %type <lnk> function_attribute function_attributes enum_specifier
107 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
108 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
109 %type <sdef> stag opt_stag
110 %type <asts> primary_expr
111 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
112 %type <asts> additive_expr shift_expr relational_expr equality_expr
113 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
114 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
115 %type <asts> expr argument_expr_list function_definition expr_opt
116 %type <asts> statement_list statement labeled_statement compound_statement
117 %type <asts> expression_statement selection_statement iteration_statement
118 %type <asts> jump_statement function_body else_statement string_literal
119 %type <ilist> initializer initializer_list
120 %type <yyint> unary_operator assignment_operator struct_or_union
127 : external_definition
128 | file external_definition
132 : function_definition {
137 && IS_FUNC($1->type))
139 /* The only legal storage classes for
140 * a function prototype (declaration)
141 * are extern and static. extern is the
142 * default. Thus, if this function isn't
143 * explicitly marked static, mark it
147 && IS_SPEC($1->etype)
148 && !SPEC_STAT($1->etype))
150 SPEC_EXTR($1->etype) = 1;
154 allocVariables ($1) ;
155 cleanUpLevel (SymbolTab,1);
160 : declarator function_body { /* function type not specified */
161 /* assume it to be 'int' */
162 addDecl($1,0,newIntLink());
163 $$ = createFunction($1,$2);
165 | declaration_specifiers declarator function_body
167 pointerTypes($2->type,copyLinkChain($1));
169 $$ = createFunction($2,$3);
174 : function_attributes
175 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
180 $$ = newLink(SPECIFIER) ;
181 FUNC_REGBANK($$) = (int) floatFromVal($2);
183 | REENTRANT { $$ = newLink (SPECIFIER);
186 | CRITICAL { $$ = newLink (SPECIFIER);
187 FUNC_ISCRITICAL($$) = 1;
189 | NAKED { $$ = newLink (SPECIFIER);
192 | JAVANATIVE { $$ = newLink (SPECIFIER);
193 FUNC_ISJAVANATIVE($$)=1;
195 | OVERLAY { $$ = newLink (SPECIFIER);
196 FUNC_ISOVERLAY($$)=1;
198 | NONBANKED {$$ = newLink (SPECIFIER);
199 FUNC_NONBANKED($$) = 1;
200 if (FUNC_BANKED($$)) {
201 werror(W_BANKED_WITH_NONBANKED);
204 | BANKED {$$ = newLink (SPECIFIER);
206 if (FUNC_NONBANKED($$)) {
207 werror(W_BANKED_WITH_NONBANKED);
210 werror(W_BANKED_WITH_STATIC);
215 $$ = newLink (SPECIFIER) ;
216 FUNC_INTNO($$) = $1 ;
223 | declaration_list compound_statement
225 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
231 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
232 | CONSTANT { $$ = newAst_VALUE($1); }
234 | '(' expr ')' { $$ = $2 ; }
238 : STRING_LITERAL { $$ = newAst_VALUE($1); }
243 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
244 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
245 $$->left->funcName = 1;}
246 | postfix_expr '(' argument_expr_list ')'
248 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
250 | postfix_expr '.' identifier
252 $3 = newSymbol($3->name,NestLevel);
254 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
255 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
257 | postfix_expr PTR_OP identifier
259 $3 = newSymbol($3->name,NestLevel);
261 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
263 | postfix_expr INC_OP
264 { $$ = newNode(INC_OP,$1,NULL);}
265 | postfix_expr DEC_OP
266 { $$ = newNode(DEC_OP,$1,NULL); }
271 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
276 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
277 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
278 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
279 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
280 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
281 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
295 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
300 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
301 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
302 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
306 : multiplicative_expr
307 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
308 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
313 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
314 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
319 | relational_expr '<' shift_expr {
321 newNode('!',newNode(GE_OP,$1,$3),NULL) :
322 newNode('<', $1,$3));
324 | relational_expr '>' shift_expr {
326 newNode('!',newNode(LE_OP,$1,$3),NULL) :
329 | relational_expr LE_OP shift_expr {
331 newNode('!', newNode('>', $1 , $3 ), NULL) :
332 newNode(LE_OP,$1,$3));
334 | relational_expr GE_OP shift_expr {
336 newNode('!', newNode('<', $1 , $3 ), NULL) :
337 newNode(GE_OP,$1,$3));
343 | equality_expr EQ_OP relational_expr {
345 newNode('!',newNode(NE_OP,$1,$3),NULL) :
346 newNode(EQ_OP,$1,$3));
348 | equality_expr NE_OP relational_expr {
350 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
351 newNode(NE_OP,$1,$3));
357 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
362 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
367 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
372 | logical_and_expr AND_OP inclusive_or_expr
373 { $$ = newNode(AND_OP,$1,$3);}
378 | logical_or_expr OR_OP logical_and_expr
379 { $$ = newNode(OR_OP,$1,$3); }
384 | logical_or_expr '?' logical_or_expr ':' conditional_expr
386 $$ = newNode(':',$3,$5) ;
387 $$ = newNode('?',$1,$$) ;
393 | unary_expr assignment_operator assignment_expr
398 $$ = newNode($2,$1,$3);
401 $$ = newNode('=',$1,newNode('*',removeIncDecOps(copyAst($1)),$3));
404 $$ = newNode('=',$1,newNode('/',removeIncDecOps(copyAst($1)),$3));
407 $$ = newNode('=',$1,newNode('%',removeIncDecOps(copyAst($1)),$3));
410 $$ = newNode('=',$1,newNode('+',removeIncDecOps(copyAst($1)),$3));
413 $$ = newNode('=',$1,newNode('-',removeIncDecOps(copyAst($1)),$3));
416 $$ = newNode('=',$1,newNode(LEFT_OP,removeIncDecOps(copyAst($1)),$3));
419 $$ = newNode('=',$1,newNode(RIGHT_OP,removeIncDecOps(copyAst($1)),$3));
422 $$ = newNode('=',$1,newNode('&',removeIncDecOps(copyAst($1)),$3));
425 $$ = newNode('=',$1,newNode('^',removeIncDecOps(copyAst($1)),$3));
428 $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3));
453 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
461 : declaration_specifiers ';' { $$ = NULL ; }
462 | declaration_specifiers init_declarator_list ';'
464 /* add the specifier list to the id */
467 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
468 sym_link *lnk = copyLinkChain($1);
469 /* do the pointer stuff */
470 pointerTypes(sym->type,lnk);
471 addDecl (sym,0,lnk) ;
478 declaration_specifiers
479 : storage_class_specifier { $$ = $1; }
480 | storage_class_specifier declaration_specifiers {
481 /* if the decl $2 is not a specifier */
482 /* find the spec and replace it */
485 while (lnk && !IS_SPEC(lnk->next))
487 lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
491 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
493 | type_specifier { $$ = $1; }
494 | type_specifier declaration_specifiers {
495 /* if the decl $2 is not a specifier */
496 /* find the spec and replace it */
499 while (lnk && !IS_SPEC(lnk->next))
501 lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
505 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
511 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
515 : declarator { $1->ival = NULL ; }
516 | declarator '=' initializer { $1->ival = $3 ; }
520 storage_class_specifier
522 $$ = newLink (SPECIFIER) ;
523 SPEC_TYPEDEF($$) = 1 ;
526 $$ = newLink(SPECIFIER);
530 $$ = newLink (SPECIFIER);
534 $$ = newLink (SPECIFIER) ;
535 SPEC_SCLS($$) = S_AUTO ;
538 $$ = newLink (SPECIFIER);
539 SPEC_SCLS($$) = S_REGISTER ;
544 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
549 | type_specifier2 AT constant_expr
551 /* add this to the storage class specifier */
552 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
553 /* now get the abs addr from value */
554 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
560 $$=newLink(SPECIFIER);
561 SPEC_NOUN($$) = V_CHAR ;
564 $$=newLink(SPECIFIER);
565 $$->select.s._short = 1 ;
568 $$=newLink(SPECIFIER);
569 SPEC_NOUN($$) = V_INT ;
572 $$=newLink(SPECIFIER);
576 $$=newLink(SPECIFIER);
577 $$->select.s._signed = 1;
580 $$=newLink(SPECIFIER);
584 $$=newLink(SPECIFIER);
585 SPEC_NOUN($$) = V_VOID ;
588 $$=newLink(SPECIFIER);
592 $$=newLink(SPECIFIER);
593 SPEC_VOLATILE($$) = 1 ;
596 $$=newLink(SPECIFIER);
597 SPEC_NOUN($$) = V_FLOAT;
600 $$ = newLink (SPECIFIER);
601 SPEC_SCLS($$) = S_XDATA ;
604 $$ = newLink (SPECIFIER) ;
605 SPEC_SCLS($$) = S_CODE ;
608 $$ = newLink (SPECIFIER) ;
609 SPEC_SCLS($$) = S_EEPROM ;
612 $$ = newLink (SPECIFIER);
613 SPEC_SCLS($$) = S_DATA ;
616 $$ = newLink (SPECIFIER);
617 SPEC_SCLS($$) = S_IDATA ;
620 $$ = newLink (SPECIFIER);
621 SPEC_SCLS($$) = S_PDATA ;
624 $$=newLink(SPECIFIER);
625 SPEC_NOUN($$) = V_BIT ;
626 SPEC_SCLS($$) = S_BIT ;
631 | struct_or_union_specifier
640 sym = findSym(TypedefTab,NULL,$1) ;
641 $$ = p = copyLinkChain(sym->type);
642 SPEC_TYPEDEF(getSpec(p)) = 0;
649 $$ = newLink(SPECIFIER) ;
650 SPEC_NOUN($$) = V_SBIT;
651 SPEC_SCLS($$) = S_SBIT;
654 $$ = newLink(SPECIFIER) ;
655 SPEC_NOUN($$) = V_CHAR;
656 SPEC_SCLS($$) = S_SFR ;
661 struct_or_union_specifier
662 : struct_or_union opt_stag '{' struct_declaration_list '}'
667 // check for duplicate structure members
668 for (sym=$4; sym; sym=sym->next) {
669 for (dsym=sym->next; dsym; dsym=dsym->next) {
670 if (strcmp(sym->name, dsym->name)==0) {
671 werror(E_DUPLICATE_MEMBER,
672 $1==STRUCT ? "struct" : "union", sym->name);
677 /* Create a structdef */
679 sdef->fields = reverseSyms($4) ; /* link the fields */
680 sdef->size = compStructSize($1,sdef); /* update size of */
682 /* Create the specifier */
683 $$ = newLink (SPECIFIER) ;
684 SPEC_NOUN($$) = V_STRUCT;
685 SPEC_STRUCT($$)= sdef ;
687 | struct_or_union stag
689 $$ = newLink(SPECIFIER) ;
690 SPEC_NOUN($$) = V_STRUCT;
691 SPEC_STRUCT($$) = $2 ;
696 : STRUCT { $$ = STRUCT ; }
697 | UNION { $$ = UNION ; }
702 | { /* synthesize a name add to structtable */
703 $$ = newStruct(genSymName(NestLevel)) ;
704 $$->level = NestLevel ;
705 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
709 : identifier { /* add name to structure table */
710 $$ = findSymWithBlock (StructTab,$1,currBlockno);
712 $$ = newStruct($1->name) ;
713 $$->level = NestLevel ;
714 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
719 struct_declaration_list
721 | struct_declaration_list struct_declaration
725 /* go to the end of the chain */
726 while (sym->next) sym=sym->next;
734 : type_specifier_list struct_declarator_list ';'
736 /* add this type to all the symbols */
738 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
740 /* make the symbol one level up */
743 pointerTypes(sym->type,copyLinkChain($1));
745 sym->type = copyLinkChain($1);
746 sym->etype = getSpec(sym->type);
749 addDecl (sym,0,copyLinkChain($1));
750 /* make sure the type is complete and sane */
751 checkTypeSanity(sym->etype, sym->name);
757 struct_declarator_list
759 | struct_declarator_list ',' struct_declarator
768 | ':' constant_expr {
769 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
770 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
772 | declarator ':' constant_expr
774 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
779 : ENUM '{' enumerator_list '}' {
783 // check for duplicate enums
784 for (sym=$3; sym; sym=sym->next) {
785 for (dsym=sym->next; dsym; dsym=dsym->next) {
786 if (strcmp(sym->name, dsym->name)==0) {
787 werror(E_DUPLICATE_MEMBER, "enum", sym->name);
793 $$ = copyLinkChain(cenum->type);
800 | ENUM identifier '{' enumerator_list '}' {
803 $2->type = copyLinkChain(cenum->type);
804 $2->etype = getSpec($2->type);
805 /* add this to the enumerator table */
806 if (!(csym=findSym(enumTab,$2,$2->name)) &&
807 (csym && csym->level == $2->level))
808 werror(E_DUPLICATE_TYPEDEF,csym->name);
810 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
812 //allocVariables (reverseSyms($4));
813 $$ = copyLinkChain(cenum->type);
814 SPEC_SCLS(getSpec($$)) = 0 ;
819 /* check the enumerator table */
820 if ((csym = findSym(enumTab,$2,$2->name)))
821 $$ = copyLinkChain(csym->type);
823 $$ = newLink(SPECIFIER) ;
824 SPEC_NOUN($$) = V_INT ;
827 SPEC_SCLS(getSpec($$)) = 0 ;
833 | enumerator_list ',' {
835 | enumerator_list ',' enumerator {
842 : identifier opt_assign_expr
844 /* make the symbol one level up */
846 $1->type = copyLinkChain($2->type);
847 $1->etype= getSpec($1->type);
848 SPEC_ENUM($1->etype) = 1;
850 // do this now, so we can use it for the next enums in the list
856 : '=' constant_expr {
859 val = constExprValue($2,TRUE);
864 SNPRINTF(lbuff, sizeof(lbuff),
865 "%d",(int) floatFromVal(cenum)+1);
866 $$ = cenum = constVal(lbuff);
869 SNPRINTF(lbuff, sizeof(lbuff),
871 $$ = cenum = constVal(lbuff);
877 : declarator2_function_attributes { $$ = $1; }
878 | pointer declarator2_function_attributes
880 addDecl ($2,0,reverseLink($1));
885 declarator2_function_attributes
886 : declarator2 { $$ = $1 ; }
887 | declarator2 function_attribute {
888 // copy the functionAttributes (not the args and hasVargs !!)
889 sym_link *funcType=$1->etype;
890 struct value *args=FUNC_ARGS(funcType);
891 unsigned hasVargs=FUNC_HASVARARGS(funcType);
893 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
894 sizeof($2->funcAttrs));
896 FUNC_ARGS(funcType)=args;
897 FUNC_HASVARARGS(funcType)=hasVargs;
900 memset (&$2->funcAttrs, 0,
901 sizeof($2->funcAttrs));
909 | '(' declarator ')' { $$ = $2; }
910 | declarator2 '[' ']'
914 p = newLink (DECLARATOR);
915 DCL_TYPE(p) = ARRAY ;
919 | declarator2 '[' constant_expr ']'
924 p = (tval = constExprValue($3,TRUE))->etype;
925 /* if it is not a constant then Error */
926 if ( SPEC_SCLS(p) != S_LITERAL)
927 werror(E_CONST_EXPECTED) ;
929 p = newLink (DECLARATOR);
930 DCL_TYPE(p) = ARRAY ;
931 DCL_ELEM(p) = (int) floatFromVal(tval) ;
935 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
936 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
939 addDecl ($1,FUNCTION,NULL) ;
941 FUNC_HASVARARGS($1->type) = IS_VARG($4);
942 FUNC_ARGS($1->type) = reverseVal($4);
944 /* nest level was incremented to take care of the parms */
948 // if this was a pointer (to a function)
949 if (IS_PTR($1->type)) {
950 // move the args and hasVargs to the function
951 FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
952 FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
953 memset (&$1->type->funcAttrs, 0,
954 sizeof($1->type->funcAttrs));
955 // remove the symbol args (if any)
956 cleanUpLevel(SymbolTab,NestLevel+1);
961 | declarator2 '(' parameter_identifier_list ')'
963 werror(E_OLD_STYLE,$1->name) ;
965 /* assume it returns an int */
966 $1->type = $1->etype = newIntLink();
972 : unqualified_pointer { $$ = $1 ;}
973 | unqualified_pointer type_specifier_list
978 | unqualified_pointer pointer
982 DCL_TYPE($2)=port->unqualified_pointer;
984 | unqualified_pointer type_specifier_list pointer
987 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
988 DCL_PTR_CONST($1) = SPEC_CONST($2);
989 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
990 switch (SPEC_SCLS($2)) {
992 DCL_TYPE($3) = FPOINTER;
995 DCL_TYPE($3) = IPOINTER ;
998 DCL_TYPE($3) = PPOINTER ;
1001 DCL_TYPE($3) = POINTER ;
1004 DCL_PTR_CONST($3) = 1;
1005 DCL_TYPE($3) = CPOINTER ;
1008 DCL_TYPE($3) = EEPPOINTER;
1011 // this could be just "constant"
1012 // werror(W_PTR_TYPE_INVALID);
1017 werror (W_PTR_TYPE_INVALID);
1025 $$ = newLink(DECLARATOR);
1026 DCL_TYPE($$)=UPOINTER;
1032 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1033 | type_specifier_list type_specifier {
1034 /* if the decl $2 is not a specifier */
1035 /* find the spec and replace it */
1036 if ( !IS_SPEC($2)) {
1037 sym_link *lnk = $2 ;
1038 while (lnk && !IS_SPEC(lnk->next))
1040 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1044 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1048 parameter_identifier_list
1050 | identifier_list ',' ELIPSIS
1055 | identifier_list ',' identifier
1064 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1068 : parameter_declaration
1069 | parameter_list ',' parameter_declaration
1076 parameter_declaration
1077 : type_specifier_list declarator
1080 pointerTypes($2->type,$1);
1082 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1089 $$->etype = getSpec($$->type);
1094 : type_specifier_list { $$ = $1 ;}
1095 | type_specifier_list abstract_declarator
1097 /* go to the end of the list */
1099 pointerTypes($2,$1);
1100 for ( p = $2 ; p && p->next ; p=p->next);
1102 werror(E_SYNTAX_ERROR, yytext);
1111 : pointer { $$ = reverseLink($1); }
1112 | abstract_declarator2
1113 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1116 abstract_declarator2
1117 : '(' abstract_declarator ')' { $$ = $2 ; }
1119 $$ = newLink (DECLARATOR);
1120 DCL_TYPE($$) = ARRAY ;
1123 | '[' constant_expr ']' {
1125 $$ = newLink (DECLARATOR);
1126 DCL_TYPE($$) = ARRAY ;
1127 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1129 | abstract_declarator2 '[' ']' {
1130 $$ = newLink (DECLARATOR);
1131 DCL_TYPE($$) = ARRAY ;
1135 | abstract_declarator2 '[' constant_expr ']'
1138 $$ = newLink (DECLARATOR);
1139 DCL_TYPE($$) = ARRAY ;
1140 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1143 | '(' ')' { $$ = NULL;}
1144 | '(' parameter_type_list ')' { $$ = NULL;}
1145 | abstract_declarator2 '(' ')' {
1146 // $1 must be a pointer to a function
1147 sym_link *p=newLink(DECLARATOR);
1148 DCL_TYPE(p) = FUNCTION;
1150 // ((void (code *) ()) 0) ()
1151 $1=newLink(DECLARATOR);
1152 DCL_TYPE($1)=CPOINTER;
1157 | abstract_declarator2 '(' parameter_type_list ')' {
1158 if (!IS_VOID($3->etype)) {
1159 // this is nonsense, so let's just burp something
1160 werror(E_TOO_FEW_PARMS);
1162 // $1 must be a pointer to a function
1163 sym_link *p=newLink(DECLARATOR);
1164 DCL_TYPE(p) = FUNCTION;
1166 // ((void (code *) (void)) 0) ()
1167 $1=newLink(DECLARATOR);
1168 DCL_TYPE($1)=CPOINTER;
1177 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1178 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1179 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1184 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1189 | compound_statement
1190 | expression_statement
1191 | selection_statement
1192 | iteration_statement
1195 ast *ex = newNode(INLINEASM,NULL,NULL);
1196 ex->values.inlineasm = strdup($1);
1202 // : identifier ':' statement { $$ = createLabel($1,$3); }
1203 : identifier ':' { $$ = createLabel($1,NULL); }
1204 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1205 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1208 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1211 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1215 : start_block end_block { $$ = createBlock(NULL,NULL); }
1216 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1218 declaration_list { addSymChain($2); }
1219 end_block { $$ = createBlock($2,NULL) ; }
1221 declaration_list { addSymChain ($2); }
1223 end_block {$$ = createBlock($2,$4) ; }
1224 | error ';' { $$ = NULL ; }
1230 /* if this is typedef declare it immediately */
1231 if ( $1 && IS_TYPEDEF($1->etype)) {
1232 allocVariables ($1);
1239 | declaration_list declaration
1243 /* if this is a typedef */
1244 if ($2 && IS_TYPEDEF($2->etype)) {
1245 allocVariables ($2);
1249 /* get to the end of the previous decl */
1264 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1267 expression_statement
1273 : ELSE statement { $$ = $2 ; }
1279 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1280 | SWITCH '(' expr ')' {
1282 static int swLabel = 0 ;
1284 /* create a node for expression */
1285 ex = newNode(SWITCH,$3,NULL);
1286 STACK_PUSH(swStk,ex); /* save it in the stack */
1287 ex->values.switchVals.swNum = swLabel ;
1289 /* now create the label */
1290 SNPRINTF(lbuff, sizeof(lbuff),
1291 "_swBrk_%d",swLabel++);
1292 $<sym>$ = newSymbol(lbuff,NestLevel);
1293 /* put label in the break stack */
1294 STACK_PUSH(breakStack,$<sym>$);
1297 /* get back the switch form the stack */
1298 $$ = STACK_POP(swStk) ;
1299 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1300 STACK_POP(breakStack);
1304 while : WHILE { /* create and push the continue , break & body labels */
1305 static int Lblnum = 0 ;
1307 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1308 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1310 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1311 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1313 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1314 $$ = newSymbol(lbuff,NestLevel);
1318 do : DO { /* create and push the continue , break & body Labels */
1319 static int Lblnum = 0 ;
1322 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1323 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1325 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1326 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1328 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1329 $$ = newSymbol (lbuff,NestLevel);
1333 for : FOR { /* create & push continue, break & body labels */
1334 static int Lblnum = 0 ;
1337 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1338 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1340 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1341 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1343 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1344 $$ = newSymbol(lbuff,NestLevel);
1346 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1347 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1352 : while '(' expr ')' statement
1355 $$ = createWhile ( $1, STACK_POP(continueStack),
1356 STACK_POP(breakStack), $3, $5 );
1357 $$->lineno = $1->lineDef ;
1360 | do statement WHILE '(' expr ')' ';'
1363 $$ = createDo ( $1 , STACK_POP(continueStack),
1364 STACK_POP(breakStack), $5, $2);
1365 $$->lineno = $1->lineDef ;
1368 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1372 /* if break or continue statement present
1373 then create a general case loop */
1374 if (STACK_PEEK(continueStack)->isref ||
1375 STACK_PEEK(breakStack)->isref) {
1376 $$ = createFor ($1, STACK_POP(continueStack),
1377 STACK_POP(breakStack) ,
1378 STACK_POP(forStack) ,
1381 $$ = newNode(FOR,$9,NULL);
1382 AST_FOR($$,trueLabel) = $1;
1383 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1384 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1385 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1386 AST_FOR($$,initExpr) = $3;
1387 AST_FOR($$,condExpr) = $5;
1388 AST_FOR($$,loopExpr) = $7;
1401 : GOTO identifier ';' {
1403 $$ = newAst_VALUE(symbolVal($2));
1404 $$ = newNode(GOTO,$$,NULL);
1407 /* make sure continue is in context */
1408 if (STACK_PEEK(continueStack) == NULL) {
1409 werror(E_BREAK_CONTEXT);
1413 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1414 $$ = newNode(GOTO,$$,NULL);
1415 /* mark the continue label as referenced */
1416 STACK_PEEK(continueStack)->isref = 1;
1420 if (STACK_PEEK(breakStack) == NULL) {
1421 werror(E_BREAK_CONTEXT);
1424 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1425 $$ = newNode(GOTO,$$,NULL);
1426 STACK_PEEK(breakStack)->isref = 1;
1429 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1430 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1434 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }