Commit 81f25bdf authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Use the symbol table to dispatch action-parsers

parent a535c1ae
...@@ -52,6 +52,7 @@ parse_call(struct vcc *tl) ...@@ -52,6 +52,7 @@ parse_call(struct vcc *tl)
VCC_GlobalSymbol(sym, SUB, "VGC_function"); VCC_GlobalSymbol(sym, SUB, "VGC_function");
Fb(tl, 1, "%s(ctx);\n", sym->rname); Fb(tl, 1, "%s(ctx);\n", sym->rname);
vcc_NextToken(tl); vcc_NextToken(tl);
SkipToken(tl, ';');
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
...@@ -136,6 +137,7 @@ parse_set(struct vcc *tl) ...@@ -136,6 +137,7 @@ parse_set(struct vcc *tl)
} }
tl->indent -= INDENT; tl->indent -= INDENT;
Fb(tl, 1, ");\n"); Fb(tl, 1, ");\n");
SkipToken(tl, ';');
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
...@@ -161,6 +163,7 @@ parse_unset(struct vcc *tl) ...@@ -161,6 +163,7 @@ parse_unset(struct vcc *tl)
} }
vcc_AddUses(tl, t, tl->t, sym->u_methods, "Cannot be unset"); vcc_AddUses(tl, t, tl->t, sym->u_methods, "Cannot be unset");
Fb(tl, 1, "%s;\n", sym->uname); Fb(tl, 1, "%s;\n", sym->uname);
SkipToken(tl, ';');
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
...@@ -181,8 +184,8 @@ parse_ban(struct vcc *tl) ...@@ -181,8 +184,8 @@ parse_ban(struct vcc *tl)
ERRCHK(tl); ERRCHK(tl);
Fb(tl, 1, ");\n"); Fb(tl, 1, ");\n");
ExpectErr(tl, ')'); SkipToken(tl, ')');
vcc_NextToken(tl); SkipToken(tl, ';');
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
...@@ -198,6 +201,7 @@ parse_hash_data(struct vcc *tl) ...@@ -198,6 +201,7 @@ parse_hash_data(struct vcc *tl)
ERRCHK(tl); ERRCHK(tl);
Fb(tl, 1, ");\n"); Fb(tl, 1, ");\n");
SkipToken(tl, ')'); SkipToken(tl, ')');
SkipToken(tl, ';');
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
...@@ -212,8 +216,7 @@ parse_return_pass(struct vcc *tl) ...@@ -212,8 +216,7 @@ parse_return_pass(struct vcc *tl)
tl->indent += INDENT; tl->indent += INDENT;
vcc_Expr(tl, DURATION); vcc_Expr(tl, DURATION);
ERRCHK(tl); ERRCHK(tl);
ExpectErr(tl, ')'); SkipToken(tl, ')');
vcc_NextToken(tl);
Fb(tl, 1, ");\n"); Fb(tl, 1, ");\n");
tl->indent -= INDENT; tl->indent -= INDENT;
} }
...@@ -238,8 +241,7 @@ parse_return_synth(struct vcc *tl) ...@@ -238,8 +241,7 @@ parse_return_synth(struct vcc *tl)
Fb(tl, 1, "(const char*)0\n"); Fb(tl, 1, "(const char*)0\n");
} }
tl->indent -= INDENT; tl->indent -= INDENT;
ExpectErr(tl, ')'); SkipToken(tl, ')');
vcc_NextToken(tl);
Fb(tl, 1, ");\n"); Fb(tl, 1, ");\n");
} }
...@@ -279,8 +281,7 @@ parse_return_vcl(struct vcc *tl) ...@@ -279,8 +281,7 @@ parse_return_vcl(struct vcc *tl)
Fb(tl, 1, "VRT_vcl_select(ctx, %s);\t/* %s */\n", Fb(tl, 1, "VRT_vcl_select(ctx, %s);\t/* %s */\n",
(const char*)sym->eval_priv, sym->name); (const char*)sym->eval_priv, sym->name);
vcc_NextToken(tl); vcc_NextToken(tl);
ExpectErr(tl, ')'); SkipToken(tl, ')');
vcc_NextToken(tl);
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
...@@ -294,11 +295,11 @@ parse_return(struct vcc *tl) ...@@ -294,11 +295,11 @@ parse_return(struct vcc *tl)
vcc_NextToken(tl); vcc_NextToken(tl);
AN(tl->curproc); AN(tl->curproc);
if (tl->t->tok == ';' && tl->curproc->method == NULL) { if (tl->t->tok == ';' && tl->curproc->method == NULL) {
SkipToken(tl, ';');
Fb(tl, 1, "return;\n"); Fb(tl, 1, "return;\n");
return; return;
} }
ExpectErr(tl, '('); SkipToken(tl, '(');
vcc_NextToken(tl);
ExpectErr(tl, ID); ExpectErr(tl, ID);
hand = VCL_RET_MAX; hand = VCL_RET_MAX;
...@@ -337,8 +338,8 @@ parse_return(struct vcc *tl) ...@@ -337,8 +338,8 @@ parse_return(struct vcc *tl)
} }
ERRCHK(tl); ERRCHK(tl);
Fb(tl, 1, "VRT_handling(ctx, VCL_RET_%s);\n", h); Fb(tl, 1, "VRT_handling(ctx, VCL_RET_%s);\n", h);
ExpectErr(tl, ')'); SkipToken(tl, ')');
vcc_NextToken(tl); SkipToken(tl, ';');
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
...@@ -357,55 +358,37 @@ parse_synthetic(struct vcc *tl) ...@@ -357,55 +358,37 @@ parse_synthetic(struct vcc *tl)
ERRCHK(tl); ERRCHK(tl);
Fb(tl, 1, ");\n"); Fb(tl, 1, ");\n");
ExpectErr(tl, ')'); SkipToken(tl, ')');
vcc_NextToken(tl); SkipToken(tl, ';');
ERRCHK(tl);
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
typedef void action_f(struct vcc *tl); // The pp[] trick is to make the length of #name visible to flexelint.
#define ACT(name, func, mask) \
static struct action_table { do { \
const char *name; const char pp[] = #name; \
action_f *func; sym = VCC_Symbol(tl, NULL, pp, NULL, SYM_ACTION, 1); \
unsigned bitmask; AN(sym); \
} action_table[] = { sym->action = func; \
/* Keep list sorted from here */ sym->action_mask = (mask); \
{ "ban", parse_ban }, } while (0)
{ "call", parse_call },
{ "hash_data", parse_hash_data, VCL_MET_HASH }, void
{ "new", vcc_ParseNew, VCL_MET_INIT}, vcc_Action_Init(struct vcc *tl)
{ "return", parse_return },
{ "set", parse_set },
{ "synthetic", parse_synthetic,
VCL_MET_SYNTH | VCL_MET_BACKEND_ERROR },
{ "unset", parse_unset },
{ NULL, NULL }
};
int
vcc_ParseAction(struct vcc *tl)
{ {
struct token *at;
struct action_table *atp;
struct symbol *sym; struct symbol *sym;
at = tl->t; ACT(ban, parse_ban, 0);
assert(at->tok == ID); ACT(call, parse_call, 0);
for (atp = action_table; atp->name != NULL; atp++) { ACT(hash_data, parse_hash_data,
if (vcc_IdIs(at, atp->name)) { VCL_MET_HASH);
if (atp->bitmask != 0) ACT(if, vcc_ParseIf, 0);
vcc_AddUses(tl, at, NULL, atp->bitmask, ACT(new, vcc_ParseNew,
"Not a valid action"); VCL_MET_INIT);
atp->func(tl); ACT(return, parse_return, 0);
return (1); ACT(set, parse_set, 0);
} ACT(synthetic, parse_synthetic,
} VCL_MET_SYNTH | VCL_MET_BACKEND_ERROR);
sym = VCC_SymbolTok(tl, SYM_NONE, 0); ACT(unset, parse_unset, 0);
if (sym != NULL && sym->kind == SYM_FUNC) {
vcc_Expr_Call(tl, sym);
return (1);
}
return (0);
} }
...@@ -563,6 +563,8 @@ vcc_CompileSource(struct vcc *tl, struct source *sp) ...@@ -563,6 +563,8 @@ vcc_CompileSource(struct vcc *tl, struct source *sp)
vcc_Expr_Init(tl); vcc_Expr_Init(tl);
vcc_Action_Init(tl);
vcc_Backend_Init(tl); vcc_Backend_Init(tl);
vcc_Var_Init(tl); vcc_Var_Init(tl);
......
...@@ -109,6 +109,8 @@ typedef void sym_expr_t(struct vcc *tl, struct expr **, ...@@ -109,6 +109,8 @@ typedef void sym_expr_t(struct vcc *tl, struct expr **,
typedef void sym_wildcard_t(struct vcc *, struct symbol *, typedef void sym_wildcard_t(struct vcc *, struct symbol *,
const char *, const char *); const char *, const char *);
typedef void sym_act_f(struct vcc *tl);
struct symbol { struct symbol {
unsigned magic; unsigned magic;
#define SYMBOL_MAGIC 0x3368c9fb #define SYMBOL_MAGIC 0x3368c9fb
...@@ -123,6 +125,9 @@ struct symbol { ...@@ -123,6 +125,9 @@ struct symbol {
sym_wildcard_t *wildcard; sym_wildcard_t *wildcard;
enum symkind kind; enum symkind kind;
sym_act_f *action;
unsigned action_mask;
const struct token *def_b, *def_e, *ref_b; const struct token *def_b, *def_e, *ref_b;
vcc_type_t fmt; vcc_type_t fmt;
...@@ -239,7 +244,7 @@ struct method { ...@@ -239,7 +244,7 @@ struct method {
void vcc_ParseAcl(struct vcc *tl); void vcc_ParseAcl(struct vcc *tl);
/* vcc_action.c */ /* vcc_action.c */
int vcc_ParseAction(struct vcc *tl); void vcc_Action_Init(struct vcc *);
/* vcc_backend.c */ /* vcc_backend.c */
struct fld_spec; struct fld_spec;
...@@ -290,6 +295,7 @@ void vcc_Var_Init(struct vcc *); ...@@ -290,6 +295,7 @@ void vcc_Var_Init(struct vcc *);
/* vcc_parse.c */ /* vcc_parse.c */
void vcc_Parse(struct vcc *tl); void vcc_Parse(struct vcc *tl);
void vcc_ParseIf(struct vcc *tl);
/* vcc_utils.c */ /* vcc_utils.c */
const char *vcc_regexp(struct vcc *tl); const char *vcc_regexp(struct vcc *tl);
......
...@@ -79,8 +79,8 @@ vcc_Conditional(struct vcc *tl) ...@@ -79,8 +79,8 @@ vcc_Conditional(struct vcc *tl)
* null * null
*/ */
static void void
vcc_IfStmt(struct vcc *tl) vcc_ParseIf(struct vcc *tl)
{ {
SkipToken(tl, ID); SkipToken(tl, ID);
...@@ -141,7 +141,8 @@ vcc_IfStmt(struct vcc *tl) ...@@ -141,7 +141,8 @@ vcc_IfStmt(struct vcc *tl)
static void static void
vcc_Compound(struct vcc *tl) vcc_Compound(struct vcc *tl)
{ {
int i; struct symbol *sym;
struct token *t;
SkipToken(tl, '{'); SkipToken(tl, '{');
Fb(tl, 1, "{\n"); Fb(tl, 1, "{\n");
...@@ -149,6 +150,7 @@ vcc_Compound(struct vcc *tl) ...@@ -149,6 +150,7 @@ vcc_Compound(struct vcc *tl)
C(tl, ";"); C(tl, ";");
while (1) { while (1) {
ERRCHK(tl); ERRCHK(tl);
t = tl->t;
switch (tl->t->tok) { switch (tl->t->tok) {
case '{': case '{':
vcc_Compound(tl); vcc_Compound(tl);
...@@ -176,16 +178,19 @@ vcc_Compound(struct vcc *tl) ...@@ -176,16 +178,19 @@ vcc_Compound(struct vcc *tl)
tl->err = 1; tl->err = 1;
return; return;
case ID: case ID:
if (vcc_IdIs(tl->t, "if")) { sym = VCC_SymbolTok(tl, SYM_NONE, 0);
vcc_IfStmt(tl); if (sym != NULL && sym->action != NULL) {
if (sym->action_mask != 0)
vcc_AddUses(tl, t, NULL,
sym->action_mask,
"Not a valid action");
sym->action(tl);
break;
}
if (sym != NULL && sym->kind == SYM_FUNC) {
vcc_Expr_Call(tl, sym);
SkipToken(tl, ';');
break; break;
} else {
i = vcc_ParseAction(tl);
ERRCHK(tl);
if (i) {
SkipToken(tl, ';');
break;
}
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
......
...@@ -184,10 +184,8 @@ VCC_Symbol(struct vcc *tl, struct symbol *parent, ...@@ -184,10 +184,8 @@ VCC_Symbol(struct vcc *tl, struct symbol *parent,
continue; continue;
if (q < e) if (q < e)
break; break;
if (kind != SYM_NONE && sym->kind != SYM_NONE && if ((kind == SYM_NONE && kind == sym->kind) ||
kind != sym->kind) (kind != SYM_NONE && kind != sym->kind))
continue;
if (kind == SYM_NONE && sym->kind == kind)
continue; continue;
break; break;
} }
......
...@@ -314,7 +314,7 @@ vcc_ParseNew(struct vcc *tl) ...@@ -314,7 +314,7 @@ vcc_ParseNew(struct vcc *tl)
bprintf(buf1, ", &%s, \"%s\"", sy1->rname, sy1->name); bprintf(buf1, ", &%s, \"%s\"", sy1->rname, sy1->name);
vcc_Eval_Func(tl, p, buf1, sy2); vcc_Eval_Func(tl, p, buf1, sy2);
ERRCHK(tl); ERRCHK(tl);
ExpectErr(tl, ';'); SkipToken(tl, ';');
while (p[0] != '\0' || p[1] != '\0' || p[2] != '\0') while (p[0] != '\0' || p[1] != '\0' || p[2] != '\0')
p++; p++;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment