X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCC.y;h=c986486087d90b7750307d6c5c1dbb1154c41bec;hb=1f6bc72d8c57790f692bbc3ffa9451993e6a51c5;hp=ff6fd1b0c60e9f4f6d2f31919456d221298ef380;hpb=91de9714407a8df390127a3bdb92fec4668184d5;p=fw%2Fsdcc diff --git a/src/SDCC.y b/src/SDCC.y index ff6fd1b0..c9864860 100644 --- a/src/SDCC.y +++ b/src/SDCC.y @@ -58,6 +58,8 @@ STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3) value *cenum = NULL ; /* current enumeration type chain*/ %} +%expect 6 + %union { symbol *sym ; /* symbol table pointer */ structdef *sdef; /* structure definition */ @@ -81,14 +83,14 @@ value *cenum = NULL ; /* current enumeration type chain*/ %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT -%token STRUCT UNION ENUM ELIPSIS RANGE FAR _XDATA _CODE _GENERIC _NEAR _PDATA _IDATA _EEPROM +%token STRUCT UNION ENUM ELIPSIS RANGE FAR %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN %token NAKED %token INLINEASM %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE %token RRC RLC -%token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND +%token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT %type Interrupt_storage %type identifier declarator declarator2 enumerator_list enumerator @@ -101,7 +103,7 @@ value *cenum = NULL ; /* current enumeration type chain*/ %type storage_class_specifier struct_or_union_specifier %type declaration_specifiers sfr_reg_bit type_specifier2 %type using_reentrant using_reentrant_interrupt enum_specifier -%type abstract_declarator abstract_declarator2 far_near_pointer far_near +%type abstract_declarator abstract_declarator2 unqualified_pointer %type parameter_type_list parameter_list parameter_declaration opt_assign_expr %type stag opt_stag %type primary_expr @@ -167,7 +169,7 @@ function_definition using_reentrant : using_reentrant_interrupt - | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2); } + | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2,"using_reentrant"); } ; using_reentrant_interrupt @@ -480,11 +482,11 @@ declaration_specifiers sym_link *lnk = $2 ; while (lnk && !IS_SPEC(lnk->next)) lnk = lnk->next; - lnk->next = mergeSpec($1,lnk->next); + lnk->next = mergeSpec($1,lnk->next, yytext); $$ = $2 ; } else - $$ = mergeSpec($1,$2); + $$ = mergeSpec($1,$2, yytext); } | type_specifier { $$ = $1; } | type_specifier declaration_specifiers { @@ -494,11 +496,11 @@ declaration_specifiers sym_link *lnk = $2 ; while (lnk && !IS_SPEC(lnk->next)) lnk = lnk->next; - lnk->next = mergeSpec($1,lnk->next); + lnk->next = mergeSpec($1,lnk->next, yytext); $$ = $2 ; } else - $$ = mergeSpec($1,$2); + $$ = mergeSpec($1,$2, yytext); } ; @@ -709,24 +711,23 @@ struct_or_union ; opt_stag - : stag - | { /* synthesize a name add to structtable */ - $$ = newStruct(genSymName(NestLevel)) ; - $$->level = NestLevel ; - addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ; - } - ; +: stag +| { /* synthesize a name add to structtable */ + $$ = newStruct(genSymName(NestLevel)) ; + $$->level = NestLevel ; + addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0); +}; stag - : identifier { /* add name to structure table */ - $$ = findSymWithBlock (StructTab,$1,currBlockno); - if (! $$ ) { - $$ = newStruct($1->name) ; - $$->level = NestLevel ; - addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ; - } - } - ; +: identifier { /* add name to structure table */ + $$ = findSymWithBlock (StructTab,$1,currBlockno); + if (! $$ ) { + $$ = newStruct($1->name) ; + $$->level = NestLevel ; + addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0); + } +}; + struct_declaration_list : struct_declaration @@ -748,6 +749,9 @@ struct_declaration symbol *sym ; for ( sym = $2 ; sym != NULL ; sym = sym->next ) { + /* make the symbol one level up */ + sym->level-- ; + pointerTypes(sym->type,copyLinkChain($1)); if (!sym->type) { sym->type = copyLinkChain($1); @@ -799,7 +803,7 @@ enum_specifier (csym && csym->level == $2->level)) werror(E_DUPLICATE_TYPEDEF,csym->name); - addSym ( enumTab,$2,$2->name,$2->level,$2->block); + addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0); addSymChain ($4); allocVariables (reverseSyms($4)); $$ = copyLinkChain(cenum->type); @@ -823,6 +827,8 @@ enum_specifier enumerator_list : enumerator + | enumerator_list ',' { + } | enumerator_list ',' enumerator { $3->next = $1 ; $$ = $3 ; @@ -927,18 +933,18 @@ declarator2 ; pointer - : far_near_pointer { $$ = $1 ;} - | far_near_pointer type_specifier_list + : unqualified_pointer { $$ = $1 ;} + | unqualified_pointer type_specifier_list { $$ = $1 ; DCL_TSPEC($1) = $2; } - | far_near_pointer pointer + | unqualified_pointer pointer { $$ = $1 ; $$->next = $2 ; } - | far_near_pointer type_specifier_list pointer + | unqualified_pointer type_specifier_list pointer { $$ = $1 ; if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) { @@ -960,6 +966,7 @@ pointer case S_CODE: DCL_PTR_CONST($3) = 1; DCL_TYPE($3) = CPOINTER ; + break; case S_EEPROM: DCL_TYPE($3) = EEPPOINTER; break; @@ -973,31 +980,17 @@ pointer } ; -far_near_pointer - : far_near '*' { - if ($1 == NULL) { - $$ = newLink(); - DCL_TYPE($$) = POINTER ; - } - else - $$ = $1 ; +unqualified_pointer + : '*' + { + $$ = newLink(); + DCL_TYPE($$)=UPOINTER; } ; -far_near - : _XDATA { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; } - | _CODE { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ; DCL_PTR_CONST($$) = 1;} - | _PDATA { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; } - | _IDATA { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; } - | _NEAR { $$ = NULL ; } - | _GENERIC { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; } - | _EEPROM { $$ = newLink() ; DCL_TYPE($$) = EEPPOINTER ;} - | { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; } - ; - type_specifier_list : type_specifier - | type_specifier_list type_specifier { $$ = mergeSpec ($1,$2); } + | type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); } ; parameter_identifier_list @@ -1093,9 +1086,23 @@ abstract_declarator2 } | '(' ')' { $$ = NULL;} | '(' parameter_type_list ')' { $$ = NULL;} - | abstract_declarator2 '(' ')' - | abstract_declarator2 '(' parameter_type_list ')' - ; + | abstract_declarator2 '(' ')' { + // $1 must be a pointer to a function + sym_link *p=newLink(); + DCL_TYPE(p) = FUNCTION; + $1->next=p; + } + | abstract_declarator2 '(' parameter_type_list ')' { + if (!IS_VOID($3->type)) { + // this is nonsense, so let's just burp something + werror(E_TOO_FEW_PARMS); + } else { + // $1 must be a pointer to a function + sym_link *p=newLink(); + DCL_TYPE(p) = FUNCTION; + $1->next=p; + } + } initializer : assignment_expr { $$ = newiList(INIT_NODE,$1); }