int blockNo = 0 ; /* sequential block number */
int currBlockno=0 ;
int inCritical= 0 ;
+int seqPointNo= 1 ; /* sequence point number */
+int ignoreTypedefType=0;
extern int yylex();
int yyparse(void);
extern int noLineno ;
value *cenum = NULL ; /* current enumeration type chain*/
bool uselessDecl = TRUE;
+#define YYDEBUG 1
+
%}
%expect 6
blockNo=0;
}
| declaration {
+ ignoreTypedefType = 0;
if ($1 && $1->type
&& IS_FUNC($1->type))
{
logical_and_expr
: inclusive_or_expr
- | logical_and_expr AND_OP inclusive_or_expr
- { $$ = newNode(AND_OP,$1,$3);}
+ | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expr
+ { $$ = newNode(AND_OP,$1,$4);}
;
logical_or_expr
: logical_and_expr
- | logical_or_expr OR_OP logical_and_expr
- { $$ = newNode(OR_OP,$1,$3); }
+ | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr
+ { $$ = newNode(OR_OP,$1,$4); }
;
conditional_expr
: logical_or_expr
- | logical_or_expr '?' logical_or_expr ':' conditional_expr
+ | logical_or_expr '?' { seqPointNo++;} logical_or_expr ':' conditional_expr
{
- $$ = newNode(':',$3,$5) ;
+ $$ = newNode(':',$4,$6) ;
$$ = newNode('?',$1,$$) ;
}
;
expr
: assignment_expr
- | expr ',' assignment_expr { $$ = newNode(',',$1,$3);}
+ | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);}
;
constant_expr
: type_specifier2
| type_specifier2 AT constant_expr
{
- /* add this to the storage class specifier */
+ /* add this to the storage class specifier */
SPEC_ABSA($1) = 1; /* set the absolute addr flag */
/* now get the abs addr from value */
SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
: CHAR {
$$=newLink(SPECIFIER);
SPEC_NOUN($$) = V_CHAR ;
+ ignoreTypedefType = 1;
}
| SHORT {
$$=newLink(SPECIFIER);
$$->select.s._short = 1 ;
+ ignoreTypedefType = 1;
}
| INT {
$$=newLink(SPECIFIER);
SPEC_NOUN($$) = V_INT ;
+ ignoreTypedefType = 1;
}
| LONG {
$$=newLink(SPECIFIER);
SPEC_LONG($$) = 1 ;
+ ignoreTypedefType = 1;
}
| SIGNED {
$$=newLink(SPECIFIER);
$$->select.s._signed = 1;
+ ignoreTypedefType = 1;
}
| UNSIGNED {
$$=newLink(SPECIFIER);
SPEC_USIGN($$) = 1 ;
+ ignoreTypedefType = 1;
}
| VOID {
$$=newLink(SPECIFIER);
SPEC_NOUN($$) = V_VOID ;
+ ignoreTypedefType = 1;
}
| CONST {
$$=newLink(SPECIFIER);
| FLOAT {
$$=newLink(SPECIFIER);
SPEC_NOUN($$) = V_FLOAT;
+ ignoreTypedefType = 1;
}
| XDATA {
$$ = newLink (SPECIFIER);
SPEC_SCLS($$) = S_BIT ;
SPEC_BLEN($$) = 1;
SPEC_BSTR($$) = 0;
+ ignoreTypedefType = 1;
}
| struct_or_union_specifier {
uselessDecl = FALSE;
$$ = $1 ;
+ ignoreTypedefType = 1;
}
| enum_specifier {
cenum = NULL ;
uselessDecl = FALSE;
+ ignoreTypedefType = 1;
$$ = $1 ;
}
| TYPE_NAME
sym = findSym(TypedefTab,NULL,$1) ;
$$ = p = copyLinkChain(sym->type);
SPEC_TYPEDEF(getSpec(p)) = 0;
+ ignoreTypedefType = 1;
}
| sfr_reg_bit
;
$$ = newLink(SPECIFIER) ;
SPEC_NOUN($$) = V_SBIT;
SPEC_SCLS($$) = S_SBIT;
+ ignoreTypedefType = 1;
}
| sfr_attributes
;
SPEC_NOUN($$) = V_CHAR;
SPEC_SCLS($$) = S_SFR ;
SPEC_USIGN($$) = 1 ;
+ ignoreTypedefType = 1;
}
| SFR BANKED {
$$ = newLink(SPECIFIER) ;
SPEC_NOUN($$) = V_CHAR;
SPEC_SCLS($$) = S_SFR ;
SPEC_USIGN($$) = 1 ;
+ ignoreTypedefType = 1;
}
;
struct_or_union_specifier
- : struct_or_union opt_stag '{' struct_declaration_list '}'
+ : struct_or_union opt_stag
+ {
+ if (!$2->type)
+ {
+ $2->type = $1;
+ }
+ else
+ {
+ if ($2->type != $1)
+ werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
+ }
+
+ }
+ '{' struct_declaration_list '}'
{
structdef *sdef ;
symbol *sym, *dsym;
// check for errors in structure members
- for (sym=$4; sym; sym=sym->next) {
+ for (sym=$5; sym; sym=sym->next) {
if (IS_ABSOLUTE(sym->etype)) {
werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "'at'");
SPEC_ABSA(sym->etype) = 0;
}
if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) {
werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "storage class");
+ printTypeChainRaw (sym->type,NULL);
SPEC_SCLS(sym->etype) = 0;
}
for (dsym=sym->next; dsym; dsym=dsym->next) {
/* Create a structdef */
sdef = $2 ;
- sdef->fields = reverseSyms($4) ; /* link the fields */
+ sdef->fields = reverseSyms($5) ; /* link the fields */
sdef->size = compStructSize($1,sdef); /* update size of */
/* Create the specifier */
{
$$ = newLink(SPECIFIER) ;
SPEC_NOUN($$) = V_STRUCT;
- SPEC_STRUCT($$) = $2 ;
+ SPEC_STRUCT($$) = $2;
+
+ if (!$2->type)
+ {
+ $2->type = $1;
+ }
+ else
+ {
+ if ($2->type != $1)
+ werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union");
+ }
}
;
/* make sure the type is complete and sane */
checkTypeSanity(sym->etype, sym->name);
}
- $$ = $2;
+ ignoreTypedefType = 0;
+ $$ = $2;
}
;
enum_specifier
: ENUM '{' enumerator_list '}' {
- symbol *sym, *dsym;
- char _error=0;
-
- // check for duplicate enums
- for (sym=$3; sym; sym=sym->next) {
- for (dsym=sym->next; dsym; dsym=dsym->next) {
- if (strcmp(sym->name, dsym->name)==0) {
- werrorfl(filename, sym->lineDef, E_DUPLICATE_MEMBER, "enum", sym->name);
- _error++;
- }
- }
- }
- if (_error==0) {
- $$ = copyLinkChain(cenum->type);
- } else {
- $$ = newIntLink();
- SPEC_NOUN($$)=0;
- }
+ $$ = newEnumType ($3); //copyLinkChain(cenum->type);
+ SPEC_SCLS(getSpec($$)) = 0;
}
| ENUM identifier '{' enumerator_list '}' {
symbol *csym ;
+ sym_link *enumtype;
+
+ csym=findSym(enumTab,$2,$2->name);
+ if ((csym && csym->level == $2->level))
+ werrorfl(filename, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name);
- $2->type = copyLinkChain(cenum->type);
- $2->etype = getSpec($2->type);
- /* add this to the enumerator table */
- if (!(csym=findSym(enumTab,$2,$2->name)) &&
- (csym && csym->level == $2->level))
- werror(E_DUPLICATE_TYPEDEF,csym->name);
+ enumtype = newEnumType ($4); //copyLinkChain(cenum->type);
+ SPEC_SCLS(getSpec(enumtype)) = 0;
+ $2->type = enumtype;
- addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
- //addSymChain ($4);
- //allocVariables (reverseSyms($4));
- $$ = copyLinkChain(cenum->type);
- SPEC_SCLS(getSpec($$)) = 0 ;
+ /* add this to the enumerator table */
+ if (!csym)
+ addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
+ $$ = copyLinkChain(enumtype);
}
| ENUM identifier {
symbol *csym ;
$$ = newLink(SPECIFIER) ;
SPEC_NOUN($$) = V_INT ;
}
-
- SPEC_SCLS(getSpec($$)) = 0 ;
}
;
: enumerator
| enumerator_list ',' {
}
- | enumerator_list ',' enumerator {
- $3->next = $1 ;
- $$ = $3 ;
- }
+ | enumerator_list ',' enumerator
+ {
+ symbol *dsym;
+
+ for (dsym=$1; dsym; dsym=dsym->next)
+ {
+ if (strcmp($3->name, dsym->name)==0)
+ werrorfl(filename, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name);
+ }
+
+ $3->next = $1 ;
+ $$ = $3 ;
+ }
;
enumerator
opt_assign_expr
: '=' constant_expr {
value *val ;
-
- val = constExprValue($2,TRUE);
+
+ val = constExprValue($2,TRUE);
+ if (!IS_INT(val->type) && !IS_CHAR(val->type))
+ {
+ werror(E_ENUM_NON_INTEGER);
+ SNPRINTF(lbuff, sizeof(lbuff),
+ "%d",(int) floatFromVal(val));
+ val = constVal(lbuff);
+ }
$$ = cenum = val ;
}
| {
function_declarator2
: declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
- | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
+ | declarator2 '(' { NestLevel++ ; currBlockno++; }
+ parameter_type_list ')'
{
addDecl ($1,FUNCTION,NULL) ;
;
parameter_list
- : parameter_declaration
+ : parameter_declaration
| parameter_list ',' parameter_declaration
{
$3->next = $1 ;
- $$ = $3 ;
+ $$ = $3 ;
}
;
for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
addSymChain ($2);
$$ = symbolVal($2);
+ ignoreTypedefType = 0;
}
| type_name {
$$ = newValue() ;
$$->type = $1;
$$->etype = getSpec($$->type);
+ ignoreTypedefType = 0;
}
;
type_name
- : type_specifier_list { $$ = $1 ;}
+ : type_specifier_list { $$ = $1; ignoreTypedefType = 0;}
| type_specifier_list abstract_declarator
{
/* go to the end of the list */
p->next = $1 ;
}
$$ = $2 ;
+ ignoreTypedefType = 0;
}
;
| jump_statement
| critical_statement
| INLINEASM ';' {
- ast *ex = newNode(INLINEASM,NULL,NULL);
+ ast *ex;
+ seqPointNo++;
+ ex = newNode(INLINEASM,NULL,NULL);
ex->values.inlineasm = strdup($1);
+ seqPointNo++;
$$ = ex;
}
;
}
;
-start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; }
+start_block : '{'
+ {
+ STACK_PUSH(blockNum,currBlockno);
+ currBlockno = ++blockNo ;
+ ignoreTypedefType = 0;
+ }
;
end_block : '}' { currBlockno = STACK_POP(blockNum); }
}
else
$$ = $1 ;
+ ignoreTypedefType = 0;
}
| declaration_list declaration
else
$$ = $2 ;
}
+ ignoreTypedefType = 0;
}
;
expression_statement
: ';' { $$ = NULL;}
- | expr ';'
+ | expr ';' { $$ = $1; seqPointNo++;}
;
else_statement
selection_statement
- : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;}
+ : IF '(' expr ')' { seqPointNo++;} statement else_statement
+ {
+ noLineno++ ;
+ $$ = createIf ($3, $6, $7 );
+ noLineno--;
+ }
| SWITCH '(' expr ')' {
ast *ex ;
static int swLabel = 0 ;
+ seqPointNo++;
/* create a node for expression */
ex = newNode(SWITCH,$3,NULL);
STACK_PUSH(swStk,ex); /* save it in the stack */
;
iteration_statement
- : while '(' expr ')' statement
+ : while '(' expr ')' { seqPointNo++;} statement
{
noLineno++ ;
$$ = createWhile ( $1, STACK_POP(continueStack),
- STACK_POP(breakStack), $3, $5 );
+ STACK_POP(breakStack), $3, $6 );
$$->lineno = $1->lineDef ;
noLineno-- ;
}
| do statement WHILE '(' expr ')' ';'
{
+ seqPointNo++;
noLineno++ ;
$$ = createDo ( $1 , STACK_POP(continueStack),
STACK_POP(breakStack), $5, $2);
;
expr_opt
- : { $$ = NULL ; }
- | expr
+ : { $$ = NULL ; seqPointNo++; }
+ | expr { $$ = $1 ; seqPointNo++; }
;
jump_statement
}
}
| RETURN ';' {
+ seqPointNo++;
if (inCritical) {
werror(E_INVALID_CRITICAL);
$$ = NULL;
}
}
| RETURN expr ';' {
+ seqPointNo++;
if (inCritical) {
werror(E_INVALID_CRITICAL);
$$ = NULL;