default:
// this could be just "constant"
// werror(W_PTR_TYPE_INVALID);
+ ;
}
}
else
/* go to the end of the list */
sym_link *p;
pointerTypes($2,$1);
- for ( p = $2 ; p->next ; p=p->next);
- p->next = $1 ;
- $$ = $2 ;
+ for ( p = $2 ; p && p->next ; p=p->next);
+ if (!p) {
+ werror(E_SYNTAX_ERROR, yytext);
+ } else {
+ p->next = $1 ;
+ }
+ $$ = $2 ;
}
;
// $1 must be a pointer to a function
sym_link *p=newLink();
DCL_TYPE(p) = FUNCTION;
+ if (!$1) {
+ // ((void (code *) ()) 0) ()
+ $1=newLink();
+ DCL_TYPE($1)=CPOINTER;
+ $$ = $1;
+ }
$1->next=p;
}
| abstract_declarator2 '(' parameter_type_list ')' {
// $1 must be a pointer to a function
sym_link *p=newLink();
DCL_TYPE(p) = FUNCTION;
+ if (!$1) {
+ // ((void (code *) (void)) 0) ()
+ $1=newLink();
+ DCL_TYPE($1)=CPOINTER;
+ $$ = $1;
+ }
$1->next=p;
}
}
+ ;
initializer
: assignment_expr { $$ = newiList(INIT_NODE,$1); }
sprintf (lbuff,"_whilebody_%d",Lblnum++);
$$ = newSymbol(lbuff,NestLevel);
}
+ ;
do : DO { /* create and push the continue , break & body Labels */
static int Lblnum = 0 ;
sprintf (lbuff,"_dobody_%d",Lblnum++);
$$ = newSymbol (lbuff,NestLevel);
}
+ ;
+
for : FOR { /* create & push continue, break & body labels */
static int Lblnum = 0 ;
sprintf (lbuff,"_forcond_%d",Lblnum++);
STACK_PUSH(forStack,newSymbol(lbuff,NestLevel));
}
+ ;
iteration_statement
: while '(' expr ')' statement