[master] 81f25bd Use the symbol table to dispatch action-parsers
Poul-Henning Kamp
phk at FreeBSD.org
Tue Jan 30 11:01:08 UTC 2018
commit 81f25bdfb987238c473130f442cf7b90abd4153d
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Tue Jan 30 09:48:26 2018 +0000
Use the symbol table to dispatch action-parsers
diff --git a/lib/libvcc/vcc_action.c b/lib/libvcc/vcc_action.c
index 0472479..d131def 100644
--- a/lib/libvcc/vcc_action.c
+++ b/lib/libvcc/vcc_action.c
@@ -52,6 +52,7 @@ parse_call(struct vcc *tl)
VCC_GlobalSymbol(sym, SUB, "VGC_function");
Fb(tl, 1, "%s(ctx);\n", sym->rname);
vcc_NextToken(tl);
+ SkipToken(tl, ';');
}
/*--------------------------------------------------------------------*/
@@ -136,6 +137,7 @@ parse_set(struct vcc *tl)
}
tl->indent -= INDENT;
Fb(tl, 1, ");\n");
+ SkipToken(tl, ';');
}
/*--------------------------------------------------------------------*/
@@ -161,6 +163,7 @@ parse_unset(struct vcc *tl)
}
vcc_AddUses(tl, t, tl->t, sym->u_methods, "Cannot be unset");
Fb(tl, 1, "%s;\n", sym->uname);
+ SkipToken(tl, ';');
}
/*--------------------------------------------------------------------*/
@@ -181,8 +184,8 @@ parse_ban(struct vcc *tl)
ERRCHK(tl);
Fb(tl, 1, ");\n");
- ExpectErr(tl, ')');
- vcc_NextToken(tl);
+ SkipToken(tl, ')');
+ SkipToken(tl, ';');
}
/*--------------------------------------------------------------------*/
@@ -198,6 +201,7 @@ parse_hash_data(struct vcc *tl)
ERRCHK(tl);
Fb(tl, 1, ");\n");
SkipToken(tl, ')');
+ SkipToken(tl, ';');
}
/*--------------------------------------------------------------------*/
@@ -212,8 +216,7 @@ parse_return_pass(struct vcc *tl)
tl->indent += INDENT;
vcc_Expr(tl, DURATION);
ERRCHK(tl);
- ExpectErr(tl, ')');
- vcc_NextToken(tl);
+ SkipToken(tl, ')');
Fb(tl, 1, ");\n");
tl->indent -= INDENT;
}
@@ -238,8 +241,7 @@ parse_return_synth(struct vcc *tl)
Fb(tl, 1, "(const char*)0\n");
}
tl->indent -= INDENT;
- ExpectErr(tl, ')');
- vcc_NextToken(tl);
+ SkipToken(tl, ')');
Fb(tl, 1, ");\n");
}
@@ -279,8 +281,7 @@ parse_return_vcl(struct vcc *tl)
Fb(tl, 1, "VRT_vcl_select(ctx, %s);\t/* %s */\n",
(const char*)sym->eval_priv, sym->name);
vcc_NextToken(tl);
- ExpectErr(tl, ')');
- vcc_NextToken(tl);
+ SkipToken(tl, ')');
}
/*--------------------------------------------------------------------*/
@@ -294,11 +295,11 @@ parse_return(struct vcc *tl)
vcc_NextToken(tl);
AN(tl->curproc);
if (tl->t->tok == ';' && tl->curproc->method == NULL) {
+ SkipToken(tl, ';');
Fb(tl, 1, "return;\n");
return;
}
- ExpectErr(tl, '(');
- vcc_NextToken(tl);
+ SkipToken(tl, '(');
ExpectErr(tl, ID);
hand = VCL_RET_MAX;
@@ -337,8 +338,8 @@ parse_return(struct vcc *tl)
}
ERRCHK(tl);
Fb(tl, 1, "VRT_handling(ctx, VCL_RET_%s);\n", h);
- ExpectErr(tl, ')');
- vcc_NextToken(tl);
+ SkipToken(tl, ')');
+ SkipToken(tl, ';');
}
/*--------------------------------------------------------------------*/
@@ -357,55 +358,37 @@ parse_synthetic(struct vcc *tl)
ERRCHK(tl);
Fb(tl, 1, ");\n");
- ExpectErr(tl, ')');
- vcc_NextToken(tl);
- ERRCHK(tl);
+ SkipToken(tl, ')');
+ SkipToken(tl, ';');
}
/*--------------------------------------------------------------------*/
-typedef void action_f(struct vcc *tl);
-
-static struct action_table {
- const char *name;
- action_f *func;
- unsigned bitmask;
-} action_table[] = {
- /* Keep list sorted from here */
- { "ban", parse_ban },
- { "call", parse_call },
- { "hash_data", parse_hash_data, VCL_MET_HASH },
- { "new", vcc_ParseNew, VCL_MET_INIT},
- { "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)
+// The pp[] trick is to make the length of #name visible to flexelint.
+#define ACT(name, func, mask) \
+ do { \
+ const char pp[] = #name; \
+ sym = VCC_Symbol(tl, NULL, pp, NULL, SYM_ACTION, 1); \
+ AN(sym); \
+ sym->action = func; \
+ sym->action_mask = (mask); \
+ } while (0)
+
+void
+vcc_Action_Init(struct vcc *tl)
{
- struct token *at;
- struct action_table *atp;
struct symbol *sym;
- at = tl->t;
- assert(at->tok == ID);
- for (atp = action_table; atp->name != NULL; atp++) {
- if (vcc_IdIs(at, atp->name)) {
- if (atp->bitmask != 0)
- vcc_AddUses(tl, at, NULL, atp->bitmask,
- "Not a valid action");
- atp->func(tl);
- return (1);
- }
- }
- sym = VCC_SymbolTok(tl, SYM_NONE, 0);
- if (sym != NULL && sym->kind == SYM_FUNC) {
- vcc_Expr_Call(tl, sym);
- return (1);
- }
- return (0);
+ ACT(ban, parse_ban, 0);
+ ACT(call, parse_call, 0);
+ ACT(hash_data, parse_hash_data,
+ VCL_MET_HASH);
+ ACT(if, vcc_ParseIf, 0);
+ ACT(new, vcc_ParseNew,
+ VCL_MET_INIT);
+ ACT(return, parse_return, 0);
+ ACT(set, parse_set, 0);
+ ACT(synthetic, parse_synthetic,
+ VCL_MET_SYNTH | VCL_MET_BACKEND_ERROR);
+ ACT(unset, parse_unset, 0);
}
diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c
index ce2d151..7161b9d 100644
--- a/lib/libvcc/vcc_compile.c
+++ b/lib/libvcc/vcc_compile.c
@@ -563,6 +563,8 @@ vcc_CompileSource(struct vcc *tl, struct source *sp)
vcc_Expr_Init(tl);
+ vcc_Action_Init(tl);
+
vcc_Backend_Init(tl);
vcc_Var_Init(tl);
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index 8d5a75b..f590a8e 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -109,6 +109,8 @@ typedef void sym_expr_t(struct vcc *tl, struct expr **,
typedef void sym_wildcard_t(struct vcc *, struct symbol *,
const char *, const char *);
+typedef void sym_act_f(struct vcc *tl);
+
struct symbol {
unsigned magic;
#define SYMBOL_MAGIC 0x3368c9fb
@@ -123,6 +125,9 @@ struct symbol {
sym_wildcard_t *wildcard;
enum symkind kind;
+ sym_act_f *action;
+ unsigned action_mask;
+
const struct token *def_b, *def_e, *ref_b;
vcc_type_t fmt;
@@ -239,7 +244,7 @@ struct method {
void vcc_ParseAcl(struct vcc *tl);
/* vcc_action.c */
-int vcc_ParseAction(struct vcc *tl);
+void vcc_Action_Init(struct vcc *);
/* vcc_backend.c */
struct fld_spec;
@@ -290,6 +295,7 @@ void vcc_Var_Init(struct vcc *);
/* vcc_parse.c */
void vcc_Parse(struct vcc *tl);
+void vcc_ParseIf(struct vcc *tl);
/* vcc_utils.c */
const char *vcc_regexp(struct vcc *tl);
diff --git a/lib/libvcc/vcc_parse.c b/lib/libvcc/vcc_parse.c
index 666b06b..1d6fcb1 100644
--- a/lib/libvcc/vcc_parse.c
+++ b/lib/libvcc/vcc_parse.c
@@ -79,8 +79,8 @@ vcc_Conditional(struct vcc *tl)
* null
*/
-static void
-vcc_IfStmt(struct vcc *tl)
+void
+vcc_ParseIf(struct vcc *tl)
{
SkipToken(tl, ID);
@@ -141,7 +141,8 @@ vcc_IfStmt(struct vcc *tl)
static void
vcc_Compound(struct vcc *tl)
{
- int i;
+ struct symbol *sym;
+ struct token *t;
SkipToken(tl, '{');
Fb(tl, 1, "{\n");
@@ -149,6 +150,7 @@ vcc_Compound(struct vcc *tl)
C(tl, ";");
while (1) {
ERRCHK(tl);
+ t = tl->t;
switch (tl->t->tok) {
case '{':
vcc_Compound(tl);
@@ -176,16 +178,19 @@ vcc_Compound(struct vcc *tl)
tl->err = 1;
return;
case ID:
- if (vcc_IdIs(tl->t, "if")) {
- vcc_IfStmt(tl);
+ sym = VCC_SymbolTok(tl, SYM_NONE, 0);
+ 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;
- } else {
- i = vcc_ParseAction(tl);
- ERRCHK(tl);
- if (i) {
- SkipToken(tl, ';');
- break;
- }
}
/* FALLTHROUGH */
default:
diff --git a/lib/libvcc/vcc_symb.c b/lib/libvcc/vcc_symb.c
index 042268d..4078619 100644
--- a/lib/libvcc/vcc_symb.c
+++ b/lib/libvcc/vcc_symb.c
@@ -184,10 +184,8 @@ VCC_Symbol(struct vcc *tl, struct symbol *parent,
continue;
if (q < e)
break;
- if (kind != SYM_NONE && sym->kind != SYM_NONE &&
- kind != sym->kind)
- continue;
- if (kind == SYM_NONE && sym->kind == kind)
+ if ((kind == SYM_NONE && kind == sym->kind) ||
+ (kind != SYM_NONE && kind != sym->kind))
continue;
break;
}
diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c
index 2b51c4f..67d82f9 100644
--- a/lib/libvcc/vcc_vmod.c
+++ b/lib/libvcc/vcc_vmod.c
@@ -314,7 +314,7 @@ vcc_ParseNew(struct vcc *tl)
bprintf(buf1, ", &%s, \"%s\"", sy1->rname, sy1->name);
vcc_Eval_Func(tl, p, buf1, sy2);
ERRCHK(tl);
- ExpectErr(tl, ';');
+ SkipToken(tl, ';');
while (p[0] != '\0' || p[1] != '\0' || p[2] != '\0')
p++;
More information about the varnish-commit
mailing list