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 */
48 int seqPointNo= 1 ; /* sequence point number */
49 int ignoreTypedefType=0;
53 char lbuff[1024]; /* local buffer */
55 /* break & continue stacks */
56 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL)
57 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL)
58 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL)
59 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL)
60 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
62 value *cenum = NULL ; /* current enumeration type chain*/
63 bool uselessDecl = TRUE;
71 symbol *sym ; /* symbol table pointer */
72 structdef *sdef; /* structure definition */
73 char yychar[SDCC_NAME_MAX+1];
74 sym_link *lnk ; /* declarator or specifier */
75 int yyint; /* integer value returned */
76 value *val ; /* for integer constant */
77 initList *ilist; /* initial list */
78 const char *yyinline; /* inlined assembler code */
79 ast *asts; /* expression tree */
82 %token <yychar> IDENTIFIER TYPE_NAME
83 %token <val> CONSTANT STRING_LITERAL
85 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
87 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
88 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
89 %token <yyint> XOR_ASSIGN OR_ASSIGN
90 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
91 %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
92 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
93 %token STRUCT UNION ENUM ELIPSIS RANGE FAR
94 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
95 %token NAKED JAVANATIVE OVERLAY
96 %token <yyinline> INLINEASM
97 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
98 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
100 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
101 %token DUMMY_READ_VOLATILE ENDCRITICAL SWAP
103 %type <yyint> Interrupt_storage
104 %type <sym> identifier declarator declarator2 declarator3 enumerator_list enumerator
105 %type <sym> struct_declarator function_declarator function_declarator2
106 %type <sym> struct_declarator_list struct_declaration struct_declaration_list
107 %type <sym> declaration init_declarator_list init_declarator
108 %type <sym> declaration_list identifier_list parameter_identifier_list
109 %type <sym> declarator2_function_attributes while do for critical
110 %type <lnk> pointer type_specifier_list type_specifier type_name
111 %type <lnk> storage_class_specifier struct_or_union_specifier
112 %type <lnk> declaration_specifiers sfr_reg_bit sfr_attributes type_specifier2
113 %type <lnk> function_attribute function_attributes enum_specifier
114 %type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
115 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
116 %type <sdef> stag opt_stag
117 %type <asts> primary_expr
118 %type <asts> postfix_expr unary_expr cast_expr multiplicative_expr
119 %type <asts> additive_expr shift_expr relational_expr equality_expr
120 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr
121 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr
122 %type <asts> expr argument_expr_list function_definition expr_opt
123 %type <asts> statement_list statement labeled_statement compound_statement
124 %type <asts> expression_statement selection_statement iteration_statement
125 %type <asts> jump_statement function_body else_statement string_literal
126 %type <asts> critical_statement
127 %type <ilist> initializer initializer_list
128 %type <yyint> unary_operator assignment_operator struct_or_union
135 : external_definition
136 | file external_definition
140 : function_definition {
144 ignoreTypedefType = 0;
146 && IS_FUNC($1->type))
148 /* The only legal storage classes for
149 * a function prototype (declaration)
150 * are extern and static. extern is the
151 * default. Thus, if this function isn't
152 * explicitly marked static, mark it
156 && IS_SPEC($1->etype)
157 && !SPEC_STAT($1->etype))
159 SPEC_EXTR($1->etype) = 1;
163 allocVariables ($1) ;
164 cleanUpLevel (SymbolTab,1);
169 : function_declarator function_body { /* function type not specified */
170 /* assume it to be 'int' */
171 addDecl($1,0,newIntLink());
172 $$ = createFunction($1,$2);
174 | declaration_specifiers function_declarator function_body
176 pointerTypes($2->type,copyLinkChain($1));
178 $$ = createFunction($2,$3);
183 : function_attributes
184 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); }
189 $$ = newLink(SPECIFIER) ;
190 FUNC_REGBANK($$) = (int) floatFromVal($2);
192 | REENTRANT { $$ = newLink (SPECIFIER);
195 | CRITICAL { $$ = newLink (SPECIFIER);
196 FUNC_ISCRITICAL($$) = 1;
198 | NAKED { $$ = newLink (SPECIFIER);
201 | JAVANATIVE { $$ = newLink (SPECIFIER);
202 FUNC_ISJAVANATIVE($$)=1;
204 | OVERLAY { $$ = newLink (SPECIFIER);
205 FUNC_ISOVERLAY($$)=1;
207 | NONBANKED {$$ = newLink (SPECIFIER);
208 FUNC_NONBANKED($$) = 1;
209 if (FUNC_BANKED($$)) {
210 werror(W_BANKED_WITH_NONBANKED);
213 | BANKED {$$ = newLink (SPECIFIER);
215 if (FUNC_NONBANKED($$)) {
216 werror(W_BANKED_WITH_NONBANKED);
219 werror(W_BANKED_WITH_STATIC);
224 $$ = newLink (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 { seqPointNo++;} inclusive_or_expr
382 { $$ = newNode(AND_OP,$1,$4);}
387 | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr
388 { $$ = newNode(OR_OP,$1,$4); }
393 | logical_or_expr '?' { seqPointNo++;} logical_or_expr ':' conditional_expr
395 $$ = newNode(':',$4,$6) ;
396 $$ = newNode('?',$1,$$) ;
402 | unary_expr assignment_operator assignment_expr
407 $$ = newNode($2,$1,$3);
410 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
411 newNode('*',removePreIncDecOps(copyAst($1)),$3));
414 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
415 newNode('/',removePreIncDecOps(copyAst($1)),$3));
418 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
419 newNode('%',removePreIncDecOps(copyAst($1)),$3));
422 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
423 newNode('+',removePreIncDecOps(copyAst($1)),$3));
426 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
427 newNode('-',removePreIncDecOps(copyAst($1)),$3));
430 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
431 newNode(LEFT_OP,removePreIncDecOps(copyAst($1)),$3));
434 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
435 newNode(RIGHT_OP,removePreIncDecOps(copyAst($1)),$3));
438 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
439 newNode('&',removePreIncDecOps(copyAst($1)),$3));
442 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
443 newNode('^',removePreIncDecOps(copyAst($1)),$3));
446 /* $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); */
447 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
448 newNode('|',removePreIncDecOps(copyAst($1)),$3));
473 | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);}
481 : declaration_specifiers ';'
484 werror(W_USELESS_DECL);
488 | declaration_specifiers init_declarator_list ';'
490 /* add the specifier list to the id */
493 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
494 sym_link *lnk = copyLinkChain($1);
495 /* do the pointer stuff */
496 pointerTypes(sym->type,lnk);
497 addDecl (sym,0,lnk) ;
505 declaration_specifiers
506 : storage_class_specifier { $$ = $1; }
507 | storage_class_specifier declaration_specifiers {
508 /* if the decl $2 is not a specifier */
509 /* find the spec and replace it */
512 while (lnk && !IS_SPEC(lnk->next))
514 lnk->next = mergeSpec($1,lnk->next, "storage_class_specifier declaration_specifiers - skipped");
518 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
520 | type_specifier { $$ = $1; }
521 | type_specifier declaration_specifiers {
522 /* if the decl $2 is not a specifier */
523 /* find the spec and replace it */
526 while (lnk && !IS_SPEC(lnk->next))
528 lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
532 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
538 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
542 : declarator { $1->ival = NULL ; }
543 | declarator '=' initializer { $1->ival = $3 ; }
547 storage_class_specifier
549 $$ = newLink (SPECIFIER) ;
550 SPEC_TYPEDEF($$) = 1 ;
553 $$ = newLink(SPECIFIER);
557 $$ = newLink (SPECIFIER);
561 $$ = newLink (SPECIFIER) ;
562 SPEC_SCLS($$) = S_AUTO ;
565 $$ = newLink (SPECIFIER);
566 SPEC_SCLS($$) = S_REGISTER ;
571 : INTERRUPT { $$ = INTNO_UNSPEC ; }
573 { int intno = (int) floatFromVal($2);
574 if ((intno >= 0) && (intno <= INTNO_MAX))
578 werror(E_INT_BAD_INTNO, intno);
586 | type_specifier2 AT constant_expr
588 /* add this to the storage class specifier */
589 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
590 /* now get the abs addr from value */
591 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
597 $$=newLink(SPECIFIER);
598 SPEC_NOUN($$) = V_CHAR ;
599 ignoreTypedefType = 1;
602 $$=newLink(SPECIFIER);
603 $$->select.s._short = 1 ;
604 ignoreTypedefType = 1;
607 $$=newLink(SPECIFIER);
608 SPEC_NOUN($$) = V_INT ;
609 ignoreTypedefType = 1;
612 $$=newLink(SPECIFIER);
614 ignoreTypedefType = 1;
617 $$=newLink(SPECIFIER);
618 $$->select.s._signed = 1;
619 ignoreTypedefType = 1;
622 $$=newLink(SPECIFIER);
624 ignoreTypedefType = 1;
627 $$=newLink(SPECIFIER);
628 SPEC_NOUN($$) = V_VOID ;
629 ignoreTypedefType = 1;
632 $$=newLink(SPECIFIER);
636 $$=newLink(SPECIFIER);
637 SPEC_VOLATILE($$) = 1 ;
640 $$=newLink(SPECIFIER);
641 SPEC_NOUN($$) = V_FLOAT;
642 ignoreTypedefType = 1;
645 $$ = newLink (SPECIFIER);
646 SPEC_SCLS($$) = S_XDATA ;
649 $$ = newLink (SPECIFIER) ;
650 SPEC_SCLS($$) = S_CODE ;
653 $$ = newLink (SPECIFIER) ;
654 SPEC_SCLS($$) = S_EEPROM ;
657 $$ = newLink (SPECIFIER);
658 SPEC_SCLS($$) = S_DATA ;
661 $$ = newLink (SPECIFIER);
662 SPEC_SCLS($$) = S_IDATA ;
665 $$ = newLink (SPECIFIER);
666 SPEC_SCLS($$) = S_PDATA ;
669 $$=newLink(SPECIFIER);
670 SPEC_NOUN($$) = V_BIT ;
671 SPEC_SCLS($$) = S_BIT ;
674 ignoreTypedefType = 1;
677 | struct_or_union_specifier {
680 ignoreTypedefType = 1;
685 ignoreTypedefType = 1;
692 sym = findSym(TypedefTab,NULL,$1) ;
693 $$ = p = copyLinkChain(sym->type);
694 SPEC_TYPEDEF(getSpec(p)) = 0;
695 ignoreTypedefType = 1;
702 $$ = newLink(SPECIFIER) ;
703 SPEC_NOUN($$) = V_SBIT;
704 SPEC_SCLS($$) = S_SBIT;
705 ignoreTypedefType = 1;
712 $$ = newLink(SPECIFIER) ;
713 FUNC_REGBANK($$) = 0;
714 SPEC_NOUN($$) = V_CHAR;
715 SPEC_SCLS($$) = S_SFR ;
717 ignoreTypedefType = 1;
720 $$ = newLink(SPECIFIER) ;
721 FUNC_REGBANK($$) = 1;
722 SPEC_NOUN($$) = V_CHAR;
723 SPEC_SCLS($$) = S_SFR ;
725 ignoreTypedefType = 1;
729 struct_or_union_specifier
730 : struct_or_union opt_stag
739 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
743 '{' struct_declaration_list '}'
748 // check for errors in structure members
749 for (sym=$5; sym; sym=sym->next) {
750 if (IS_ABSOLUTE(sym->etype)) {
751 werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "'at'");
752 SPEC_ABSA(sym->etype) = 0;
754 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
755 werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "storage class");
756 SPEC_SCLS(sym->etype) = 0;
758 for (dsym=sym->next; dsym; dsym=dsym->next) {
759 if (strcmp(sym->name, dsym->name)==0) {
760 werrorfl(filename, sym->lineDef, E_DUPLICATE_MEMBER,
761 $1==STRUCT ? "struct" : "union", sym->name);
766 /* Create a structdef */
768 sdef->fields = reverseSyms($5) ; /* link the fields */
769 sdef->size = compStructSize($1,sdef); /* update size of */
771 /* Create the specifier */
772 $$ = newLink (SPECIFIER) ;
773 SPEC_NOUN($$) = V_STRUCT;
774 SPEC_STRUCT($$)= sdef ;
776 | struct_or_union stag
778 $$ = newLink(SPECIFIER) ;
779 SPEC_NOUN($$) = V_STRUCT;
780 SPEC_STRUCT($$) = $2;
789 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
795 : STRUCT { $$ = STRUCT ; }
796 | UNION { $$ = UNION ; }
801 | { /* synthesize a name add to structtable */
802 $$ = newStruct(genSymName(NestLevel)) ;
803 $$->level = NestLevel ;
804 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
808 : identifier { /* add name to structure table */
809 $$ = findSymWithBlock (StructTab,$1,currBlockno);
811 $$ = newStruct($1->name) ;
812 $$->level = NestLevel ;
813 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
818 struct_declaration_list
820 | struct_declaration_list struct_declaration
824 /* go to the end of the chain */
825 while (sym->next) sym=sym->next;
833 : type_specifier_list struct_declarator_list ';'
835 /* add this type to all the symbols */
837 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
838 sym_link *btype = copyLinkChain($1);
840 /* make the symbol one level up */
843 pointerTypes(sym->type,btype);
846 sym->etype = getSpec(sym->type);
849 addDecl (sym,0,btype);
850 /* make sure the type is complete and sane */
851 checkTypeSanity(sym->etype, sym->name);
853 ignoreTypedefType = 0;
858 struct_declarator_list
860 | struct_declarator_list ',' struct_declarator
869 | ':' constant_expr {
871 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
872 bitsize= (int) floatFromVal(constExprValue($2,TRUE));
873 if (bitsize > (port->s.int_size * 8)) {
874 bitsize = port->s.int_size * 8;
875 werror(E_BITFLD_SIZE, bitsize);
878 bitsize = BITVAR_PAD;
879 $$->bitVar = bitsize;
881 | declarator ':' constant_expr
884 bitsize= (int) floatFromVal(constExprValue($3,TRUE));
885 if (bitsize > (port->s.int_size * 8)) {
886 bitsize = port->s.int_size * 8;
887 werror(E_BITFLD_SIZE, bitsize);
890 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
891 $$->bitVar = BITVAR_PAD;
892 werror(W_BITFLD_NAMED);
895 $1->bitVar = bitsize;
900 : ENUM '{' enumerator_list '}' {
904 // check for duplicate enums
905 for (sym=$3; sym; sym=sym->next) {
906 for (dsym=sym->next; dsym; dsym=dsym->next) {
907 if (strcmp(sym->name, dsym->name)==0) {
908 werrorfl(filename, sym->lineDef, E_DUPLICATE_MEMBER, "enum", sym->name);
914 $$ = copyLinkChain(cenum->type);
921 | ENUM identifier '{' enumerator_list '}' {
924 $2->type = copyLinkChain(cenum->type);
925 $2->etype = getSpec($2->type);
926 /* add this to the enumerator table */
927 if (!(csym=findSym(enumTab,$2,$2->name)) &&
928 (csym && csym->level == $2->level))
929 werror(E_DUPLICATE_TYPEDEF,csym->name);
931 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
933 //allocVariables (reverseSyms($4));
934 $$ = copyLinkChain(cenum->type);
935 SPEC_SCLS(getSpec($$)) = 0 ;
940 /* check the enumerator table */
941 if ((csym = findSym(enumTab,$2,$2->name)))
942 $$ = copyLinkChain(csym->type);
944 $$ = newLink(SPECIFIER) ;
945 SPEC_NOUN($$) = V_INT ;
948 SPEC_SCLS(getSpec($$)) = 0 ;
954 | enumerator_list ',' {
956 | enumerator_list ',' enumerator {
963 : identifier opt_assign_expr
965 /* make the symbol one level up */
967 $1->type = copyLinkChain($2->type);
968 $1->etype= getSpec($1->type);
969 SPEC_ENUM($1->etype) = 1;
971 // do this now, so we can use it for the next enums in the list
977 : '=' constant_expr {
980 val = constExprValue($2,TRUE);
985 SNPRINTF(lbuff, sizeof(lbuff),
986 "%d",(int) floatFromVal(cenum)+1);
987 $$ = cenum = constVal(lbuff);
990 SNPRINTF(lbuff, sizeof(lbuff),
992 $$ = cenum = constVal(lbuff);
998 : declarator3 { $$ = $1 ; }
999 | pointer declarator3
1001 addDecl ($2,0,reverseLink($1));
1007 : declarator2_function_attributes { $$ = $1 ; }
1008 | declarator2 { $$ = $1 ; }
1012 : declarator2_function_attributes { $$ = $1; }
1013 | pointer declarator2_function_attributes
1015 addDecl ($2,0,reverseLink($1));
1020 declarator2_function_attributes
1021 : function_declarator2 { $$ = $1 ; }
1022 | function_declarator2 function_attribute {
1023 // copy the functionAttributes (not the args and hasVargs !!)
1024 sym_link *funcType=$1->etype;
1025 struct value *args=FUNC_ARGS(funcType);
1026 unsigned hasVargs=FUNC_HASVARARGS(funcType);
1028 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
1029 sizeof($2->funcAttrs));
1031 FUNC_ARGS(funcType)=args;
1032 FUNC_HASVARARGS(funcType)=hasVargs;
1035 memset (&$2->funcAttrs, 0,
1036 sizeof($2->funcAttrs));
1044 | '(' declarator ')' { $$ = $2; }
1045 | declarator3 '[' ']'
1049 p = newLink (DECLARATOR);
1050 DCL_TYPE(p) = ARRAY ;
1054 | declarator3 '[' constant_expr ']'
1059 tval = constExprValue($3,TRUE);
1060 /* if it is not a constant then Error */
1061 p = newLink (DECLARATOR);
1062 DCL_TYPE(p) = ARRAY ;
1063 if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1064 werror(E_CONST_EXPECTED) ;
1065 /* Assume a single item array to limit the cascade */
1066 /* of additional errors. */
1070 DCL_ELEM(p) = (int) floatFromVal(tval) ;
1076 function_declarator2
1077 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
1078 | declarator2 '(' { NestLevel++ ; currBlockno++; }
1079 parameter_type_list ')'
1082 addDecl ($1,FUNCTION,NULL) ;
1084 FUNC_HASVARARGS($1->type) = IS_VARG($4);
1085 FUNC_ARGS($1->type) = reverseVal($4);
1087 /* nest level was incremented to take care of the parms */
1091 // if this was a pointer (to a function)
1092 if (IS_PTR($1->type)) {
1093 // move the args and hasVargs to the function
1094 FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
1095 FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
1096 memset (&$1->type->funcAttrs, 0,
1097 sizeof($1->type->funcAttrs));
1098 // remove the symbol args (if any)
1099 cleanUpLevel(SymbolTab,NestLevel+1);
1104 | declarator2 '(' parameter_identifier_list ')'
1106 werror(E_OLD_STYLE,$1->name) ;
1107 /* assume it returns an int */
1108 $1->type = $1->etype = newIntLink();
1114 : unqualified_pointer { $$ = $1 ;}
1115 | unqualified_pointer type_specifier_list
1120 DCL_PTR_CONST($1) = SPEC_CONST($2);
1121 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1124 werror (W_PTR_TYPE_INVALID);
1126 | unqualified_pointer pointer
1130 DCL_TYPE($2)=port->unqualified_pointer;
1132 | unqualified_pointer type_specifier_list pointer
1135 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1136 DCL_PTR_CONST($1) = SPEC_CONST($2);
1137 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1138 switch (SPEC_SCLS($2)) {
1140 DCL_TYPE($3) = FPOINTER;
1143 DCL_TYPE($3) = IPOINTER ;
1146 DCL_TYPE($3) = PPOINTER ;
1149 DCL_TYPE($3) = POINTER ;
1152 DCL_TYPE($3) = CPOINTER ;
1155 DCL_TYPE($3) = EEPPOINTER;
1158 // this could be just "constant"
1159 // werror(W_PTR_TYPE_INVALID);
1164 werror (W_PTR_TYPE_INVALID);
1172 $$ = newLink(DECLARATOR);
1173 DCL_TYPE($$)=UPOINTER;
1179 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1180 | type_specifier_list type_specifier {
1181 /* if the decl $2 is not a specifier */
1182 /* find the spec and replace it */
1183 if ( !IS_SPEC($2)) {
1184 sym_link *lnk = $2 ;
1185 while (lnk && !IS_SPEC(lnk->next))
1187 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1191 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1195 parameter_identifier_list
1197 | identifier_list ',' ELIPSIS
1202 | identifier_list ',' identifier
1211 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1215 : parameter_declaration
1216 | parameter_list ',' parameter_declaration
1223 parameter_declaration
1224 : type_specifier_list declarator
1227 pointerTypes($2->type,$1);
1229 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1232 ignoreTypedefType = 0;
1237 $$->etype = getSpec($$->type);
1238 ignoreTypedefType = 0;
1243 : type_specifier_list { $$ = $1; ignoreTypedefType = 0;}
1244 | type_specifier_list abstract_declarator
1246 /* go to the end of the list */
1248 pointerTypes($2,$1);
1249 for ( p = $2 ; p && p->next ; p=p->next);
1251 werror(E_SYNTAX_ERROR, yytext);
1256 ignoreTypedefType = 0;
1261 : pointer { $$ = reverseLink($1); }
1262 | abstract_declarator2
1263 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1264 if (IS_PTR($1) && IS_FUNC($2))
1265 DCL_TYPE($1) = CPOINTER;
1269 abstract_declarator2
1270 : '(' abstract_declarator ')' { $$ = $2 ; }
1272 $$ = newLink (DECLARATOR);
1273 DCL_TYPE($$) = ARRAY ;
1276 | '[' constant_expr ']' {
1278 $$ = newLink (DECLARATOR);
1279 DCL_TYPE($$) = ARRAY ;
1280 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1282 | abstract_declarator2 '[' ']' {
1283 $$ = newLink (DECLARATOR);
1284 DCL_TYPE($$) = ARRAY ;
1288 | abstract_declarator2 '[' constant_expr ']'
1291 $$ = newLink (DECLARATOR);
1292 DCL_TYPE($$) = ARRAY ;
1293 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1296 | '(' ')' { $$ = NULL;}
1297 | '(' parameter_type_list ')' { $$ = NULL;}
1298 | abstract_declarator2 '(' ')' {
1299 // $1 must be a pointer to a function
1300 sym_link *p=newLink(DECLARATOR);
1301 DCL_TYPE(p) = FUNCTION;
1303 // ((void (code *) ()) 0) ()
1304 $1=newLink(DECLARATOR);
1305 DCL_TYPE($1)=CPOINTER;
1310 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1311 sym_link *p=newLink(DECLARATOR);
1312 DCL_TYPE(p) = FUNCTION;
1314 FUNC_HASVARARGS(p) = IS_VARG($4);
1315 FUNC_ARGS(p) = reverseVal($4);
1317 /* nest level was incremented to take care of the parms */
1323 // remove the symbol args (if any)
1324 cleanUpLevel(SymbolTab,NestLevel+1);
1329 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1330 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1331 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1336 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1341 | compound_statement
1342 | expression_statement
1343 | selection_statement
1344 | iteration_statement
1346 | critical_statement
1350 ex = newNode(INLINEASM,NULL,NULL);
1351 ex->values.inlineasm = strdup($1);
1360 STACK_PUSH(continueStack,NULL);
1361 STACK_PUSH(breakStack,NULL);
1367 : critical statement {
1368 STACK_POP(breakStack);
1369 STACK_POP(continueStack);
1371 $$ = newNode(CRITICAL,$2,NULL);
1376 // : identifier ':' statement { $$ = createLabel($1,$3); }
1377 : identifier ':' { $$ = createLabel($1,NULL); }
1378 | CASE constant_expr ':' statement
1380 if (STACK_EMPTY(swStk))
1381 $$ = createCase(NULL,$2,$4);
1383 $$ = createCase(STACK_PEEK(swStk),$2,$4);
1385 | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':' statement
1387 if (STACK_EMPTY(swStk))
1388 $$ = createDefault(NULL,$<asts>2,$4);
1390 $$ = createDefault(STACK_PEEK(swStk),$<asts>2,$4);
1396 STACK_PUSH(blockNum,currBlockno);
1397 currBlockno = ++blockNo ;
1398 ignoreTypedefType = 0;
1402 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1406 : start_block end_block { $$ = createBlock(NULL,NULL); }
1407 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1409 declaration_list { addSymChain($2); }
1410 end_block { $$ = createBlock($2,NULL) ; }
1412 declaration_list { addSymChain ($2); }
1414 end_block {$$ = createBlock($2,$4) ; }
1415 | error ';' { $$ = NULL ; }
1421 /* if this is typedef declare it immediately */
1422 if ( $1 && IS_TYPEDEF($1->etype)) {
1423 allocVariables ($1);
1428 ignoreTypedefType = 0;
1431 | declaration_list declaration
1435 /* if this is a typedef */
1436 if ($2 && IS_TYPEDEF($2->etype)) {
1437 allocVariables ($2);
1441 /* get to the end of the previous decl */
1451 ignoreTypedefType = 0;
1457 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1460 expression_statement
1462 | expr ';' { $$ = $1; seqPointNo++;}
1466 : ELSE statement { $$ = $2 ; }
1472 : IF '(' expr ')' { seqPointNo++;} statement else_statement
1475 $$ = createIf ($3, $6, $7 );
1478 | SWITCH '(' expr ')' {
1480 static int swLabel = 0 ;
1483 /* create a node for expression */
1484 ex = newNode(SWITCH,$3,NULL);
1485 STACK_PUSH(swStk,ex); /* save it in the stack */
1486 ex->values.switchVals.swNum = swLabel ;
1488 /* now create the label */
1489 SNPRINTF(lbuff, sizeof(lbuff),
1490 "_swBrk_%d",swLabel++);
1491 $<sym>$ = newSymbol(lbuff,NestLevel);
1492 /* put label in the break stack */
1493 STACK_PUSH(breakStack,$<sym>$);
1496 /* get back the switch form the stack */
1497 $$ = STACK_POP(swStk) ;
1498 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1499 STACK_POP(breakStack);
1503 while : WHILE { /* create and push the continue , break & body labels */
1504 static int Lblnum = 0 ;
1506 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1507 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1509 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1510 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1512 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1513 $$ = newSymbol(lbuff,NestLevel);
1517 do : DO { /* create and push the continue , break & body Labels */
1518 static int Lblnum = 0 ;
1521 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1522 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1524 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1525 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1527 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1528 $$ = newSymbol (lbuff,NestLevel);
1532 for : FOR { /* create & push continue, break & body labels */
1533 static int Lblnum = 0 ;
1536 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1537 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1539 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1540 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1542 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1543 $$ = newSymbol(lbuff,NestLevel);
1545 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1546 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1551 : while '(' expr ')' { seqPointNo++;} statement
1554 $$ = createWhile ( $1, STACK_POP(continueStack),
1555 STACK_POP(breakStack), $3, $6 );
1556 $$->lineno = $1->lineDef ;
1559 | do statement WHILE '(' expr ')' ';'
1563 $$ = createDo ( $1 , STACK_POP(continueStack),
1564 STACK_POP(breakStack), $5, $2);
1565 $$->lineno = $1->lineDef ;
1568 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1572 /* if break or continue statement present
1573 then create a general case loop */
1574 if (STACK_PEEK(continueStack)->isref ||
1575 STACK_PEEK(breakStack)->isref) {
1576 $$ = createFor ($1, STACK_POP(continueStack),
1577 STACK_POP(breakStack) ,
1578 STACK_POP(forStack) ,
1581 $$ = newNode(FOR,$9,NULL);
1582 AST_FOR($$,trueLabel) = $1;
1583 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1584 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1585 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1586 AST_FOR($$,initExpr) = $3;
1587 AST_FOR($$,condExpr) = $5;
1588 AST_FOR($$,loopExpr) = $7;
1596 : { $$ = NULL ; seqPointNo++; }
1597 | expr { $$ = $1 ; seqPointNo++; }
1601 : GOTO identifier ';' {
1603 $$ = newAst_VALUE(symbolVal($2));
1604 $$ = newNode(GOTO,$$,NULL);
1607 /* make sure continue is in context */
1608 if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) {
1609 werror(E_BREAK_CONTEXT);
1613 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1614 $$ = newNode(GOTO,$$,NULL);
1615 /* mark the continue label as referenced */
1616 STACK_PEEK(continueStack)->isref = 1;
1620 if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) {
1621 werror(E_BREAK_CONTEXT);
1624 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1625 $$ = newNode(GOTO,$$,NULL);
1626 STACK_PEEK(breakStack)->isref = 1;
1632 werror(E_INVALID_CRITICAL);
1635 $$ = newNode(RETURN,NULL,NULL);
1641 werror(E_INVALID_CRITICAL);
1644 $$ = newNode(RETURN,NULL,$2);
1650 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }