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"
38 extern int yyerror (char *);
40 int NestLevel = 0 ; /* current NestLevel */
41 int stackPtr = 1 ; /* stack pointer */
42 int xstackPtr = 0 ; /* xstack pointer */
44 int blockNo = 0 ; /* sequential block number */
49 char lbuff[1024]; /* local buffer */
51 /* break & continue stacks */
52 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
53 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
54 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
55 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
56 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
58 value *cenum = NULL ; /* current enumeration type chain*/
64 symbol *sym ; /* symbol table pointer */
65 structdef *sdef; /* structure definition */
66 char yychar[SDCC_NAME_MAX+1];
67 sym_link *lnk ; /* declarator or specifier */
68 int yyint; /* integer value returned */
69 value *val ; /* for integer constant */
70 initList *ilist; /* initial list */
71 char *yyinline; /* inlined assembler code */
72 ast *asts; /* expression tree */
75 %token <yychar> IDENTIFIER TYPE_NAME
76 %token <val> CONSTANT STRING_LITERAL
78 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
80 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
81 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
82 %token <yyint> XOR_ASSIGN OR_ASSIGN
83 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
84 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
85 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
86 %token STRUCT UNION ENUM ELIPSIS RANGE FAR
87 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
88 %token NAKED JAVANATIVE OVERLAY
89 %token <yyinline> INLINEASM
90 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
91 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
93 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
95 %type <yyint> Interrupt_storage
96 %type <sym> identifier declarator declarator2 enumerator_list enumerator
97 %type <sym> struct_declarator
98 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
99 %type <sym> declaration init_declarator_list init_declarator
100 %type <sym> declaration_list identifier_list parameter_identifier_list
101 %type <sym> declarator2_function_attributes while do for
102 %type <lnk> pointer type_specifier_list type_specifier type_name
103 %type <lnk> storage_class_specifier struct_or_union_specifier
104 %type <lnk> declaration_specifiers sfr_reg_bit type_specifier2
105 %type <lnk> function_attribute function_attributes enum_specifier
106 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
107 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
108 %type <sdef> stag opt_stag
109 %type <asts> primary_expr
110 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
111 %type <asts> additive_expr shift_expr relational_expr equality_expr
112 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
113 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
114 %type <asts> expr argument_expr_list function_definition expr_opt
115 %type <asts> statement_list statement labeled_statement compound_statement
116 %type <asts> expression_statement selection_statement iteration_statement
117 %type <asts> jump_statement function_body else_statement string_literal
118 %type <ilist> initializer initializer_list
119 %type <yyint> unary_operator assignment_operator struct_or_union
126 : external_definition
127 | file external_definition
131 : function_definition {
136 && IS_FUNC($1->type))
138 /* The only legal storage classes for
139 * a function prototype (declaration)
140 * are extern and static. extern is the
141 * default. Thus, if this function isn't
142 * explicitly marked static, mark it
146 && IS_SPEC($1->etype)
147 && !SPEC_STAT($1->etype))
149 SPEC_EXTR($1->etype) = 1;
153 allocVariables ($1) ;
154 cleanUpLevel (SymbolTab,1);
159 : declarator function_body { /* function type not specified */
160 /* assume it to be 'int' */
161 addDecl($1,0,newIntLink());
162 $$ = createFunction($1,$2);
164 | declaration_specifiers declarator function_body
166 pointerTypes($2->type,copyLinkChain($1));
168 $$ = createFunction($2,$3);
173 : function_attributes
174 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
180 $$->class = SPECIFIER ;
181 FUNC_REGBANK($$) = (int) floatFromVal($2);
183 | REENTRANT { $$ = newLink ();
184 $$->class = SPECIFIER ;
187 | CRITICAL { $$ = newLink ();
188 $$->class = SPECIFIER ;
189 FUNC_ISCRITICAL($$) = 1;
191 | NAKED { $$ = newLink ();
192 $$->class = SPECIFIER ;
195 | JAVANATIVE { $$ = newLink ();
196 $$->class = SPECIFIER ;
197 FUNC_ISJAVANATIVE($$)=1;
199 | OVERLAY { $$ = newLink ();
200 $$->class = SPECIFIER ;
201 FUNC_ISOVERLAY($$)=1;
203 | NONBANKED {$$ = newLink ();
204 $$->class = SPECIFIER ;
205 FUNC_NONBANKED($$) = 1;
206 if (FUNC_BANKED($$)) {
207 werror(W_BANKED_WITH_NONBANKED);
210 | BANKED {$$ = newLink ();
211 $$->class = SPECIFIER ;
213 if (FUNC_NONBANKED($$)) {
214 werror(W_BANKED_WITH_NONBANKED);
217 werror(W_BANKED_WITH_STATIC);
223 $$->class = SPECIFIER ;
224 FUNC_INTNO($$) = $1 ;
231 | declaration_list compound_statement
233 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
239 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
240 | CONSTANT { $$ = newAst_VALUE($1); }
242 | '(' expr ')' { $$ = $2 ; }
246 : STRING_LITERAL { $$ = newAst_VALUE($1); }
251 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
252 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
253 $$->left->funcName = 1;}
254 | postfix_expr '(' argument_expr_list ')'
256 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
258 | postfix_expr '.' identifier
260 $3 = newSymbol($3->name,NestLevel);
262 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
263 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
265 | postfix_expr PTR_OP identifier
267 $3 = newSymbol($3->name,NestLevel);
269 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
271 | postfix_expr INC_OP
272 { $$ = newNode(INC_OP,$1,NULL);}
273 | postfix_expr DEC_OP
274 { $$ = newNode(DEC_OP,$1,NULL); }
279 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
284 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
285 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
286 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
287 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
288 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
289 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
303 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
308 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
309 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
310 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
314 : multiplicative_expr
315 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
316 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
321 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
322 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
327 | relational_expr '<' shift_expr {
329 newNode('!',newNode(GE_OP,$1,$3),NULL) :
330 newNode('<', $1,$3));
332 | relational_expr '>' shift_expr {
334 newNode('!',newNode(LE_OP,$1,$3),NULL) :
337 | relational_expr LE_OP shift_expr {
339 newNode('!', newNode('>', $1 , $3 ), NULL) :
340 newNode(LE_OP,$1,$3));
342 | relational_expr GE_OP shift_expr {
344 newNode('!', newNode('<', $1 , $3 ), NULL) :
345 newNode(GE_OP,$1,$3));
351 | equality_expr EQ_OP relational_expr {
353 newNode('!',newNode(NE_OP,$1,$3),NULL) :
354 newNode(EQ_OP,$1,$3));
356 | equality_expr NE_OP relational_expr {
358 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
359 newNode(NE_OP,$1,$3));
365 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
370 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
375 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
380 | logical_and_expr AND_OP inclusive_or_expr
381 { $$ = newNode(AND_OP,$1,$3);}
386 | logical_or_expr OR_OP logical_and_expr
387 { $$ = newNode(OR_OP,$1,$3); }
392 | logical_or_expr '?' logical_or_expr ':' conditional_expr
394 $$ = newNode(':',$3,$5) ;
395 $$ = newNode('?',$1,$$) ;
401 | unary_expr assignment_operator assignment_expr
406 $$ = newNode($2,$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('+',removeIncDecOps(copyAst($1)),$3));
421 $$ = newNode('=',$1,newNode('-',removeIncDecOps(copyAst($1)),$3));
424 $$ = newNode('=',$1,newNode(LEFT_OP,removeIncDecOps(copyAst($1)),$3));
427 $$ = newNode('=',$1,newNode(RIGHT_OP,removeIncDecOps(copyAst($1)),$3));
430 $$ = newNode('=',$1,newNode('&',removeIncDecOps(copyAst($1)),$3));
433 $$ = newNode('=',$1,newNode('^',removeIncDecOps(copyAst($1)),$3));
436 $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3));
461 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
469 : declaration_specifiers ';' { $$ = NULL ; }
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) ;
486 declaration_specifiers
487 : storage_class_specifier { $$ = $1; }
488 | storage_class_specifier declaration_specifiers {
489 /* if the decl $2 is not a specifier */
490 /* find the spec and replace it */
493 while (lnk && !IS_SPEC(lnk->next))
495 lnk->next = mergeSpec($1,lnk->next, yytext);
499 $$ = mergeSpec($1,$2, yytext);
501 | type_specifier { $$ = $1; }
502 | type_specifier declaration_specifiers {
503 /* if the decl $2 is not a specifier */
504 /* find the spec and replace it */
507 while (lnk && !IS_SPEC(lnk->next))
509 lnk->next = mergeSpec($1,lnk->next, yytext);
513 $$ = mergeSpec($1,$2, yytext);
519 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
523 : declarator { $1->ival = NULL ; }
524 | declarator '=' initializer { $1->ival = $3 ; }
528 storage_class_specifier
531 $$->class = SPECIFIER ;
532 SPEC_TYPEDEF($$) = 1 ;
536 $$->class = SPECIFIER ;
541 $$->class = SPECIFIER ;
546 $$->class = SPECIFIER ;
547 SPEC_SCLS($$) = S_AUTO ;
551 $$->class = SPECIFIER ;
552 SPEC_SCLS($$) = S_REGISTER ;
557 : INTERRUPT CONSTANT { $$ = (int) floatFromVal($2) ; }
562 | type_specifier2 AT constant_expr
564 /* add this to the storage class specifier */
565 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
566 /* now get the abs addr from value */
567 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
574 $$->class = SPECIFIER ;
575 SPEC_NOUN($$) = V_CHAR ;
579 $$->class = SPECIFIER ;
580 $$->select.s._short = 1 ;
584 $$->class = SPECIFIER ;
585 SPEC_NOUN($$) = V_INT ;
589 $$->class = SPECIFIER ;
594 $$->class = SPECIFIER ;
595 $$->select.s._signed = 1;
599 $$->class = SPECIFIER ;
604 $$->class = SPECIFIER ;
605 SPEC_NOUN($$) = V_VOID ;
609 $$->class = SPECIFIER ;
614 $$->class = SPECIFIER ;
615 SPEC_VOLATILE($$) = 1 ;
619 SPEC_NOUN($$) = V_FLOAT;
620 $$->class = SPECIFIER ;
624 $$->class = SPECIFIER ;
625 SPEC_SCLS($$) = S_XDATA ;
629 $$->class = SPECIFIER ;
630 SPEC_SCLS($$) = S_CODE ;
634 $$->class = SPECIFIER ;
635 SPEC_SCLS($$) = S_EEPROM ;
639 $$->class = SPECIFIER ;
640 SPEC_SCLS($$) = S_DATA ;
644 $$->class = SPECIFIER ;
645 SPEC_SCLS($$) = S_IDATA ;
649 $$->class = SPECIFIER ;
650 SPEC_SCLS($$) = S_PDATA ;
654 $$->class = SPECIFIER ;
655 SPEC_NOUN($$) = V_BIT ;
656 SPEC_SCLS($$) = S_BIT ;
661 | struct_or_union_specifier
670 sym = findSym(TypedefTab,NULL,$1) ;
671 $$ = p = copyLinkChain(sym->type);
672 SPEC_TYPEDEF(getSpec(p)) = 0;
680 $$->class = SPECIFIER ;
681 SPEC_NOUN($$) = V_SBIT;
682 SPEC_SCLS($$) = S_SBIT;
686 $$->class = SPECIFIER ;
687 SPEC_NOUN($$) = V_CHAR;
688 SPEC_SCLS($$) = S_SFR ;
693 struct_or_union_specifier
694 : struct_or_union opt_stag '{' struct_declaration_list '}'
698 /* Create a structdef */
700 sdef->fields = reverseSyms($4) ; /* link the fields */
701 sdef->size = compStructSize($1,sdef); /* update size of */
703 /* Create the specifier */
705 $$->class = SPECIFIER ;
706 SPEC_NOUN($$) = V_STRUCT;
707 SPEC_STRUCT($$)= sdef ;
709 | struct_or_union stag
712 $$->class = 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
747 /* go to the end of the chain */
748 while (sym->next) sym = sym->next;
756 : type_specifier_list struct_declarator_list ';'
758 /* add this type to all the symbols */
760 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
762 /* make the symbol one level up */
765 pointerTypes(sym->type,copyLinkChain($1));
767 sym->type = copyLinkChain($1);
768 sym->etype = getSpec(sym->type);
771 addDecl (sym,0,cloneSpec($1));
772 /* make sure the type is complete and sane */
773 checkTypeSanity(sym->etype, sym->name);
779 struct_declarator_list
781 | struct_declarator_list ',' struct_declarator
790 | ':' constant_expr {
791 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
792 $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
794 | declarator ':' constant_expr
796 $1->bitVar = (int) floatFromVal(constExprValue($3,TRUE));
801 : ENUM '{' enumerator_list '}' {
803 //allocVariables(reverseSyms($3)) ;
804 $$ = copyLinkChain(cenum->type);
806 | ENUM identifier '{' enumerator_list '}' {
809 $2->type = copyLinkChain(cenum->type);
810 $2->etype = getSpec($2->type);
811 /* add this to the enumerator table */
812 if (!(csym=findSym(enumTab,$2,$2->name)) &&
813 (csym && csym->level == $2->level))
814 werror(E_DUPLICATE_TYPEDEF,csym->name);
816 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
818 //allocVariables (reverseSyms($4));
819 $$ = copyLinkChain(cenum->type);
820 SPEC_SCLS(getSpec($$)) = 0 ;
825 /* check the enumerator table */
826 if ((csym = findSym(enumTab,$2,$2->name)))
827 $$ = copyLinkChain(csym->type);
830 $$->class = SPECIFIER ;
831 SPEC_NOUN($$) = V_INT ;
834 SPEC_SCLS(getSpec($$)) = 0 ;
840 | enumerator_list ',' {
842 | enumerator_list ',' enumerator {
849 : identifier opt_assign_expr
851 /* make the symbol one level up */
853 $1->type = copyLinkChain($2->type);
854 $1->etype= getSpec($1->type);
855 SPEC_ENUM($1->etype) = 1;
857 // do this now, so we can use it for the next enums in the list
863 : '=' constant_expr {
866 val = constExprValue($2,TRUE);
871 sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1);
872 $$ = cenum = constVal(lbuff);
875 sprintf(lbuff,"%d",0);
876 $$ = cenum = constVal(lbuff);
882 : declarator2_function_attributes { $$ = $1; }
883 | pointer declarator2_function_attributes
885 addDecl ($2,0,reverseLink($1));
890 declarator2_function_attributes
891 : declarator2 { $$ = $1 ; }
892 | declarator2 function_attribute {
893 // copy the functionAttributes (not the args and hasVargs !!)
894 sym_link *funcType=$1->etype;
895 struct value *args=FUNC_ARGS(funcType);
896 unsigned hasVargs=FUNC_HASVARARGS(funcType);
898 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
899 sizeof($2->funcAttrs));
901 FUNC_ARGS(funcType)=args;
902 FUNC_HASVARARGS(funcType)=hasVargs;
905 memset (&$2->funcAttrs, 0,
906 sizeof($2->funcAttrs));
914 | '(' declarator ')' { $$ = $2; }
915 | declarator2 '[' ']'
920 DCL_TYPE(p) = ARRAY ;
924 | declarator2 '[' constant_expr ']'
929 p = (tval = constExprValue($3,TRUE))->etype;
930 /* if it is not a constant then Error */
931 if ( SPEC_SCLS(p) != S_LITERAL)
932 werror(E_CONST_EXPECTED) ;
935 DCL_TYPE(p) = ARRAY ;
936 DCL_ELEM(p) = (int) floatFromVal(tval) ;
940 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
941 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
944 addDecl ($1,FUNCTION,NULL) ;
946 FUNC_HASVARARGS($1->type) = IS_VARG($4);
947 FUNC_ARGS($1->type) = reverseVal($4);
949 /* nest level was incremented to take care of the parms */
953 // if this was a pointer (to a function)
954 if (IS_PTR($1->type)) {
955 // move the args and hasVargs to the function
956 FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
957 FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
958 memset (&$1->type->funcAttrs, 0,
959 sizeof($1->type->funcAttrs));
960 // remove the symbol args (if any)
961 cleanUpLevel(SymbolTab,NestLevel+1);
966 | declarator2 '(' parameter_identifier_list ')'
968 werror(E_OLD_STYLE,$1->name) ;
970 /* assume it returns an int */
971 $1->type = $1->etype = newIntLink();
977 : unqualified_pointer { $$ = $1 ;}
978 | unqualified_pointer type_specifier_list
983 | unqualified_pointer pointer
987 DCL_TYPE($2)=port->unqualified_pointer;
989 | unqualified_pointer type_specifier_list pointer
992 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
993 DCL_PTR_CONST($1) = SPEC_CONST($2);
994 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
995 switch (SPEC_SCLS($2)) {
997 DCL_TYPE($3) = FPOINTER;
1000 DCL_TYPE($3) = IPOINTER ;
1003 DCL_TYPE($3) = PPOINTER ;
1006 DCL_TYPE($3) = POINTER ;
1009 DCL_PTR_CONST($3) = 1;
1010 DCL_TYPE($3) = CPOINTER ;
1013 DCL_TYPE($3) = EEPPOINTER;
1016 // this could be just "constant"
1017 // werror(W_PTR_TYPE_INVALID);
1022 werror (W_PTR_TYPE_INVALID);
1031 DCL_TYPE($$)=UPOINTER;
1037 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1038 | type_specifier_list type_specifier {
1039 /* if the decl $2 is not a specifier */
1040 /* find the spec and replace it */
1041 if ( !IS_SPEC($2)) {
1042 sym_link *lnk = $2 ;
1043 while (lnk && !IS_SPEC(lnk->next))
1045 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list");
1049 $$ = mergeSpec($1,$2, "type_specifier_list");
1053 parameter_identifier_list
1055 | identifier_list ',' ELIPSIS
1060 | identifier_list ',' identifier
1069 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1073 : parameter_declaration
1074 | parameter_list ',' parameter_declaration
1081 parameter_declaration
1082 : type_specifier_list declarator
1085 pointerTypes($2->type,$1);
1087 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1094 $$->etype = getSpec($$->type);
1099 : type_specifier_list { $$ = $1 ;}
1100 | type_specifier_list abstract_declarator
1102 /* go to the end of the list */
1104 pointerTypes($2,$1);
1105 for ( p = $2 ; p && p->next ; p=p->next);
1107 werror(E_SYNTAX_ERROR, yytext);
1116 : pointer { $$ = reverseLink($1); }
1117 | abstract_declarator2
1118 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;}
1121 abstract_declarator2
1122 : '(' abstract_declarator ')' { $$ = $2 ; }
1125 DCL_TYPE($$) = ARRAY ;
1128 | '[' constant_expr ']' {
1131 DCL_TYPE($$) = ARRAY ;
1132 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1134 | abstract_declarator2 '[' ']' {
1136 DCL_TYPE($$) = ARRAY ;
1140 | abstract_declarator2 '[' constant_expr ']'
1144 DCL_TYPE($$) = ARRAY ;
1145 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1148 | '(' ')' { $$ = NULL;}
1149 | '(' parameter_type_list ')' { $$ = NULL;}
1150 | abstract_declarator2 '(' ')' {
1151 // $1 must be a pointer to a function
1152 sym_link *p=newLink();
1153 DCL_TYPE(p) = FUNCTION;
1155 // ((void (code *) ()) 0) ()
1157 DCL_TYPE($1)=CPOINTER;
1162 | abstract_declarator2 '(' parameter_type_list ')' {
1163 if (!IS_VOID($3->type)) {
1164 // this is nonsense, so let's just burp something
1165 werror(E_TOO_FEW_PARMS);
1167 // $1 must be a pointer to a function
1168 sym_link *p=newLink();
1169 DCL_TYPE(p) = FUNCTION;
1171 // ((void (code *) (void)) 0) ()
1173 DCL_TYPE($1)=CPOINTER;
1182 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1183 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1184 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1189 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1194 | compound_statement
1195 | expression_statement
1196 | selection_statement
1197 | iteration_statement
1200 ast *ex = newNode(INLINEASM,NULL,NULL);
1201 ex->values.inlineasm = malloc(strlen($1)+1);
1202 strcpy(ex->values.inlineasm,$1);
1208 // : identifier ':' statement { $$ = createLabel($1,$3); }
1209 : identifier ':' { $$ = createLabel($1,NULL); }
1210 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1211 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1214 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1217 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1221 : start_block end_block { $$ = createBlock(NULL,NULL); }
1222 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1224 declaration_list { addSymChain($2); }
1225 end_block { $$ = createBlock($2,NULL) ; }
1227 declaration_list { addSymChain ($2); }
1229 end_block {$$ = createBlock($2,$4) ; }
1230 | error ';' { $$ = NULL ; }
1236 /* if this is typedef declare it immediately */
1237 if ( $1 && IS_TYPEDEF($1->etype)) {
1238 allocVariables ($1);
1245 | declaration_list declaration
1249 /* if this is a typedef */
1250 if ($2 && IS_TYPEDEF($2->etype)) {
1251 allocVariables ($2);
1255 /* get to the end of the previous decl */
1270 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1273 expression_statement
1279 : ELSE statement { $$ = $2 ; }
1285 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1286 | SWITCH '(' expr ')' {
1288 static int swLabel = 0 ;
1290 /* create a node for expression */
1291 ex = newNode(SWITCH,$3,NULL);
1292 STACK_PUSH(swStk,ex); /* save it in the stack */
1293 ex->values.switchVals.swNum = swLabel ;
1295 /* now create the label */
1296 sprintf(lbuff,"_swBrk_%d",swLabel++);
1297 $<sym>$ = newSymbol(lbuff,NestLevel);
1298 /* put label in the break stack */
1299 STACK_PUSH(breakStack,$<sym>$);
1302 /* get back the switch form the stack */
1303 $$ = STACK_POP(swStk) ;
1304 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1305 STACK_POP(breakStack);
1309 while : WHILE { /* create and push the continue , break & body labels */
1310 static int Lblnum = 0 ;
1312 sprintf (lbuff,"_whilecontinue_%d",Lblnum);
1313 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1315 sprintf (lbuff,"_whilebreak_%d",Lblnum);
1316 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1318 sprintf (lbuff,"_whilebody_%d",Lblnum++);
1319 $$ = newSymbol(lbuff,NestLevel);
1323 do : DO { /* create and push the continue , break & body Labels */
1324 static int Lblnum = 0 ;
1327 sprintf(lbuff,"_docontinue_%d",Lblnum);
1328 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1330 sprintf (lbuff,"_dobreak_%d",Lblnum);
1331 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1333 sprintf (lbuff,"_dobody_%d",Lblnum++);
1334 $$ = newSymbol (lbuff,NestLevel);
1338 for : FOR { /* create & push continue, break & body labels */
1339 static int Lblnum = 0 ;
1342 sprintf (lbuff,"_forcontinue_%d",Lblnum);
1343 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1345 sprintf (lbuff,"_forbreak_%d",Lblnum);
1346 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1348 sprintf (lbuff,"_forbody_%d",Lblnum);
1349 $$ = newSymbol(lbuff,NestLevel);
1351 sprintf (lbuff,"_forcond_%d",Lblnum++);
1352 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1357 : while '(' expr ')' statement
1360 $$ = createWhile ( $1, STACK_POP(continueStack),
1361 STACK_POP(breakStack), $3, $5 );
1362 $$->lineno = $1->lineDef ;
1365 | do statement WHILE '(' expr ')' ';'
1368 $$ = createDo ( $1 , STACK_POP(continueStack),
1369 STACK_POP(breakStack), $5, $2);
1370 $$->lineno = $1->lineDef ;
1373 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1377 /* if break or continue statement present
1378 then create a general case loop */
1379 if (STACK_PEEK(continueStack)->isref ||
1380 STACK_PEEK(breakStack)->isref) {
1381 $$ = createFor ($1, STACK_POP(continueStack),
1382 STACK_POP(breakStack) ,
1383 STACK_POP(forStack) ,
1386 $$ = newNode(FOR,$9,NULL);
1387 AST_FOR($$,trueLabel) = $1;
1388 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1389 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1390 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1391 AST_FOR($$,initExpr) = $3;
1392 AST_FOR($$,condExpr) = $5;
1393 AST_FOR($$,loopExpr) = $7;
1406 : GOTO identifier ';' {
1408 $$ = newAst_VALUE(symbolVal($2));
1409 $$ = newNode(GOTO,$$,NULL);
1412 /* make sure continue is in context */
1413 if (STACK_PEEK(continueStack) == NULL) {
1414 werror(E_BREAK_CONTEXT);
1418 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1419 $$ = newNode(GOTO,$$,NULL);
1420 /* mark the continue label as referenced */
1421 STACK_PEEK(continueStack)->isref = 1;
1425 if (STACK_PEEK(breakStack) == NULL) {
1426 werror(E_BREAK_CONTEXT);
1429 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1430 $$ = newNode(GOTO,$$,NULL);
1431 STACK_PEEK(breakStack)->isref = 1;
1434 | RETURN ';' { $$ = newNode(RETURN,NULL,NULL) ; }
1435 | RETURN expr ';' { $$ = newNode(RETURN,NULL,$2) ; }
1439 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }