[master] 126203852 Parse identifiers element by element.

Poul-Henning Kamp phk at FreeBSD.org
Wed May 29 14:38:09 UTC 2019


commit 1262038523db35653e97977fc874fbf8ae92b41b
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed May 29 14:36:25 2019 +0000

    Parse identifiers element by element.
    
    This is not very elegant, but I wanted to maintain the
    same error messages for now.  More to come.

diff --git a/include/vct.h b/include/vct.h
index 24143a332..44021f72d 100644
--- a/include/vct.h
+++ b/include/vct.h
@@ -43,7 +43,6 @@
 #define VCT_TCHAR		(1<<9)
 #define VCT_ID			(1<<10)
 #define VCT_IDENT		(VCT_ALPHA | VCT_DIGIT | VCT_ID)
-#define VCT_VAR			(1<<11)
 #define VCT_VT			(1<<12)
 #define VCT_SPACE		(VCT_LWS | VCT_VT)
 
@@ -71,7 +70,6 @@ vct_is(int x, uint16_t y)
 #define vct_issepctl(x) vct_is(x, VCT_SEPARATOR | VCT_CTL)
 #define vct_isident1(x) vct_isalpha(x)
 #define vct_isident(x) vct_is(x, VCT_IDENT)
-#define vct_isvar(x) vct_is(x, VCT_IDENT | VCT_VAR)
 #define vct_isxmlnamestart(x) vct_is(x, VCT_XMLNAMESTART)
 #define vct_isxmlname(x) vct_is(x, VCT_XMLNAMESTART | VCT_XMLNAME)
 #define vct_istchar(x) vct_is(x, VCT_ALPHA | VCT_DIGIT | VCT_TCHAR)
diff --git a/lib/libvarnish/vct.c b/lib/libvarnish/vct.c
index 73b784e32..a86e2e427 100644
--- a/lib/libvarnish/vct.c
+++ b/lib/libvarnish/vct.c
@@ -91,7 +91,7 @@ const uint16_t vct_typtab[256] = {
 	[0x2b]  =	VCT_TCHAR,
 	[0x2c]  =	VCT_SEPARATOR,
 	[0x2d]	=	VCT_XMLNAME | VCT_TCHAR | VCT_ID,
-	[0x2e]	=	VCT_XMLNAME | VCT_TCHAR | VCT_VAR,
+	[0x2e]	=	VCT_XMLNAME | VCT_TCHAR,
 	[0x2f]  =	VCT_SEPARATOR,
 	[0x30]	=	VCT_DIGIT | VCT_HEX | VCT_XMLNAME,
 	[0x31]	=	VCT_DIGIT | VCT_HEX | VCT_XMLNAME,
diff --git a/lib/libvcc/vcc_symb.c b/lib/libvcc/vcc_symb.c
index fb64b26cb..048efc896 100644
--- a/lib/libvcc/vcc_symb.c
+++ b/lib/libvcc/vcc_symb.c
@@ -262,6 +262,22 @@ const char XREF_REF[] = "xref_ref";
 const char SYMTAB_NOERR[] = "sym_noerror";
 const char SYMTAB_CREATE[] = "sym_create";
 
+static void
+vcc_symxref(struct symbol *sym, const char *x, const struct token *t)
+{
+	if (x == XREF_DEF) {
+		if (sym->def_b == NULL)
+			sym->def_b = t;
+		sym->ndef++;
+	} else if (x == XREF_REF) {
+		if (sym->ref_b == NULL)
+			sym->ref_b = t;
+		sym->nref++;
+	} else {
+		assert (x == XREF_NONE);
+	}
+}
+
 struct symbol *
 VCC_SymbolGetTok(struct vcc *tl, vcc_kind_t kind, const char *e, const char *x,
     const struct token *t)
@@ -320,28 +336,90 @@ VCC_SymbolGetTok(struct vcc *tl, vcc_kind_t kind, const char *e, const char *x,
 		}
 		return (NULL);
 	}
-	if (x == XREF_DEF) {
-		if (sym->def_b == NULL)
-			sym->def_b = t;
-		sym->ndef++;
-	} else if (x == XREF_REF) {
-		if (sym->ref_b == NULL)
-			sym->ref_b = t;
-		sym->nref++;
-	} else {
-		assert (x == XREF_NONE);
-	}
+	vcc_symxref(sym, x, t);
 	return (sym);
 }
 
 struct symbol *
 VCC_SymbolGet(struct vcc *tl, vcc_kind_t kind, const char *e, const char *x)
 {
+	struct symtab *st;
 	struct symbol *sym;
+	struct token *tn, *tn1;
+
+	if (tl->syntax >= VCL_41 && e == SYMTAB_CREATE && kind != SYM_SUB &&
+	    (tl->t->b[0] == 'v'|| tl->t->b[0] == 'V') &&
+	    (tl->t->b[1] == 'c'|| tl->t->b[1] == 'C') &&
+	    (tl->t->b[2] == 'l'|| tl->t->b[2] == 'L') &&
+	    (tl->t->b[3] == '_')) {
+		VSB_printf(tl->sb,
+		    "Symbols named 'vcl_*' are reserved.\nAt:");
+		vcc_ErrWhere(tl, tl->t);
+		return (NULL);
+	}
 
-	sym = VCC_SymbolGetTok(tl, kind, e, x, tl->t);
-	if (sym != NULL)
-		vcc_NextToken(tl);
+	st = tl->syms;
+	tn = tl->t;
+	while (1) {
+		st = vcc_symtab_str(st, tn->b, tn->e);
+		tn1 = VTAILQ_NEXT(tn, list);
+		if (tn1->tok != '.')
+			break;
+		tn1 = VTAILQ_NEXT(tn1, list);
+		if (tn1->tok != ID)
+			break;
+		tn = tn1;
+	}
+	sym = vcc_sym_in_tab(tl, st, kind, tl->syntax, tl->syntax);
+	if (sym == NULL && e == SYMTAB_CREATE) {
+		sym = vcc_new_symbol(tl, st);
+		sym->lorev = tl->syntax;
+		sym->hirev = tl->syntax;
+		sym->kind = kind;
+	}
+	if (sym == NULL && e == SYMTAB_NOERR)
+		return (sym);
+	if (sym == NULL) {
+		VSB_printf(tl->sb, "%s: '", e);
+		tn = VTAILQ_NEXT(tn, list);
+		for (tn1 = tl->t; tn1 != tn; tn1 = VTAILQ_NEXT(tn1, list))
+			VSB_printf(tl->sb, "%.*s", PF(tn1));
+		VSB_printf(tl->sb, "'");
+		sym = vcc_sym_in_tab(tl, st, kind, VCL_LOW, VCL_HIGH);
+		if (sym != NULL) {
+			VSB_printf(tl->sb, " (Only available when");
+			if (sym->lorev >= VCL_LOW)
+				VSB_printf(tl->sb, " %.1f <=", .1 * sym->lorev);
+			VSB_printf(tl->sb, " VCL syntax");
+			if (sym->hirev <= VCL_HIGH)
+				VSB_printf(tl->sb, " <= %.1f", .1 * sym->hirev);
+			VSB_printf(tl->sb, ")");
+		}
+		VSB_cat(tl->sb, "\nAt: ");
+		vcc_ErrWhere(tl, tl->t);
+		return (NULL);
+	}
+	if (kind != SYM_NONE && kind != sym->kind) {
+		VSB_printf(tl->sb, "Symbol '");
+		tn = VTAILQ_NEXT(tn, list);
+		for (tn1 = tl->t; tn1 != tn; tn1 = VTAILQ_NEXT(tn1, list))
+			VSB_printf(tl->sb, "%.*s", PF(tn1));
+		VSB_printf(tl->sb, "' has wrong type (%s): ", sym->kind->name);
+		VSB_cat(tl->sb, "\nAt: ");
+		vcc_ErrWhere2(tl, tl->t, tn);
+		if (sym->def_b != NULL) {
+			VSB_printf(tl->sb, "Symbol was defined here: ");
+			vcc_ErrWhere(tl, sym->def_b);
+		} else if (sym->ref_b != NULL) {
+			VSB_printf(tl->sb, "Symbol was declared here: ");
+			vcc_ErrWhere(tl, sym->ref_b);
+		} else {
+			VSB_printf(tl->sb, "Symbol was builtin\n");
+		}
+		return (NULL);
+	}
+	vcc_symxref(sym, x, tl->t);
+	tl->t = VTAILQ_NEXT(tn, list);
 	return (sym);
 }
 
diff --git a/lib/libvcc/vcc_token.c b/lib/libvcc/vcc_token.c
index fcd37796c..090c84439 100644
--- a/lib/libvcc/vcc_token.c
+++ b/lib/libvcc/vcc_token.c
@@ -299,18 +299,29 @@ vcc_IdIs(const struct token *t, const char *p)
 void
 vcc_ExpectVid(struct vcc *tl, const char *what)
 {
-	const char *bad;
+	const char *bad = NULL;
+	struct token *t2, *t3;
 
 	ExpectErr(tl, ID);
 	ERRCHK(tl);
 
-	bad = VCT_invalid_name(tl->t->b, tl->t->e);
+	t2 = VTAILQ_NEXT(tl->t, list);
+	while (t2->tok == '.') {
+		bad = ".";
+		t2 = VTAILQ_NEXT(t2, list);
+		if (t2->tok != ID)
+			break;
+		t2 = VTAILQ_NEXT(t2, list);
+	}
+	if (bad == NULL)
+		bad = VCT_invalid_name(tl->t->b, tl->t->e);
 	if (bad != NULL) {
-		VSB_printf(tl->sb, "Name of %s, ", what);
-		vcc_ErrToken(tl, tl->t);
+		VSB_printf(tl->sb, "Name of %s, '", what);
+		for (t3 = tl->t; t3 != t2; t3 = VTAILQ_NEXT(t3, list))
+			VSB_printf(tl->sb, "%.*s", PF(t3));
 		VSB_printf(tl->sb,
-		    ", contains illegal character '%c'\n", *bad);
-		vcc_ErrWhere(tl, tl->t);
+		    "', contains illegal character '%c'\n", *bad);
+		vcc_ErrWhere2(tl, tl->t, t2);
 		return;
 	}
 }
@@ -493,7 +504,7 @@ vcc_Lexer(struct vcc *tl, struct source *sp)
 		/* Match Identifiers */
 		if (vct_isident1(*p)) {
 			for (q = p; q < sp->e; q++)
-				if (!vct_isvar(*q))
+				if (!vct_isident(*q))
 					break;
 			vcc_AddToken(tl, ID, p, q);
 			p = q;


More information about the varnish-commit mailing list