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 SWAP
99 %type <yyint> Interrupt_storage
100 %type <sym> identifier declarator declarator2 declarator3 enumerator_list enumerator
101 %type <sym> struct_declarator function_declarator function_declarator2
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 sfr_attributes 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 : function_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 function_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('=',removePostIncDecOps(copyAst($1)),
406 newNode('*',removePreIncDecOps(copyAst($1)),$3));
409 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
410 newNode('/',removePreIncDecOps(copyAst($1)),$3));
413 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
414 newNode('%',removePreIncDecOps(copyAst($1)),$3));
417 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
418 newNode('+',removePreIncDecOps(copyAst($1)),$3));
421 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
422 newNode('-',removePreIncDecOps(copyAst($1)),$3));
425 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
426 newNode(LEFT_OP,removePreIncDecOps(copyAst($1)),$3));
429 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
430 newNode(RIGHT_OP,removePreIncDecOps(copyAst($1)),$3));
433 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
434 newNode('&',removePreIncDecOps(copyAst($1)),$3));
437 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
438 newNode('^',removePreIncDecOps(copyAst($1)),$3));
441 /* $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); */
442 $$ = newNode('=',removePostIncDecOps(copyAst($1)),
443 newNode('|',removePreIncDecOps(copyAst($1)),$3));
468 | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
476 : declaration_specifiers ';'
479 werror(W_USELESS_DECL);
483 | declaration_specifiers init_declarator_list ';'
485 /* add the specifier list to the id */
488 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) {
489 sym_link *lnk = copyLinkChain($1);
490 /* do the pointer stuff */
491 pointerTypes(sym->type,lnk);
492 addDecl (sym,0,lnk) ;
500 declaration_specifiers
501 : storage_class_specifier { $$ = $1; }
502 | storage_class_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, "storage_class_specifier declaration_specifiers - skipped");
513 $$ = mergeSpec($1,$2, "storage_class_specifier declaration_specifiers");
515 | type_specifier { $$ = $1; }
516 | type_specifier declaration_specifiers {
517 /* if the decl $2 is not a specifier */
518 /* find the spec and replace it */
521 while (lnk && !IS_SPEC(lnk->next))
523 lnk->next = mergeSpec($1,lnk->next, "type_specifier declaration_specifiers - skipped");
527 $$ = mergeSpec($1,$2, "type_specifier declaration_specifiers");
533 | init_declarator_list ',' init_declarator { $3->next = $1 ; $$ = $3;}
537 : declarator { $1->ival = NULL ; }
538 | declarator '=' initializer { $1->ival = $3 ; }
542 storage_class_specifier
544 $$ = newLink (SPECIFIER) ;
545 SPEC_TYPEDEF($$) = 1 ;
548 $$ = newLink(SPECIFIER);
552 $$ = newLink (SPECIFIER);
556 $$ = newLink (SPECIFIER) ;
557 SPEC_SCLS($$) = S_AUTO ;
560 $$ = newLink (SPECIFIER);
561 SPEC_SCLS($$) = S_REGISTER ;
566 : INTERRUPT { $$ = INTNO_UNSPEC ; }
568 { int intno = (int) floatFromVal($2);
569 if ((intno >= 0) && (intno <= INTNO_MAX))
573 werror(E_INT_BAD_INTNO, intno);
581 | type_specifier2 AT constant_expr
583 /* add this to the storage class specifier */
584 SPEC_ABSA($1) = 1; /* set the absolute addr flag */
585 /* now get the abs addr from value */
586 SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
592 $$=newLink(SPECIFIER);
593 SPEC_NOUN($$) = V_CHAR ;
596 $$=newLink(SPECIFIER);
597 $$->select.s._short = 1 ;
600 $$=newLink(SPECIFIER);
601 SPEC_NOUN($$) = V_INT ;
604 $$=newLink(SPECIFIER);
608 $$=newLink(SPECIFIER);
609 $$->select.s._signed = 1;
612 $$=newLink(SPECIFIER);
616 $$=newLink(SPECIFIER);
617 SPEC_NOUN($$) = V_VOID ;
620 $$=newLink(SPECIFIER);
624 $$=newLink(SPECIFIER);
625 SPEC_VOLATILE($$) = 1 ;
628 $$=newLink(SPECIFIER);
629 SPEC_NOUN($$) = V_FLOAT;
632 $$ = newLink (SPECIFIER);
633 SPEC_SCLS($$) = S_XDATA ;
636 $$ = newLink (SPECIFIER) ;
637 SPEC_SCLS($$) = S_CODE ;
640 $$ = newLink (SPECIFIER) ;
641 SPEC_SCLS($$) = S_EEPROM ;
644 $$ = newLink (SPECIFIER);
645 SPEC_SCLS($$) = S_DATA ;
648 $$ = newLink (SPECIFIER);
649 SPEC_SCLS($$) = S_IDATA ;
652 $$ = newLink (SPECIFIER);
653 SPEC_SCLS($$) = S_PDATA ;
656 $$=newLink(SPECIFIER);
657 SPEC_NOUN($$) = V_BIT ;
658 SPEC_SCLS($$) = S_BIT ;
663 | struct_or_union_specifier {
676 sym = findSym(TypedefTab,NULL,$1) ;
677 $$ = p = copyLinkChain(sym->type);
678 SPEC_TYPEDEF(getSpec(p)) = 0;
685 $$ = newLink(SPECIFIER) ;
686 SPEC_NOUN($$) = V_SBIT;
687 SPEC_SCLS($$) = S_SBIT;
694 $$ = newLink(SPECIFIER) ;
695 FUNC_REGBANK($$) = 0;
696 SPEC_NOUN($$) = V_CHAR;
697 SPEC_SCLS($$) = S_SFR ;
701 $$ = newLink(SPECIFIER) ;
702 FUNC_REGBANK($$) = 1;
703 SPEC_NOUN($$) = V_CHAR;
704 SPEC_SCLS($$) = S_SFR ;
709 struct_or_union_specifier
710 : struct_or_union opt_stag '{' struct_declaration_list '}'
715 // check for errors in structure members
716 for (sym=$4; sym; sym=sym->next) {
717 if (IS_ABSOLUTE(sym->etype)) {
718 werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "'at'");
719 SPEC_ABSA(sym->etype) = 0;
721 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
722 werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "storage class");
723 SPEC_SCLS(sym->etype) = 0;
725 for (dsym=sym->next; dsym; dsym=dsym->next) {
726 if (strcmp(sym->name, dsym->name)==0) {
727 werrorfl(filename, sym->lineDef, E_DUPLICATE_MEMBER,
728 $1==STRUCT ? "struct" : "union", sym->name);
733 /* Create a structdef */
735 sdef->fields = reverseSyms($4) ; /* link the fields */
736 sdef->size = compStructSize($1,sdef); /* update size of */
738 /* Create the specifier */
739 $$ = newLink (SPECIFIER) ;
740 SPEC_NOUN($$) = V_STRUCT;
741 SPEC_STRUCT($$)= sdef ;
743 | struct_or_union stag
745 $$ = newLink(SPECIFIER) ;
746 SPEC_NOUN($$) = V_STRUCT;
747 SPEC_STRUCT($$) = $2 ;
752 : STRUCT { $$ = STRUCT ; }
753 | UNION { $$ = UNION ; }
758 | { /* synthesize a name add to structtable */
759 $$ = newStruct(genSymName(NestLevel)) ;
760 $$->level = NestLevel ;
761 addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
765 : identifier { /* add name to structure table */
766 $$ = findSymWithBlock (StructTab,$1,currBlockno);
768 $$ = newStruct($1->name) ;
769 $$->level = NestLevel ;
770 addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
775 struct_declaration_list
777 | struct_declaration_list struct_declaration
781 /* go to the end of the chain */
782 while (sym->next) sym=sym->next;
790 : type_specifier_list struct_declarator_list ';'
792 /* add this type to all the symbols */
794 for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
795 sym_link *btype = copyLinkChain($1);
797 /* make the symbol one level up */
800 pointerTypes(sym->type,btype);
803 sym->etype = getSpec(sym->type);
806 addDecl (sym,0,btype);
807 /* make sure the type is complete and sane */
808 checkTypeSanity(sym->etype, sym->name);
814 struct_declarator_list
816 | struct_declarator_list ',' struct_declarator
825 | ':' constant_expr {
827 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
828 bitsize= (int) floatFromVal(constExprValue($2,TRUE));
829 if (bitsize > (port->s.int_size * 8)) {
830 bitsize = port->s.int_size * 8;
831 werror(E_BITFLD_SIZE, bitsize);
834 bitsize = BITVAR_PAD;
835 $$->bitVar = bitsize;
837 | declarator ':' constant_expr
840 bitsize= (int) floatFromVal(constExprValue($3,TRUE));
841 if (bitsize > (port->s.int_size * 8)) {
842 bitsize = port->s.int_size * 8;
843 werror(E_BITFLD_SIZE, bitsize);
846 $$ = newSymbol (genSymName(NestLevel),NestLevel) ;
847 $$->bitVar = BITVAR_PAD;
848 werror(W_BITFLD_NAMED);
851 $1->bitVar = bitsize;
856 : ENUM '{' enumerator_list '}' {
860 // check for duplicate enums
861 for (sym=$3; sym; sym=sym->next) {
862 for (dsym=sym->next; dsym; dsym=dsym->next) {
863 if (strcmp(sym->name, dsym->name)==0) {
864 werrorfl(filename, sym->lineDef, E_DUPLICATE_MEMBER, "enum", sym->name);
870 $$ = copyLinkChain(cenum->type);
877 | ENUM identifier '{' enumerator_list '}' {
880 $2->type = copyLinkChain(cenum->type);
881 $2->etype = getSpec($2->type);
882 /* add this to the enumerator table */
883 if (!(csym=findSym(enumTab,$2,$2->name)) &&
884 (csym && csym->level == $2->level))
885 werror(E_DUPLICATE_TYPEDEF,csym->name);
887 addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
889 //allocVariables (reverseSyms($4));
890 $$ = copyLinkChain(cenum->type);
891 SPEC_SCLS(getSpec($$)) = 0 ;
896 /* check the enumerator table */
897 if ((csym = findSym(enumTab,$2,$2->name)))
898 $$ = copyLinkChain(csym->type);
900 $$ = newLink(SPECIFIER) ;
901 SPEC_NOUN($$) = V_INT ;
904 SPEC_SCLS(getSpec($$)) = 0 ;
910 | enumerator_list ',' {
912 | enumerator_list ',' enumerator {
919 : identifier opt_assign_expr
921 /* make the symbol one level up */
923 $1->type = copyLinkChain($2->type);
924 $1->etype= getSpec($1->type);
925 SPEC_ENUM($1->etype) = 1;
927 // do this now, so we can use it for the next enums in the list
933 : '=' constant_expr {
936 val = constExprValue($2,TRUE);
941 SNPRINTF(lbuff, sizeof(lbuff),
942 "%d",(int) floatFromVal(cenum)+1);
943 $$ = cenum = constVal(lbuff);
946 SNPRINTF(lbuff, sizeof(lbuff),
948 $$ = cenum = constVal(lbuff);
954 : declarator3 { $$ = $1 ; }
955 | pointer declarator3
957 addDecl ($2,0,reverseLink($1));
963 : declarator2_function_attributes { $$ = $1 ; }
964 | declarator2 { $$ = $1 ; }
968 : declarator2_function_attributes { $$ = $1; }
969 | pointer declarator2_function_attributes
971 addDecl ($2,0,reverseLink($1));
976 declarator2_function_attributes
977 : function_declarator2 { $$ = $1 ; }
978 | function_declarator2 function_attribute {
979 // copy the functionAttributes (not the args and hasVargs !!)
980 sym_link *funcType=$1->etype;
981 struct value *args=FUNC_ARGS(funcType);
982 unsigned hasVargs=FUNC_HASVARARGS(funcType);
984 memcpy (&funcType->funcAttrs, &$2->funcAttrs,
985 sizeof($2->funcAttrs));
987 FUNC_ARGS(funcType)=args;
988 FUNC_HASVARARGS(funcType)=hasVargs;
991 memset (&$2->funcAttrs, 0,
992 sizeof($2->funcAttrs));
1000 | '(' declarator ')' { $$ = $2; }
1001 | declarator3 '[' ']'
1005 p = newLink (DECLARATOR);
1006 DCL_TYPE(p) = ARRAY ;
1010 | declarator3 '[' constant_expr ']'
1015 tval = constExprValue($3,TRUE);
1016 /* if it is not a constant then Error */
1017 p = newLink (DECLARATOR);
1018 DCL_TYPE(p) = ARRAY ;
1019 if ( !tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) {
1020 werror(E_CONST_EXPECTED) ;
1021 /* Assume a single item array to limit the cascade */
1022 /* of additional errors. */
1026 DCL_ELEM(p) = (int) floatFromVal(tval) ;
1032 function_declarator2
1033 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
1034 | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
1037 addDecl ($1,FUNCTION,NULL) ;
1039 FUNC_HASVARARGS($1->type) = IS_VARG($4);
1040 FUNC_ARGS($1->type) = reverseVal($4);
1042 /* nest level was incremented to take care of the parms */
1046 // if this was a pointer (to a function)
1047 if (IS_PTR($1->type)) {
1048 // move the args and hasVargs to the function
1049 FUNC_ARGS($1->etype)=FUNC_ARGS($1->type);
1050 FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type);
1051 memset (&$1->type->funcAttrs, 0,
1052 sizeof($1->type->funcAttrs));
1053 // remove the symbol args (if any)
1054 cleanUpLevel(SymbolTab,NestLevel+1);
1059 | declarator2 '(' parameter_identifier_list ')'
1061 werror(E_OLD_STYLE,$1->name) ;
1062 /* assume it returns an int */
1063 $1->type = $1->etype = newIntLink();
1069 : unqualified_pointer { $$ = $1 ;}
1070 | unqualified_pointer type_specifier_list
1075 DCL_PTR_CONST($1) = SPEC_CONST($2);
1076 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1079 werror (W_PTR_TYPE_INVALID);
1081 | unqualified_pointer pointer
1085 DCL_TYPE($2)=port->unqualified_pointer;
1087 | unqualified_pointer type_specifier_list pointer
1090 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
1091 DCL_PTR_CONST($1) = SPEC_CONST($2);
1092 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2);
1093 switch (SPEC_SCLS($2)) {
1095 DCL_TYPE($3) = FPOINTER;
1098 DCL_TYPE($3) = IPOINTER ;
1101 DCL_TYPE($3) = PPOINTER ;
1104 DCL_TYPE($3) = POINTER ;
1107 DCL_TYPE($3) = CPOINTER ;
1110 DCL_TYPE($3) = EEPPOINTER;
1113 // this could be just "constant"
1114 // werror(W_PTR_TYPE_INVALID);
1119 werror (W_PTR_TYPE_INVALID);
1127 $$ = newLink(DECLARATOR);
1128 DCL_TYPE($$)=UPOINTER;
1134 //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
1135 | type_specifier_list type_specifier {
1136 /* if the decl $2 is not a specifier */
1137 /* find the spec and replace it */
1138 if ( !IS_SPEC($2)) {
1139 sym_link *lnk = $2 ;
1140 while (lnk && !IS_SPEC(lnk->next))
1142 lnk->next = mergeSpec($1,lnk->next, "type_specifier_list type_specifier skipped");
1146 $$ = mergeSpec($1,$2, "type_specifier_list type_specifier");
1150 parameter_identifier_list
1152 | identifier_list ',' ELIPSIS
1157 | identifier_list ',' identifier
1166 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;}
1170 : parameter_declaration
1171 | parameter_list ',' parameter_declaration
1178 parameter_declaration
1179 : type_specifier_list declarator
1182 pointerTypes($2->type,$1);
1184 for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
1191 $$->etype = getSpec($$->type);
1196 : type_specifier_list { $$ = $1 ;}
1197 | type_specifier_list abstract_declarator
1199 /* go to the end of the list */
1201 pointerTypes($2,$1);
1202 for ( p = $2 ; p && p->next ; p=p->next);
1204 werror(E_SYNTAX_ERROR, yytext);
1213 : pointer { $$ = reverseLink($1); }
1214 | abstract_declarator2
1215 | pointer abstract_declarator2 { $1 = reverseLink($1); $1->next = $2 ; $$ = $1;
1216 if (IS_PTR($1) && IS_FUNC($2))
1217 DCL_TYPE($1) = CPOINTER;
1221 abstract_declarator2
1222 : '(' abstract_declarator ')' { $$ = $2 ; }
1224 $$ = newLink (DECLARATOR);
1225 DCL_TYPE($$) = ARRAY ;
1228 | '[' constant_expr ']' {
1230 $$ = newLink (DECLARATOR);
1231 DCL_TYPE($$) = ARRAY ;
1232 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
1234 | abstract_declarator2 '[' ']' {
1235 $$ = newLink (DECLARATOR);
1236 DCL_TYPE($$) = ARRAY ;
1240 | abstract_declarator2 '[' constant_expr ']'
1243 $$ = newLink (DECLARATOR);
1244 DCL_TYPE($$) = ARRAY ;
1245 DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
1248 | '(' ')' { $$ = NULL;}
1249 | '(' parameter_type_list ')' { $$ = NULL;}
1250 | abstract_declarator2 '(' ')' {
1251 // $1 must be a pointer to a function
1252 sym_link *p=newLink(DECLARATOR);
1253 DCL_TYPE(p) = FUNCTION;
1255 // ((void (code *) ()) 0) ()
1256 $1=newLink(DECLARATOR);
1257 DCL_TYPE($1)=CPOINTER;
1262 | abstract_declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' {
1263 sym_link *p=newLink(DECLARATOR);
1264 DCL_TYPE(p) = FUNCTION;
1266 FUNC_HASVARARGS(p) = IS_VARG($4);
1267 FUNC_ARGS(p) = reverseVal($4);
1269 /* nest level was incremented to take care of the parms */
1275 // remove the symbol args (if any)
1276 cleanUpLevel(SymbolTab,NestLevel+1);
1281 : assignment_expr { $$ = newiList(INIT_NODE,$1); }
1282 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1283 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); }
1288 | initializer_list ',' initializer { $3->next = $1; $$ = $3; }
1293 | compound_statement
1294 | expression_statement
1295 | selection_statement
1296 | iteration_statement
1298 | critical_statement
1300 ast *ex = newNode(INLINEASM,NULL,NULL);
1301 ex->values.inlineasm = strdup($1);
1309 STACK_PUSH(continueStack,NULL);
1310 STACK_PUSH(breakStack,NULL);
1316 : critical statement {
1317 STACK_POP(breakStack);
1318 STACK_POP(continueStack);
1320 $$ = newNode(CRITICAL,$2,NULL);
1325 // : identifier ':' statement { $$ = createLabel($1,$3); }
1326 : identifier ':' { $$ = createLabel($1,NULL); }
1327 | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); }
1328 | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); }
1331 start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
1334 end_block : '}' { currBlockno = STACK_POP(blockNum); }
1338 : start_block end_block { $$ = createBlock(NULL,NULL); }
1339 | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
1341 declaration_list { addSymChain($2); }
1342 end_block { $$ = createBlock($2,NULL) ; }
1344 declaration_list { addSymChain ($2); }
1346 end_block {$$ = createBlock($2,$4) ; }
1347 | error ';' { $$ = NULL ; }
1353 /* if this is typedef declare it immediately */
1354 if ( $1 && IS_TYPEDEF($1->etype)) {
1355 allocVariables ($1);
1362 | declaration_list declaration
1366 /* if this is a typedef */
1367 if ($2 && IS_TYPEDEF($2->etype)) {
1368 allocVariables ($2);
1372 /* get to the end of the previous decl */
1387 | statement_list statement { $$ = newNode(NULLOP,$1,$2) ;}
1390 expression_statement
1396 : ELSE statement { $$ = $2 ; }
1402 : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
1403 | SWITCH '(' expr ')' {
1405 static int swLabel = 0 ;
1407 /* create a node for expression */
1408 ex = newNode(SWITCH,$3,NULL);
1409 STACK_PUSH(swStk,ex); /* save it in the stack */
1410 ex->values.switchVals.swNum = swLabel ;
1412 /* now create the label */
1413 SNPRINTF(lbuff, sizeof(lbuff),
1414 "_swBrk_%d",swLabel++);
1415 $<sym>$ = newSymbol(lbuff,NestLevel);
1416 /* put label in the break stack */
1417 STACK_PUSH(breakStack,$<sym>$);
1420 /* get back the switch form the stack */
1421 $$ = STACK_POP(swStk) ;
1422 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL));
1423 STACK_POP(breakStack);
1427 while : WHILE { /* create and push the continue , break & body labels */
1428 static int Lblnum = 0 ;
1430 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum);
1431 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1433 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum);
1434 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1436 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++);
1437 $$ = newSymbol(lbuff,NestLevel);
1441 do : DO { /* create and push the continue , break & body Labels */
1442 static int Lblnum = 0 ;
1445 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum);
1446 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1448 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum);
1449 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1451 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++);
1452 $$ = newSymbol (lbuff,NestLevel);
1456 for : FOR { /* create & push continue, break & body labels */
1457 static int Lblnum = 0 ;
1460 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum);
1461 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel));
1463 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum);
1464 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel));
1466 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum);
1467 $$ = newSymbol(lbuff,NestLevel);
1469 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++);
1470 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
1475 : while '(' expr ')' statement
1478 $$ = createWhile ( $1, STACK_POP(continueStack),
1479 STACK_POP(breakStack), $3, $5 );
1480 $$->lineno = $1->lineDef ;
1483 | do statement WHILE '(' expr ')' ';'
1486 $$ = createDo ( $1 , STACK_POP(continueStack),
1487 STACK_POP(breakStack), $5, $2);
1488 $$->lineno = $1->lineDef ;
1491 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement
1495 /* if break or continue statement present
1496 then create a general case loop */
1497 if (STACK_PEEK(continueStack)->isref ||
1498 STACK_PEEK(breakStack)->isref) {
1499 $$ = createFor ($1, STACK_POP(continueStack),
1500 STACK_POP(breakStack) ,
1501 STACK_POP(forStack) ,
1504 $$ = newNode(FOR,$9,NULL);
1505 AST_FOR($$,trueLabel) = $1;
1506 AST_FOR($$,continueLabel) = STACK_POP(continueStack);
1507 AST_FOR($$,falseLabel) = STACK_POP(breakStack);
1508 AST_FOR($$,condLabel) = STACK_POP(forStack) ;
1509 AST_FOR($$,initExpr) = $3;
1510 AST_FOR($$,condExpr) = $5;
1511 AST_FOR($$,loopExpr) = $7;
1524 : GOTO identifier ';' {
1526 $$ = newAst_VALUE(symbolVal($2));
1527 $$ = newNode(GOTO,$$,NULL);
1530 /* make sure continue is in context */
1531 if (STACK_PEEK(continueStack) == NULL) {
1532 werror(E_BREAK_CONTEXT);
1536 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));
1537 $$ = newNode(GOTO,$$,NULL);
1538 /* mark the continue label as referenced */
1539 STACK_PEEK(continueStack)->isref = 1;
1543 if (STACK_PEEK(breakStack) == NULL) {
1544 werror(E_BREAK_CONTEXT);
1547 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
1548 $$ = newNode(GOTO,$$,NULL);
1549 STACK_PEEK(breakStack)->isref = 1;
1554 werror(E_INVALID_CRITICAL);
1557 $$ = newNode(RETURN,NULL,NULL);
1562 werror(E_INVALID_CRITICAL);
1565 $$ = newNode(RETURN,NULL,$2);
1571 : IDENTIFIER { $$ = newSymbol ($1,NestLevel) ; }