[cexpr] Keep track of unidentified symbol names

At least with a push-parser, by the time the parser has figured out it
has an identifier, the lexer has forgotten the token, thus the annoying
and uninformative "undefined identifier " error messages. Since
identifiers should always have a value (and functions need a function
type), setting up a dummy symbol with just the identifier name
duplicated seems to do the trick. It is a bit wasteful of memory if
there are a lot of such errors between cmem resets, though.
This commit is contained in:
Bill Currie 2023-02-11 12:17:23 +09:00
parent cb99c4d907
commit 65e15c2dd0
2 changed files with 10 additions and 3 deletions

View file

@ -312,6 +312,13 @@ parse_name (const char *name, exprctx_t *context)
sym = Hash_Find (symtab->tab, name);
}
if (!sym) {
sym = cmemalloc (context->memsuper, sizeof (exprsym_t));
size_t size = strlen (name) + 1;
char *sym_name = cmemalloc (context->memsuper, size);
memcpy (sym_name, name, size);
*sym = (exprsym_t) { .name = sym_name };
}
return sym;
}

View file

@ -113,13 +113,13 @@ start
uexpr
: NAME
{
if ($1) {
if ($1->value) {
$$ = (exprval_t *) cmemalloc (context->memsuper, sizeof (*$$));
$$->type = $1->type;
$$->value = $1->value;
} else {
cexpr_error (context, "undefined identifier %s",
cexpr_yyget_text (scanner));
cexpr_error (context, "undefined identifier %s", $1->name);
$$ = 0;
}
}
| VALUE