[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