[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