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 */
51 char lbuff[1024]; /* local buffer */
53 /* break & continue stacks */
54 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
55 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
56 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
57 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
58 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
60 value *cenum = NULL ; /* current enumeration type chain*/
61 bool uselessDecl = TRUE;
67 symbol *sym ; /* symbol table pointer */
68 structdef *sdef; /* structure definition */
69 char yychar[SDCC_NAME_MAX+1];
70 sym_link *lnk ; /* declarator or specifier */
71 int yyint; /* integer value returned */
72 value *val ; /* for integer constant */
73 initList *ilist; /* initial list */
74 const char *yyinline; /* inlined assembler code */
75 ast *asts; /* expression tree */
78 %token <yychar> IDENTIFIER TYPE_NAME
79 %token <val> CONSTANT STRING_LITERAL
81 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
83 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
84 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
85 %token <yyint> XOR_ASSIGN OR_ASSIGN
86 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
87 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
88 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
89 %token STRUCT UNION ENUM ELIPSIS RANGE FAR
90 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
91 %token NAKED JAVANATIVE OVERLAY
92 %token <yyinline> INLINEASM
93 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
94 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
96 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
97 %token DUMMY_READ_VOLATILE ENDCRITICAL
99 %type <yyint> Interrupt_storage
100 %type <sym> identifier declarator declarator2 enumerator_list enumerator
101 %type <sym> struct_declarator
102 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
103 %type <sym> declaration init_declarator_list init_declarator
104 %type <sym> declaration_list identifier_list parameter_identifier_list
105 %type <sym> declarator2_function_attributes while do for critical
106 %type <lnk> pointer type_specifier_list type_specifier type_name
107 %type <lnk> storage_class_specifier struct_or_union_specifier
108 %type <lnk> declaration_specifiers sfr_reg_bit type_specifier2
109 %type <lnk> function_attribute function_attributes enum_specifier
110 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
111 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
112 %type <sdef> stag opt_stag
113 %type <asts> primary_expr
114 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
115 %type <asts> additive_expr shift_expr relational_expr equality_expr
116 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
117 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
118 %type <asts> expr argument_expr_list function_definition expr_opt
119 %type <asts> statement_list statement labeled_statement compound_statement
120 %type <asts> expression_statement selection_statement iteration_statement
121 %type <asts> jump_statement function_body else_statement string_literal
122 %type <asts> critical_statement
123 %type <ilist> initializer initializer_list
124 %type <yyint> unary_operator assignment_operator struct_or_union
131 : external_definition
132 | file external_definition
136 : function_definition {
141 && IS_FUNC($1->type))
143 /* The only legal storage classes for
144 * a function prototype (declaration)
145 * are extern and static. extern is the
146 * default. Thus, if this function isn't
147 * explicitly marked static, mark it
151 && IS_SPEC($1->etype)
152 && !SPEC_STAT($1->etype))
154 SPEC_EXTR($1->etype) = 1;
158 allocVariables ($1) ;
159 cleanUpLevel (SymbolTab,1);
164 : declarator function_body { /* function type not specified */
165 /* assume it to be 'int' */
166 addDecl($1,0,newIntLink());
167 $$ = createFunction($1,$2);
169 | declaration_specifiers declarator function_body
171 pointerTypes($2->type,copyLinkChain($1));
173 $$ = createFunction($2,$3);
178 : function_attributes
179 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
184 $$ = newLink(SPECIFIER) ;
185 FUNC_REGBANK($$) = (int) floatFromVal($2);
187 | REENTRANT { $$ = newLink (SPECIFIER);
190 | CRITICAL { $$ = newLink (SPECIFIER);
191 FUNC_ISCRITICAL($$) = 1;
193 | NAKED { $$ = newLink (SPECIFIER);
196 | JAVANATIVE { $$ = newLink (SPECIFIER);
197 FUNC_ISJAVANATIVE($$)=1;
199 | OVERLAY { $$ = newLink (SPECIFIER);
200 FUNC_ISOVERLAY($$)=1;
202 | NONBANKED {$$ = newLink (SPECIFIER);
203 FUNC_NONBANKED($$) = 1;
204 if (FUNC_BANKED($$)) {
205 werror(W_BANKED_WITH_NONBANKED);
208 | BANKED {$$ = newLink (SPECIFIER);
210 if (FUNC_NONBANKED($$)) {
211 werror(W_BANKED_WITH_NONBANKED);
214 werror(W_BANKED_WITH_STATIC);
219 $$ = newLink (SPECIFIER) ;
220 FUNC_INTNO($$) = $1 ;
227 | declaration_list compound_statement
229 werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
235 : identifier { $$ = newAst_VALUE(symbolVal($1)); }
236 | CONSTANT { $$ = newAst_VALUE($1); }
238 | '(' expr ')' { $$ = $2 ; }
242 : STRING_LITERAL { $$ = newAst_VALUE($1); }
247 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3) ; }
248 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL);
249 $$->left->funcName = 1;}
250 | postfix_expr '(' argument_expr_list ')'
252 $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
254 | postfix_expr '.' identifier
256 $3 = newSymbol($3->name,NestLevel);
258 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
259 /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
261 | postfix_expr PTR_OP identifier
263 $3 = newSymbol($3->name,NestLevel);
265 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
267 | postfix_expr INC_OP
268 { $$ = newNode(INC_OP,$1,NULL);}
269 | postfix_expr DEC_OP
270 { $$ = newNode(DEC_OP,$1,NULL); }
275 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); }
280 | INC_OP unary_expr { $$ = newNode(INC_OP,NULL,$2); }
281 | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); }
282 | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; }
283 | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); }
284 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
285 | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); }
299 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
304 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);}
305 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);}
306 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);}
310 : multiplicative_expr
311 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);}
312 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);}
317 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); }
318 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); }
323 | relational_expr '<' shift_expr {
325 newNode('!',newNode(GE_OP,$1,$3),NULL) :
326 newNode('<', $1,$3));
328 | relational_expr '>' shift_expr {
330 newNode('!',newNode(LE_OP,$1,$3),NULL) :
333 | relational_expr LE_OP shift_expr {
335 newNode('!', newNode('>', $1 , $3 ), NULL) :
336 newNode(LE_OP,$1,$3));
338 | relational_expr GE_OP shift_expr {
340 newNode('!', newNode('<', $1 , $3 ), NULL) :
341 newNode(GE_OP,$1,$3));
347 | equality_expr EQ_OP relational_expr {
349 newNode('!',newNode(NE_OP,$1,$3),NULL) :
350 newNode(EQ_OP,$1,$3));
352 | equality_expr NE_OP relational_expr {
354 newNode('!', newNode(EQ_OP,$1,$3), NULL) :
355 newNode(NE_OP,$1,$3));
361 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);}
366 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);}
371 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);}
376 | logical_and_expr AND_OP inclusive_or_expr
377 { $$ = newNode(AND_OP,$1,$3);}
382 | logical_or_expr OR_OP logical_and_expr
383 { $$ = newNode(OR_OP,$1,$3); }
388 | logical_or_expr '?' logical_or_expr ':' conditional_expr
390 $$ = newNode(':',$3,$5) ;
391 $$ = newNode('?',$1,$$) ;
397 | unary_expr assignment_operator assignment_expr
402 $$ = newNode($2,$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('-',removeIncDecOps(copyAst($1)),$3));
420 $$ = newNode('=',$1,newNode(LEFT_OP,removeIncDecOps(copyAst($1)),$3));
423 $$ = newNode('=',$1,newNode(RIGHT_OP,removeIncDecOps(copyAst($1)),$3));
426 $$ = newNode('=',$1,newNode('&',removeIncDecOps(copyAst($1)),$3));
429 $$ = newNode('=',$1,newNode('^',removeIncDecOps(copyAst($1)),$3));
432 $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3));
457 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
465 : declaration_specifiers ';'
468 werror(W_USELESS_DECL);
472 | declaration_specifiers init_declarator_list ';'
474 /* add the specifier list to the id */
477 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
478 sym_link *lnk = copyLinkChain($1);
479 /* do the pointer stuff */
480 pointerTypes(sym->type,lnk);
481 addDecl (sym,0,lnk) ;
489 declaration_specifiers
490 : storage_class_specifier { $$ = $1; }
491 | storage_class_specifier declaration_specifiers {
492 /* if the decl $2 is not a specifier */
493 /* find the spec and replace it */
496 while (lnk && !IS_SPEC(lnk->next))
498 lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
502 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
504 | type_specifier { $$ = $1; }
505 | type_specifier declaration_specifiers {
506 /* if the decl $2 is not a specifier */
507 /* find the spec and replace it */
510 while (lnk && !IS_SPEC(lnk->next))
512 lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
516 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
522 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
526 : declarator { $1->ival = NULL ; }
527 | declarator '=' initializer { $1->ival = $3 ; }
531 storage_class_specifier
533 $$ = newLink (SPECIFIER) ;
534 SPEC_TYPEDEF($$) = 1 ;
537 $$ = newLink(SPECIFIER);
541 $$ = newLink (SPECIFIER);
545 $$ = newLink (SPECIFIER) ;
546 SPEC_SCLS($$) = S_AUTO ;
549 $$ = newLink (SPECIFIER);
550 SPEC_SCLS($$) = S_REGISTER ;
555 : INTERRUPT { $$ = INTNO_UNSPEC ; }
557 { int intno = (int) floatFromVal($2);
558 if ((intno >= 0) && (intno <= INTNO_MAX))
562 werror(E_INT_BAD_INTNO, intno);
570 | type_specifier2 AT constant_expr
572 /* add this to the storage class specifier */
573 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
574 /* now get the abs addr from value */
575 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
581 $$=newLink(SPECIFIER);
582 SPEC_NOUN($$) = V_CHAR ;
585 $$=newLink(SPECIFIER);
586 $$->select.s._short = 1 ;
589 $$=newLink(SPECIFIER);
590 SPEC_NOUN($$) = V_INT ;
593 $$=newLink(SPECIFIER);
597 $$=newLink(SPECIFIER);
598 $$->select.s._signed = 1;
601 $$=newLink(SPECIFIER);
605 $$=newLink(SPECIFIER);
606 SPEC_NOUN($$) = V_VOID ;
609 $$=newLink(SPECIFIER);
613 $$=newLink(SPECIFIER);
614 SPEC_VOLATILE($$) = 1 ;
617 $$=newLink(SPECIFIER);
618 SPEC_NOUN($$) = V_FLOAT;
621 $$ = newLink (SPECIFIER);
622 SPEC_SCLS($$) = S_XDATA ;
625 $$ = newLink (SPECIFIER) ;
626 SPEC_SCLS($$) = S_CODE ;
629 $$ = newLink (SPECIFIER) ;
630 SPEC_SCLS($$) = S_EEPROM ;
633 $$ = newLink (SPECIFIER);
634 SPEC_SCLS($$) = S_DATA ;
637 $$ = newLink (SPECIFIER);
638 SPEC_SCLS($$) = S_IDATA ;
641 $$ = newLink (SPECIFIER);
642 SPEC_SCLS($$) = S_PDATA ;
645 $$=newLink(SPECIFIER);
646 SPEC_NOUN($$) = V_BIT ;
647 SPEC_SCLS($$) = S_BIT ;
652 | struct_or_union_specifier {
665 sym = findSym(TypedefTab,NULL,$1) ;
666 $$ = p = copyLinkChain(sym->type);
667 SPEC_TYPEDEF(getSpec(p)) = 0;
674 $$ = newLink(SPECIFIER) ;
675 SPEC_NOUN($$) = V_SBIT;
676 SPEC_SCLS($$) = S_SBIT;
679 $$ = newLink(SPECIFIER) ;
680 SPEC_NOUN($$) = V_CHAR;
681 SPEC_SCLS($$) = S_SFR ;
686 struct_or_union_specifier
687 : struct_or_union opt_stag '{' struct_declaration_list '}'
692 // check for duplicate structure members
693 for (sym=$4; sym; sym=sym->next) {
694 for (dsym=sym->next; dsym; dsym=dsym->next) {
695 if (strcmp(sym->name, dsym->name)==0) {
696 werror(E_DUPLICATE_MEMBER,
697 $1==STRUCT ? "struct" : "union", sym->name);
702 /* Create a structdef */
704 sdef->fields = reverseSyms($4) ; /* link the fields */
705 sdef->size = compStructSize($1,sdef); /* update size of */
707 /* Create the specifier */
708 $$ = newLink (SPECIFIER) ;
709 SPEC_NOUN($$) = V_STRUCT;
710 SPEC_STRUCT($$)= sdef ;
712 | struct_or_union stag
714 $$ = newLink(SPECIFIER) ;
715 SPEC_NOUN($$) = V_STRUCT;
716 SPEC_STRUCT($$) = $2 ;
721 : STRUCT { $$ = STRUCT ; }
722 | UNION { $$ = UNION ; }
727 | { /* synthesize a name add to structtable */
728 $$ = newStruct(genSymName(NestLevel)) ;
729 $$->level = NestLevel ;
730 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
734 : identifier { /* add name to structure table */
735 $$ = findSymWithBlock (StructTab,$1,currBlockno);
737 $$ = newStruct($1->name) ;
738 $$->level = NestLevel ;
739 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
744 struct_declaration_list
746 | struct_declaration_list struct_declaration
750 /* go to the end of the chain */
751 while (sym->next) sym=sym->next;
759 : type_specifier_list struct_declarator_list ';'
761 /* add this type to all the symbols */
763 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
765 /* make the symbol one level up */
768 pointerTypes(sym->type,copyLinkChain($1));
770 sym->type = copyLinkChain($1);
771 sym->etype = getSpec(sym->type);
774 addDecl (sym,0,copyLinkChain($1));
775 /* make sure the type is complete and sane */
776 checkTypeSanity(sym->etype, sym->name);
782 struct_declarator_list
784 | struct_declarator_list ',' struct_declarator
793 | ':' constant_expr {
795 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
796 bitsize= (int) floatFromVal(constExprValue($2,TRUE));
797 if (bitsize > (port->s.int_size * 8)) {
798 bitsize = port->s.int_size * 8;
799 werror(E_BITFLD_SIZE, bitsize);
802 bitsize = BITVAR_PAD;
803 $$->bitVar = bitsize;
805 | declarator ':' constant_expr
808 bitsize= (int) floatFromVal(constExprValue($3,TRUE));
809 if (bitsize > (port->s.int_size * 8)) {
810 bitsize = port->s.int_size * 8;
811 werror(E_BITFLD_SIZE, bitsize);
814 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
815 $$->bitVar = BITVAR_PAD;
816 werror(W_BITFLD_NAMED);
819 $1->bitVar = bitsize;
824 : ENUM '{' enumerator_list '}' {
828 // check for duplicate enums
829 for (sym=$3; sym; sym=sym->next) {
830 for (dsym=sym->next; dsym; dsym=dsym->next) {
831 if (strcmp(sym->name, dsym->name)==0) {
832 werror(E_DUPLICATE_MEMBER, "enum", sym->name);
838 $$ = copyLinkChain(cenum->type);
845 | ENUM identifier '{' enumerator_list '}' {
848 $2->type = copyLinkChain(cenum->type);
849 $2->etype = getSpec($2->type);
850 /* add this to the enumerator table */
851 if (!(csym=findSym(enumTab,$2,$2->name)) &&
852 (csym && csym->level == $2->level))
853 werror(E_DUPLICATE_TYPEDEF,csym->name);
855 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
857 //allocVariables (reverseSyms($4));
858 $$ = copyLinkChain(cenum->type);
859 SPEC_SCLS(getSpec($$)) = 0 ;
864 /* check the enumerator table */
865 if ((csym = findSym(enumTab,$2,$2->name)))
866 $$ = copyLinkChain(csym->type);
868 $$ = newLink(SPECIFIER) ;
869 SPEC_NOUN($$) = V_INT ;
872 SPEC_SCLS(getSpec($$)) = 0 ;
878 | enumerator_list ',' {
880 | enumerator_list ',' enumerator {
887 : identifier opt_assign_expr
889 /* make the symbol one level up */
891 $1->type = copyLinkChain($2->type);
892 $1->etype= getSpec($1->type);
893 SPEC_ENUM($1->etype) = 1;
895 // do this now, so we can use it for the next enums in the list
901 : '=' constant_expr {
904 val = constExprValue($2,TRUE);
909 SNPRINTF(lbuff, sizeof(lbuff),
910 "%d",(int) floatFromVal(cenum)+1);
911 $$ = cenum = constVal(lbuff);
914 SNPRINTF(lbuff, sizeof(lbuff),
916 $$ = cenum = constVal(lbuff);
922 : declarator2_function_attributes { $$ = $1; }
923 | pointer declarator2_function_attributes
925 addDecl ($2,0,reverseLink($1));
930 declarator2_function_attributes
931 : declarator2 { $$ = $1 ; }
932 | declarator2 function_attribute {
933 if ((! $1) || (! IS_FUNC($1->etype)))
935 // function_attribute is only allowed if declarator2 was
936 // an actual function
942 // copy the functionAttributes (not the args and hasVargs !!)
943 sym_link *funcType=$1->etype;
944 struct value *args=FUNC_ARGS(funcType);
945 unsigned hasVargs=FUNC_HASVARARGS(funcType);
947 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
948 sizeof($2->funcAttrs));
950 FUNC_ARGS(funcType)=args;
951 FUNC_HASVARARGS(funcType)=hasVargs;
954 memset (&$2->funcAttrs, 0,
955 sizeof($2->funcAttrs));
964 | '(' declarator ')' { $$ = $2; }
965 | declarator2 '[' ']'
969 p = newLink (DECLARATOR);
970 DCL_TYPE(p) = ARRAY ;
974 | declarator2 '[' constant_expr ']'
979 p = (tval = constExprValue($3,TRUE))->etype;
980 /* if it is not a constant then Error */
981 if ( SPEC_SCLS(p) != S_LITERAL)
982 werror(E_CONST_EXPECTED) ;
984 p = newLink (DECLARATOR);
985 DCL_TYPE(p) = ARRAY ;
986 DCL_ELEM(p) = (int) floatFromVal(tval) ;
990 | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
991 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
994 addDecl ($1,FUNCTION,NULL) ;
996 FUNC_HASVARARGS($1->type) = IS_VARG($4);
997 FUNC_ARGS($1->type) = reverseVal($4);
999 /* nest level was incremented to take care of the parms */
1003 // if this was a pointer (to a function)
1004 if (IS_PTR($1->type)) {
1005 // move the args and hasVargs to the function
1006 FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
1007 FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
1008 memset (&$1->type->funcAttrs, 0,
1009 sizeof($1->type->funcAttrs));
1010 // remove the symbol args (if any)
1011 cleanUpLevel(SymbolTab,NestLevel+1);
1016 | declarator2 '(' parameter_identifier_list ')'
1018 werror(E_OLD_STYLE,$1->name) ;
1020 /* assume it returns an int */
1021 $1->type = $1->etype = newIntLink();
1027 : unqualified_pointer { $$ = $1 ;}
1028 | unqualified_pointer type_specifier_list
1032 DCL_PTR_CONST($1) = SPEC_CONST($2);
1033 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1035 | unqualified_pointer pointer
1039 DCL_TYPE($2)=port->unqualified_pointer;
1041 | unqualified_pointer type_specifier_list pointer
1044 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1045 DCL_PTR_CONST($1) = SPEC_CONST($2);
1046 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1047 switch (SPEC_SCLS($2)) {
1049 DCL_TYPE($3) = FPOINTER;
1052 DCL_TYPE($3) = IPOINTER ;
1055 DCL_TYPE($3) = PPOINTER ;
1058 DCL_TYPE($3) = POINTER ;
1061 DCL_TYPE($3) = CPOINTER ;
1064 DCL_TYPE($3) = EEPPOINTER;
1067 // this could be just "constant"
1068 // werror(W_PTR_TYPE_INVALID);
1073 werror (W_PTR_TYPE_INVALID);
1081 $$ = newLink(DECLARATOR);
1082 DCL_TYPE($$)=UPOINTER;
1088 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1089 | type_specifier_list type_specifier {
1090 /* if the decl $2 is not a specifier */
1091 /* find the spec and replace it */
1092 if ( !IS_SPEC($2)) {
1093 sym_link *lnk = $2 ;
1094 while (lnk && !IS_SPEC(lnk->next))
1096 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1100 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1104 parameter_identifier_list
1106 | identifier_list ',' ELIPSIS
1111 | identifier_list ',' identifier
1120 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1124 : parameter_declaration
1125 | parameter_list ',' parameter_declaration
1132 parameter_declaration
1133 : type_specifier_list declarator
1136 pointerTypes($2->type,$1);
1138 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1145 $$->etype = getSpec($$->type);
1150 : type_specifier_list { $$ = $1 ;}
1151 | type_specifier_list abstract_declarator
1153 /* go to the end of the list */
1155 pointerTypes($2,$1);
1156 for ( p = $2 ; p && p->next ; p=p->next);
1158 werror(E_SYNTAX_ERROR, yytext);
1167 : pointer { $$ = reverseLink($1); }
1168 | abstract_declarator2
1169 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1170 if (IS_PTR($1) && IS_FUNC($2))
1171 DCL_TYPE($1) = CPOINTER;
1175 abstract_declarator2
1176 : '(' abstract_declarator ')' { $$ = $2 ; }
1178 $$ = newLink (DECLARATOR);
1179 DCL_TYPE($$) = ARRAY ;
1182 | '[' constant_expr ']' {
1184 $$ = newLink (DECLARATOR);
1185 DCL_TYPE($$) = ARRAY ;
1186 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1188 | abstract_declarator2 '[' ']' {
1189 $$ = newLink (DECLARATOR);
1190 DCL_TYPE($$) = ARRAY ;
1194 | abstract_declarator2 '[' constant_expr ']'
1197 $$ = newLink (DECLARATOR);
1198 DCL_TYPE($$) = ARRAY ;
1199 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1202 | '(' ')' { $$ = NULL;}
1203 | '(' parameter_type_list ')' { $$ = NULL;}
1204 | abstract_declarator2 '(' ')' {
1205 // $1 must be a pointer to a function
1206 sym_link *p=newLink(DECLARATOR);
1207 DCL_TYPE(p) = FUNCTION;
1209 // ((void (code *) ()) 0) ()
1210 $1=newLink(DECLARATOR);
1211 DCL_TYPE($1)=CPOINTER;
1216 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1217 sym_link *p=newLink(DECLARATOR);
1218 DCL_TYPE(p) = FUNCTION;
1220 FUNC_HASVARARGS(p) = IS_VARG($4);
1221 FUNC_ARGS(p) = reverseVal($4);
1223 /* nest level was incremented to take care of the parms */
1229 // remove the symbol args (if any)
1230 cleanUpLevel(SymbolTab,NestLevel+1);
1235 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1236 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1237 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1242 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1247 | compound_statement
1248 | expression_statement
1249 | selection_statement
1250 | iteration_statement
1252 | critical_statement
1254 ast *ex = newNode(INLINEASM,NULL,NULL);
1255 ex->values.inlineasm = strdup($1);
1263 STACK_PUSH(continueStack,NULL);
1264 STACK_PUSH(breakStack,NULL);
1270 : critical statement {
1271 STACK_POP(breakStack);
1272 STACK_POP(continueStack);
1274 $$ = newNode(CRITICAL,$2,NULL);
1279 // : identifier ':' statement { $$ = createLabel($1,$3); }
1280 : identifier ':' { $$ = createLabel($1,NULL); }
1281 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1282 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1285 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1288 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1292 : start_block end_block { $$ = createBlock(NULL,NULL); }
1293 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1295 declaration_list { addSymChain($2); }
1296 end_block { $$ = createBlock($2,NULL) ; }
1298 declaration_list { addSymChain ($2); }
1300 end_block {$$ = createBlock($2,$4) ; }
1301 | error ';' { $$ = NULL ; }
1307 /* if this is typedef declare it immediately */
1308 if ( $1 && IS_TYPEDEF($1->etype)) {
1309 allocVariables ($1);
1316 | declaration_list declaration
1320 /* if this is a typedef */
1321 if ($2 && IS_TYPEDEF($2->etype)) {
1322 allocVariables ($2);
1326 /* get to the end of the previous decl */
1341 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1344 expression_statement
1350 : ELSE statement { $$ = $2 ; }
1356 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1357 | SWITCH '(' expr ')' {
1359 static int swLabel = 0 ;
1361 /* create a node for expression */
1362 ex = newNode(SWITCH,$3,NULL);
1363 STACK_PUSH(swStk,ex); /* save it in the stack */
1364 ex->values.switchVals.swNum = swLabel ;
1366 /* now create the label */
1367 SNPRINTF(lbuff, sizeof(lbuff),
1368 "_swBrk_%d",swLabel++);
1369 $<sym>$ = newSymbol(lbuff,NestLevel);
1370 /* put label in the break stack */
1371 STACK_PUSH(breakStack,$<sym>$);
1374 /* get back the switch form the stack */
1375 $$ = STACK_POP(swStk) ;
1376 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1377 STACK_POP(breakStack);
1381 while : WHILE { /* create and push the continue , break & body labels */
1382 static int Lblnum = 0 ;
1384 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1385 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1387 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1388 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1390 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1391 $$ = newSymbol(lbuff,NestLevel);
1395 do : DO { /* create and push the continue , break & body Labels */
1396 static int Lblnum = 0 ;
1399 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1400 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1402 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1403 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1405 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1406 $$ = newSymbol (lbuff,NestLevel);
1410 for : FOR { /* create & push continue, break & body labels */
1411 static int Lblnum = 0 ;
1414 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1415 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1417 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1418 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1420 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1421 $$ = newSymbol(lbuff,NestLevel);
1423 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1424 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1429 : while '(' expr ')' statement
1432 $$ = createWhile ( $1, STACK_POP(continueStack),
1433 STACK_POP(breakStack), $3, $5 );
1434 $$->lineno = $1->lineDef ;
1437 | do statement WHILE '(' expr ')' ';'
1440 $$ = createDo ( $1 , STACK_POP(continueStack),
1441 STACK_POP(breakStack), $5, $2);
1442 $$->lineno = $1->lineDef ;
1445 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1449 /* if break or continue statement present
1450 then create a general case loop */
1451 if (STACK_PEEK(continueStack)->isref ||
1452 STACK_PEEK(breakStack)->isref) {
1453 $$ = createFor ($1, STACK_POP(continueStack),
1454 STACK_POP(breakStack) ,
1455 STACK_POP(forStack) ,
1458 $$ = newNode(FOR,$9,NULL);
1459 AST_FOR($$,trueLabel) = $1;
1460 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1461 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1462 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1463 AST_FOR($$,initExpr) = $3;
1464 AST_FOR($$,condExpr) = $5;
1465 AST_FOR($$,loopExpr) = $7;
1478 : GOTO identifier ';' {
1480 $$ = newAst_VALUE(symbolVal($2));
1481 $$ = newNode(GOTO,$$,NULL);
1484 /* make sure continue is in context */
1485 if (STACK_PEEK(continueStack) == NULL) {
1486 werror(E_BREAK_CONTEXT);
1490 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1491 $$ = newNode(GOTO,$$,NULL);
1492 /* mark the continue label as referenced */
1493 STACK_PEEK(continueStack)->isref = 1;
1497 if (STACK_PEEK(breakStack) == NULL) {
1498 werror(E_BREAK_CONTEXT);
1501 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1502 $$ = newNode(GOTO,$$,NULL);
1503 STACK_PEEK(breakStack)->isref = 1;
1508 werror(E_INVALID_CRITICAL);
1511 $$ = newNode(RETURN,NULL,NULL);
1516 werror(E_INVALID_CRITICAL);
1519 $$ = newNode(RETURN,NULL,$2);
1525 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }