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"); }
181 $$->class = SPECIFIER ;
182 FUNC_REGBANK($$) = (int) floatFromVal($2);
184 | REENTRANT { $$ = newLink ();
185 $$->class = SPECIFIER ;
188 | CRITICAL { $$ = newLink ();
189 $$->class = SPECIFIER ;
190 FUNC_ISCRITICAL($$) = 1;
192 | NAKED { $$ = newLink ();
193 $$->class = SPECIFIER ;
196 | JAVANATIVE { $$ = newLink ();
197 $$->class = SPECIFIER ;
198 FUNC_ISJAVANATIVE($$)=1;
200 | OVERLAY { $$ = newLink ();
201 $$->class = SPECIFIER ;
202 FUNC_ISOVERLAY($$)=1;
204 | NONBANKED {$$ = newLink ();
205 $$->class = SPECIFIER ;
206 FUNC_NONBANKED($$) = 1;
207 if (FUNC_BANKED($$)) {
208 werror(W_BANKED_WITH_NONBANKED);
211 | BANKED {$$ = newLink ();
212 $$->class = SPECIFIER ;
214 if (FUNC_NONBANKED($$)) {
215 werror(W_BANKED_WITH_NONBANKED);
218 werror(W_BANKED_WITH_STATIC);
224 $$->class = SPECIFIER ;
225 FUNC_INTNO($$) = $1 ;
232 | declaration_list compound_statement
234 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
240 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
241 | CONSTANT { $$ = newAst_VALUE($1); }
243 | '(' expr ')' { $$ = $2 ; }
247 : STRING_LITERAL { $$ = newAst_VALUE($1); }
252 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
253 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
254 $$->left->funcName = 1;}
255 | postfix_expr '(' argument_expr_list ')'
257 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
259 | postfix_expr '.' identifier
261 $3 = newSymbol($3->name,NestLevel);
263 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
264 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
266 | postfix_expr PTR_OP identifier
268 $3 = newSymbol($3->name,NestLevel);
270 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
272 | postfix_expr INC_OP
273 { $$ = newNode(INC_OP,$1,NULL);}
274 | postfix_expr DEC_OP
275 { $$ = newNode(DEC_OP,$1,NULL); }
280 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
285 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
286 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
287 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
288 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
289 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
290 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
304 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
309 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
310 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
311 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
315 : multiplicative_expr
316 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
317 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
322 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
323 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
328 | relational_expr '<' shift_expr {
330 newNode('!',newNode(GE_OP,$1,$3),NULL) :
331 newNode('<', $1,$3));
333 | relational_expr '>' shift_expr {
335 newNode('!',newNode(LE_OP,$1,$3),NULL) :
338 | relational_expr LE_OP shift_expr {
340 newNode('!', newNode('>', $1 , $3 ), NULL) :
341 newNode(LE_OP,$1,$3));
343 | relational_expr GE_OP shift_expr {
345 newNode('!', newNode('<', $1 , $3 ), NULL) :
346 newNode(GE_OP,$1,$3));
352 | equality_expr EQ_OP relational_expr {
354 newNode('!',newNode(NE_OP,$1,$3),NULL) :
355 newNode(EQ_OP,$1,$3));
357 | equality_expr NE_OP relational_expr {
359 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
360 newNode(NE_OP,$1,$3));
366 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
371 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
376 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
381 | logical_and_expr AND_OP inclusive_or_expr
382 { $$ = newNode(AND_OP,$1,$3);}
387 | logical_or_expr OR_OP logical_and_expr
388 { $$ = newNode(OR_OP,$1,$3); }
393 | logical_or_expr '?' logical_or_expr ':' conditional_expr
395 $$ = newNode(':',$3,$5) ;
396 $$ = newNode('?',$1,$$) ;
402 | unary_expr assignment_operator assignment_expr
407 $$ = newNode($2,$1,$3);
410 $$ = newNode('=',$1,newNode('*',removeIncDecOps(copyAst($1)),$3));
413 $$ = newNode('=',$1,newNode('/',removeIncDecOps(copyAst($1)),$3));
416 $$ = newNode('=',$1,newNode('%',removeIncDecOps(copyAst($1)),$3));
419 $$ = newNode('=',$1,newNode('+',removeIncDecOps(copyAst($1)),$3));
422 $$ = newNode('=',$1,newNode('-',removeIncDecOps(copyAst($1)),$3));
425 $$ = newNode('=',$1,newNode(LEFT_OP,removeIncDecOps(copyAst($1)),$3));
428 $$ = newNode('=',$1,newNode(RIGHT_OP,removeIncDecOps(copyAst($1)),$3));
431 $$ = newNode('=',$1,newNode('&',removeIncDecOps(copyAst($1)),$3));
434 $$ = newNode('=',$1,newNode('^',removeIncDecOps(copyAst($1)),$3));
437 $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3));
462 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
470 : declaration_specifiers ';' { $$ = NULL ; }
471 | declaration_specifiers init_declarator_list ';'
473 /* add the specifier list to the id */
476 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
477 sym_link *lnk = copyLinkChain($1);
478 /* do the pointer stuff */
479 pointerTypes(sym->type,lnk);
480 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, yytext);
500 $$ = mergeSpec($1,$2, yytext);
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, yytext);
514 $$ = mergeSpec($1,$2, yytext);
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
532 $$->class = SPECIFIER ;
533 SPEC_TYPEDEF($$) = 1 ;
537 $$->class = SPECIFIER ;
542 $$->class = SPECIFIER ;
547 $$->class = SPECIFIER ;
548 SPEC_SCLS($$) = S_AUTO ;
552 $$->class = SPECIFIER ;
553 SPEC_SCLS($$) = S_REGISTER ;
558 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
563 | type_specifier2 AT constant_expr
565 /* add this to the storage class specifier */
566 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
567 /* now get the abs addr from value */
568 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
575 $$->class = SPECIFIER ;
576 SPEC_NOUN($$) = V_CHAR ;
580 $$->class = SPECIFIER ;
581 $$->select.s._short = 1 ;
585 $$->class = SPECIFIER ;
586 SPEC_NOUN($$) = V_INT ;
590 $$->class = SPECIFIER ;
595 $$->class = SPECIFIER ;
596 $$->select.s._signed = 1;
600 $$->class = SPECIFIER ;
605 $$->class = SPECIFIER ;
606 SPEC_NOUN($$) = V_VOID ;
610 $$->class = SPECIFIER ;
615 $$->class = SPECIFIER ;
616 SPEC_VOLATILE($$) = 1 ;
620 SPEC_NOUN($$) = V_FLOAT;
621 $$->class = SPECIFIER ;
625 $$->class = SPECIFIER ;
626 SPEC_SCLS($$) = S_XDATA ;
630 $$->class = SPECIFIER ;
631 SPEC_SCLS($$) = S_CODE ;
635 $$->class = SPECIFIER ;
636 SPEC_SCLS($$) = S_EEPROM ;
640 $$->class = SPECIFIER ;
641 SPEC_SCLS($$) = S_DATA ;
645 $$->class = SPECIFIER ;
646 SPEC_SCLS($$) = S_IDATA ;
650 $$->class = SPECIFIER ;
651 SPEC_SCLS($$) = S_PDATA ;
655 $$->class = SPECIFIER ;
656 SPEC_NOUN($$) = V_BIT ;
657 SPEC_SCLS($$) = S_BIT ;
662 | struct_or_union_specifier
671 sym = findSym(TypedefTab,NULL,$1) ;
672 $$ = p = copyLinkChain(sym->type);
673 SPEC_TYPEDEF(getSpec(p)) = 0;
681 $$->class = SPECIFIER ;
682 SPEC_NOUN($$) = V_SBIT;
683 SPEC_SCLS($$) = S_SBIT;
687 $$->class = SPECIFIER ;
688 SPEC_NOUN($$) = V_CHAR;
689 SPEC_SCLS($$) = S_SFR ;
694 struct_or_union_specifier
695 : struct_or_union opt_stag '{' struct_declaration_list '}'
699 /* Create a structdef */
701 sdef->fields = reverseSyms($4) ; /* link the fields */
702 sdef->size = compStructSize($1,sdef); /* update size of */
704 /* Create the specifier */
706 $$->class = SPECIFIER ;
707 SPEC_NOUN($$) = V_STRUCT;
708 SPEC_STRUCT($$)= sdef ;
710 | struct_or_union stag
713 $$->class = SPECIFIER ;
714 SPEC_NOUN($$) = V_STRUCT;
715 SPEC_STRUCT($$) = $2 ;
720 : STRUCT { $$ = STRUCT ; }
721 | UNION { $$ = UNION ; }
726 | { /* synthesize a name add to structtable */
727 $$ = newStruct(genSymName(NestLevel)) ;
728 $$->level = NestLevel ;
729 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
733 : identifier { /* add name to structure table */
734 $$ = findSymWithBlock (StructTab,$1,currBlockno);
736 $$ = newStruct($1->name) ;
737 $$->level = NestLevel ;
738 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
743 struct_declaration_list
745 | 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,cloneSpec($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 {
792 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
793 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
795 | declarator ':' constant_expr
797 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
802 : ENUM '{' enumerator_list '}' {
804 //allocVariables(reverseSyms($3)) ;
805 $$ = copyLinkChain(cenum->type);
807 | ENUM identifier '{' enumerator_list '}' {
810 $2->type = copyLinkChain(cenum->type);
811 $2->etype = getSpec($2->type);
812 /* add this to the enumerator table */
813 if (!(csym=findSym(enumTab,$2,$2->name)) &&
814 (csym && csym->level == $2->level))
815 werror(E_DUPLICATE_TYPEDEF,csym->name);
817 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
819 //allocVariables (reverseSyms($4));
820 $$ = copyLinkChain(cenum->type);
821 SPEC_SCLS(getSpec($$)) = 0 ;
826 /* check the enumerator table */
827 if ((csym = findSym(enumTab,$2,$2->name)))
828 $$ = copyLinkChain(csym->type);
831 $$->class = SPECIFIER ;
832 SPEC_NOUN($$) = V_INT ;
835 SPEC_SCLS(getSpec($$)) = 0 ;
841 | enumerator_list ',' {
843 | enumerator_list ',' enumerator {
850 : identifier opt_assign_expr
852 /* make the symbol one level up */
854 $1->type = copyLinkChain($2->type);
855 $1->etype= getSpec($1->type);
856 SPEC_ENUM($1->etype) = 1;
858 // do this now, so we can use it for the next enums in the list
864 : '=' constant_expr {
867 val = constExprValue($2,TRUE);
872 SNPRINTF(lbuff, sizeof(lbuff),
873 "%d",(int) floatFromVal(cenum)+1);
874 $$ = cenum = constVal(lbuff);
877 SNPRINTF(lbuff, sizeof(lbuff),
879 $$ = cenum = constVal(lbuff);
885 : declarator2_function_attributes { $$ = $1; }
886 | pointer declarator2_function_attributes
888 addDecl ($2,0,reverseLink($1));
893 declarator2_function_attributes
894 : declarator2 { $$ = $1 ; }
895 | declarator2 function_attribute {
896 // copy the functionAttributes (not the args and hasVargs !!)
897 sym_link *funcType=$1->etype;
898 struct value *args=FUNC_ARGS(funcType);
899 unsigned hasVargs=FUNC_HASVARARGS(funcType);
901 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
902 sizeof($2->funcAttrs));
904 FUNC_ARGS(funcType)=args;
905 FUNC_HASVARARGS(funcType)=hasVargs;
908 memset (&$2->funcAttrs, 0,
909 sizeof($2->funcAttrs));
917 | '(' declarator ')' { $$ = $2; }
918 | declarator2 '[' ']'
923 DCL_TYPE(p) = ARRAY ;
927 | declarator2 '[' constant_expr ']'
932 p = (tval = constExprValue($3,TRUE))->etype;
933 /* if it is not a constant then Error */
934 if ( SPEC_SCLS(p) != S_LITERAL)
935 werror(E_CONST_EXPECTED) ;
938 DCL_TYPE(p) = ARRAY ;
939 DCL_ELEM(p) = (int) floatFromVal(tval) ;
943 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
944 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
947 addDecl ($1,FUNCTION,NULL) ;
949 FUNC_HASVARARGS($1->type) = IS_VARG($4);
950 FUNC_ARGS($1->type) = reverseVal($4);
952 /* nest level was incremented to take care of the parms */
956 // if this was a pointer (to a function)
957 if (IS_PTR($1->type)) {
958 // move the args and hasVargs to the function
959 FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
960 FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
961 memset (&$1->type->funcAttrs, 0,
962 sizeof($1->type->funcAttrs));
963 // remove the symbol args (if any)
964 cleanUpLevel(SymbolTab,NestLevel+1);
969 | declarator2 '(' parameter_identifier_list ')'
971 werror(E_OLD_STYLE,$1->name) ;
973 /* assume it returns an int */
974 $1->type = $1->etype = newIntLink();
980 : unqualified_pointer { $$ = $1 ;}
981 | unqualified_pointer type_specifier_list
986 | unqualified_pointer pointer
990 DCL_TYPE($2)=port->unqualified_pointer;
992 | unqualified_pointer type_specifier_list pointer
995 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
996 DCL_PTR_CONST($1) = SPEC_CONST($2);
997 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
998 switch (SPEC_SCLS($2)) {
1000 DCL_TYPE($3) = FPOINTER;
1003 DCL_TYPE($3) = IPOINTER ;
1006 DCL_TYPE($3) = PPOINTER ;
1009 DCL_TYPE($3) = POINTER ;
1012 DCL_PTR_CONST($3) = 1;
1013 DCL_TYPE($3) = CPOINTER ;
1016 DCL_TYPE($3) = EEPPOINTER;
1019 // this could be just "constant"
1020 // werror(W_PTR_TYPE_INVALID);
1025 werror (W_PTR_TYPE_INVALID);
1034 DCL_TYPE($$)=UPOINTER;
1040 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1041 | type_specifier_list type_specifier {
1042 /* if the decl $2 is not a specifier */
1043 /* find the spec and replace it */
1044 if ( !IS_SPEC($2)) {
1045 sym_link *lnk = $2 ;
1046 while (lnk && !IS_SPEC(lnk->next))
1048 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list");
1052 $$ = mergeSpec($1,$2, "type_specifier_list");
1056 parameter_identifier_list
1058 | identifier_list ',' ELIPSIS
1063 | identifier_list ',' identifier
1072 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1076 : parameter_declaration
1077 | parameter_list ',' parameter_declaration
1084 parameter_declaration
1085 : type_specifier_list declarator
1088 pointerTypes($2->type,$1);
1090 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1097 $$->etype = getSpec($$->type);
1102 : type_specifier_list { $$ = $1 ;}
1103 | type_specifier_list abstract_declarator
1105 /* go to the end of the list */
1107 pointerTypes($2,$1);
1108 for ( p = $2 ; p && p->next ; p=p->next);
1110 werror(E_SYNTAX_ERROR, yytext);
1119 : pointer { $$ = reverseLink($1); }
1120 | abstract_declarator2
1121 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1124 abstract_declarator2
1125 : '(' abstract_declarator ')' { $$ = $2 ; }
1128 DCL_TYPE($$) = ARRAY ;
1131 | '[' constant_expr ']' {
1134 DCL_TYPE($$) = ARRAY ;
1135 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1137 | abstract_declarator2 '[' ']' {
1139 DCL_TYPE($$) = ARRAY ;
1143 | abstract_declarator2 '[' constant_expr ']'
1147 DCL_TYPE($$) = ARRAY ;
1148 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1151 | '(' ')' { $$ = NULL;}
1152 | '(' parameter_type_list ')' { $$ = NULL;}
1153 | abstract_declarator2 '(' ')' {
1154 // $1 must be a pointer to a function
1155 sym_link *p=newLink();
1156 DCL_TYPE(p) = FUNCTION;
1158 // ((void (code *) ()) 0) ()
1160 DCL_TYPE($1)=CPOINTER;
1165 | abstract_declarator2 '(' parameter_type_list ')' {
1166 if (!IS_VOID($3->etype)) {
1167 // this is nonsense, so let's just burp something
1168 werror(E_TOO_FEW_PARMS);
1170 // $1 must be a pointer to a function
1171 sym_link *p=newLink();
1172 DCL_TYPE(p) = FUNCTION;
1174 // ((void (code *) (void)) 0) ()
1176 DCL_TYPE($1)=CPOINTER;
1185 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1186 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1187 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1192 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1197 | compound_statement
1198 | expression_statement
1199 | selection_statement
1200 | iteration_statement
1203 ast *ex = newNode(INLINEASM,NULL,NULL);
1204 ex->values.inlineasm = strdup($1);
1210 // : identifier ':' statement { $$ = createLabel($1,$3); }
1211 : identifier ':' { $$ = createLabel($1,NULL); }
1212 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1213 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1216 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1219 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1223 : start_block end_block { $$ = createBlock(NULL,NULL); }
1224 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1226 declaration_list { addSymChain($2); }
1227 end_block { $$ = createBlock($2,NULL) ; }
1229 declaration_list { addSymChain ($2); }
1231 end_block {$$ = createBlock($2,$4) ; }
1232 | error ';' { $$ = NULL ; }
1238 /* if this is typedef declare it immediately */
1239 if ( $1 && IS_TYPEDEF($1->etype)) {
1240 allocVariables ($1);
1247 | declaration_list declaration
1251 /* if this is a typedef */
1252 if ($2 && IS_TYPEDEF($2->etype)) {
1253 allocVariables ($2);
1257 /* get to the end of the previous decl */
1272 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1275 expression_statement
1281 : ELSE statement { $$ = $2 ; }
1287 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1288 | SWITCH '(' expr ')' {
1290 static int swLabel = 0 ;
1292 /* create a node for expression */
1293 ex = newNode(SWITCH,$3,NULL);
1294 STACK_PUSH(swStk,ex); /* save it in the stack */
1295 ex->values.switchVals.swNum = swLabel ;
1297 /* now create the label */
1298 SNPRINTF(lbuff, sizeof(lbuff),
1299 "_swBrk_%d",swLabel++);
1300 $<sym>$ = newSymbol(lbuff,NestLevel);
1301 /* put label in the break stack */
1302 STACK_PUSH(breakStack,$<sym>$);
1305 /* get back the switch form the stack */
1306 $$ = STACK_POP(swStk) ;
1307 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1308 STACK_POP(breakStack);
1312 while : WHILE { /* create and push the continue , break & body labels */
1313 static int Lblnum = 0 ;
1315 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1316 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1318 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1319 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1321 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1322 $$ = newSymbol(lbuff,NestLevel);
1326 do : DO { /* create and push the continue , break & body Labels */
1327 static int Lblnum = 0 ;
1330 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1331 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1333 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1334 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1336 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1337 $$ = newSymbol (lbuff,NestLevel);
1341 for : FOR { /* create & push continue, break & body labels */
1342 static int Lblnum = 0 ;
1345 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1346 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1348 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1349 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1351 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1352 $$ = newSymbol(lbuff,NestLevel);
1354 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1355 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1360 : while '(' expr ')' statement
1363 $$ = createWhile ( $1, STACK_POP(continueStack),
1364 STACK_POP(breakStack), $3, $5 );
1365 $$->lineno = $1->lineDef ;
1368 | do statement WHILE '(' expr ')' ';'
1371 $$ = createDo ( $1 , STACK_POP(continueStack),
1372 STACK_POP(breakStack), $5, $2);
1373 $$->lineno = $1->lineDef ;
1376 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1380 /* if break or continue statement present
1381 then create a general case loop */
1382 if (STACK_PEEK(continueStack)->isref ||
1383 STACK_PEEK(breakStack)->isref) {
1384 $$ = createFor ($1, STACK_POP(continueStack),
1385 STACK_POP(breakStack) ,
1386 STACK_POP(forStack) ,
1389 $$ = newNode(FOR,$9,NULL);
1390 AST_FOR($$,trueLabel) = $1;
1391 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1392 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1393 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1394 AST_FOR($$,initExpr) = $3;
1395 AST_FOR($$,condExpr) = $5;
1396 AST_FOR($$,loopExpr) = $7;
1409 : GOTO identifier ';' {
1411 $$ = newAst_VALUE(symbolVal($2));
1412 $$ = newNode(GOTO,$$,NULL);
1415 /* make sure continue is in context */
1416 if (STACK_PEEK(continueStack) == NULL) {
1417 werror(E_BREAK_CONTEXT);
1421 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1422 $$ = newNode(GOTO,$$,NULL);
1423 /* mark the continue label as referenced */
1424 STACK_PEEK(continueStack)->isref = 1;
1428 if (STACK_PEEK(breakStack) == NULL) {
1429 werror(E_BREAK_CONTEXT);
1432 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1433 $$ = newNode(GOTO,$$,NULL);
1434 STACK_PEEK(breakStack)->isref = 1;
1437 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1438 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1442 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }