ref: d93d39b724055b9e8b8f342481308d0e0f634b7a
parent: c821608f58c35cdcd45433f0173ab1ad84ba8093
author: Roberto E. Vargas Caballero <[email protected]>
date: Sun Aug 26 05:43:43 EDT 2012
Added support for different namespace in the symbol table The symbol table hold symbols relative to different namespaces, (keywords, identifiers, labels ...). So we need can lookup only in one namespace. When the lexical analysis is done, we don't have this information, but we need the symbol pointer requested later. The aproach used in this patch consist in assume number of duplicated symbol names is low, so we usually will catch the correct one without be worried in the namespace, and later, in the moment that we have enough information of the symbol, check is the namespace is correct or we have to do a new lookup with the correct namespace.
--- a/decl.c
+++ b/decl.c
@@ -13,16 +13,22 @@
static void declarator(void);
-static struct symbol *
-newiden(char *s)
+static void
+newiden(void)
{
- register struct symbol *sym = lookup(yytext);
-
- if (!sym)
- sym = install(yytext);
- else if (sym->ctx == curctx)
- error("redeclaration of '%s'", yytext);
- return sym;
+ switch (yyval.sym->ns) {
+ case NS_ANY: /* First aparrence of the symbol */
+ yyval.sym->ns = NS_IDEN;
+ yyval.sym->ctx = curctx;
+ break;
+ case NS_STRUCT: case NS_LABEL: case NS_TYPEDEF:
+ lookup(yytext, NS_IDEN, CTX_ANY);
+ case NS_IDEN:
+ if (yyval.sym->ctx == curctx)
+ error("redeclaration of '%s'", yytext);
+ default:
+ lookup(yytext, NS_IDEN, curctx);
+ }
}
static void
@@ -32,7 +38,7 @@
declarator();
expect(')');
} else if (yytoken == IDEN) {
- newiden(yytext);
+ newiden();
next();
} else {
error("expected '(' or identifier before of '%s'", yytext);
@@ -162,7 +168,7 @@
tp = newctype();
if (!spec(tp)) {
- if (curctx != OUTER_CTX)
+ if (curctx != CTX_OUTER)
return 0;
warning("data definition has no type or storage class");
}
--- a/keyword.c
+++ b/keyword.c
@@ -51,9 +51,8 @@
register struct symbol *sym;
for (bp = keywords; bp->str; bp++) {
- sym = install(bp->str);
+ sym = lookup(bp->str, NS_KEYWORD, CTX_ANY);
sym->tok = bp->tok;
- sym->ns = NS_KEYWORD;
}
new_ctx();
}
--- a/lex.c
+++ b/lex.c
@@ -24,7 +24,6 @@
{
register char *bp;
register char ch;
- register struct symbol *sym;
for (bp = yytext; bp < yytext + TOKSIZ_MAX; *bp++ = ch) {
if (!isdigit(ch = getc(yyin)))
@@ -34,8 +33,8 @@
error("identifier too long %s", yytext);
*bp = '\0';
ungetc(ch, yyin);
- yyval.sym = sym = install(NULL);
- sym->val = atoi(yytext);
+ yyval.sym = lookup(yytext, NS_ANY, CTX_ANY);
+ yyval.sym->val = atoi(yytext);
return CONSTANT;
}
@@ -54,10 +53,9 @@
error("identifier too long %s", yytext);
*bp = '\0';
ungetc(ch, yyin);
- if ((sym = lookup(yytext)) && sym->ns == NS_KEYWORD)
- return sym->tok;
- yyval.sym = sym;
- return IDEN;
+ yyval.sym = lookup(yytext, NS_ANY, CTX_ANY);
+
+ return (yyval.sym->ns == NS_KEYWORD) ? yyval.sym->tok : IDEN;
}
static unsigned char
--- a/symbol.c
+++ b/symbol.c
@@ -52,7 +52,7 @@
{
register struct symbol *sym, *next;
- if (curctx == OUTER_CTX) {
+ if (curctx == CTX_OUTER) {
for (sym = headfun; sym; sym = next) {
next = sym->next;
free(sym->name);
@@ -62,39 +62,28 @@
}
struct symbol *
-install(const char *s)
+lookup(register const char *s, unsigned char ns, unsigned char ctx)
{
register struct symbol *sym;
- register unsigned char key;
+ static unsigned char l, key;
+ l = strlen(s);
+ for (sym = htab[hash(s)]; sym; sym = sym->hash) {
+ if (!memcmp(sym->name, s, l) &&
+ (ns == NS_ANY || ns == sym->ns) &&
+ (sym->ctx == ctx || ctx == CTX_ANY)) {
+ return sym;
+ }
+ }
sym = xmalloc(sizeof(*sym));
- sym->ctx = curctx;
+ sym->name = xstrdup(s);
+ sym->ns = ns;
+ sym->ctx = CTX_ANY;
sym->next = head;
head = sym;
+ key = hash(s);
+ sym->hash = htab[key];
+ htab[key] = sym;
- if (s) {
- sym->name = xstrdup(s);
- key = hash(s);
- sym->hash = htab[key];
- htab[key] = sym;
- sym->ns = NS_IDEN;
- } else {
- sym->hash = NULL;
- sym->name = NULL;
- }
- return sym;
-}
-
-struct symbol *
-lookup(const char *s)
-{
- register struct symbol *sym;
- static unsigned char l;
-
- l = strlen(s);
- for (sym = htab[hash(s)]; sym; sym = sym->hash) {
- if (!memcmp(sym->name, s, l))
- break;
- }
return sym;
}
--- a/symbol.h
+++ b/symbol.h
@@ -7,13 +7,15 @@
# include <stdbool.h>
#endif
-#define OUTER_CTX 1
+#define CTX_OUTER 1
+#define CTX_ANY 0
enum namespace {
NS_IDEN,
NS_KEYWORD,
NS_STRUCT,
NS_LABEL,
- NS_TYPEDEF
+ NS_TYPEDEF,
+ NS_ANY
};
struct ctype {
@@ -56,8 +58,8 @@
extern void new_ctx(void);
extern void del_ctx(void);
extern void freesyms(void);
-extern struct symbol *install(const char *s);
-extern struct symbol *lookup(const char *s);
+extern struct symbol *lookup(register const char *s,
+ unsigned char ns, unsigned char ctx);
extern void ctype(struct ctype *cp, unsigned char mod);
extern struct ctype *newctype(void);
extern void delctype(register struct ctype *tp);
--- a/types.c
+++ b/types.c
@@ -157,7 +157,7 @@
cp->c_static = 1;
return;
case AUTO:
- if (curctx != OUTER_CTX)
+ if (curctx != CTX_OUTER)
goto bad_file_scope_storage;
if (cp->c_type | cp->c_extern | cp->c_static | cp->c_reg)
goto two_storage;
@@ -166,7 +166,7 @@
cp->c_static = 1;
return;
case REGISTER:
- if (curctx != OUTER_CTX)
+ if (curctx != CTX_OUTER)
goto bad_file_scope_storage;
if (cp->c_type | cp->c_extern | cp->c_auto | cp->c_static)
goto two_storage;