summaryrefslogtreecommitdiffstats
path: root/contrib/byacc/reader.c
diff options
context:
space:
mode:
authorrodrigc <rodrigc@FreeBSD.org>2014-10-11 19:34:41 +0000
committerrodrigc <rodrigc@FreeBSD.org>2014-10-11 19:34:41 +0000
commita4222aadd697ce4b01020ab3ed88d54b0d53871f (patch)
treebda1498f6f047eb64827df7ff50e43b988d4eccb /contrib/byacc/reader.c
parente054537bc7c2b4e39e4560faa33b4806017025c1 (diff)
downloadFreeBSD-src-a4222aadd697ce4b01020ab3ed88d54b0d53871f.zip
FreeBSD-src-a4222aadd697ce4b01020ab3ed88d54b0d53871f.tar.gz
Merge: 272655
Import byacc 20141005 from vendor
Diffstat (limited to 'contrib/byacc/reader.c')
-rw-r--r--contrib/byacc/reader.c401
1 files changed, 294 insertions, 107 deletions
diff --git a/contrib/byacc/reader.c b/contrib/byacc/reader.c
index dfd3620..9fc50a2 100644
--- a/contrib/byacc/reader.c
+++ b/contrib/byacc/reader.c
@@ -1,4 +1,4 @@
-/* $Id: reader.c,v 1.47 2014/04/09 21:09:27 tom Exp $ */
+/* $Id: reader.c,v 1.57 2014/10/06 00:52:44 tom Exp $ */
#include "defs.h"
@@ -70,6 +70,7 @@ static bucket *default_destructor[3] =
static bucket *
lookup_type_destructor(char *tag)
{
+ const char fmt[] = "%.*s destructor";
char name[1024] = "\0";
bucket *bp, **bpp = &default_destructor[TYPE_SPECIFIED];
@@ -80,7 +81,8 @@ lookup_type_destructor(char *tag)
bpp = &bp->link;
}
- *bpp = bp = make_bucket(strcat(strcpy(name, tag), " destructor"));
+ sprintf(name, fmt, (int)(sizeof(name) - sizeof(fmt)), tag);
+ *bpp = bp = make_bucket(name);
bp->tag = tag;
return (bp);
@@ -205,7 +207,7 @@ skip_comment(void)
}
static int
-nextc(void)
+next_inline(void)
{
char *s;
@@ -221,27 +223,6 @@ nextc(void)
{
switch (*s)
{
- case '\n':
- get_line();
- if (line == 0)
- return (EOF);
- s = cptr;
- break;
-
- case ' ':
- case '\t':
- case '\f':
- case '\r':
- case '\v':
- case ',':
- case ';':
- ++s;
- break;
-
- case '\\':
- cptr = s;
- return ('%');
-
case '/':
if (s[1] == '*')
{
@@ -266,6 +247,41 @@ nextc(void)
}
}
}
+
+static int
+nextc(void)
+{
+ int ch;
+ int finish = 0;
+
+ do
+ {
+ switch (ch = next_inline())
+ {
+ case '\n':
+ get_line();
+ break;
+ case ' ':
+ case '\t':
+ case '\f':
+ case '\r':
+ case '\v':
+ case ',':
+ case ';':
+ ++cptr;
+ break;
+ case '\\':
+ ch = '%';
+ /* FALLTHRU */
+ default:
+ finish = 1;
+ break;
+ }
+ }
+ while (!finish);
+
+ return ch;
+}
/* *INDENT-OFF* */
static struct keyword
{
@@ -644,92 +660,109 @@ copy_union(void)
}
}
+static char *
+after_blanks(char *s)
+{
+ while (*s != '\0' && isspace(UCH(*s)))
+ ++s;
+ return s;
+}
+
/*
- * Keep a linked list of parameters
+ * Trim leading/trailing blanks, and collapse multiple embedded blanks to a
+ * single space. Return index to last character in the buffer.
*/
-static void
-copy_param(int k)
+static int
+trim_blanks(char *buffer)
{
- char *buf;
- int c;
- param *head, *p;
- int i;
- int name, type2;
-
- c = nextc();
- if (c == EOF)
- unexpected_EOF();
- if (c != L_CURL)
- goto out;
- cptr++;
+ if (*buffer != '\0')
+ {
+ char *d = buffer;
+ char *s = after_blanks(d);
- c = nextc();
- if (c == EOF)
- unexpected_EOF();
- if (c == R_CURL)
- goto out;
+ while ((*d++ = *s++) != '\0')
+ {
+ ;
+ }
- buf = TMALLOC(char, linesize);
- NO_SPACE(buf);
+ --d;
+ while ((--d != buffer) && isspace(UCH(*d)))
+ *d = '\0';
- for (i = 0; (c = *cptr++) != R_CURL; i++)
- {
- if (c == '\0')
- missing_brace();
- if (c == EOF)
- unexpected_EOF();
- buf[i] = (char)c;
+ for (s = d = buffer; (*d++ = *s++) != '\0';)
+ {
+ if (isspace(UCH(*s)))
+ {
+ *s = ' ';
+ while (isspace(UCH(*s)))
+ {
+ *s++ = ' ';
+ }
+ --s;
+ }
+ }
}
- if (i == 0)
- goto out;
-
- buf[i--] = '\0';
- while (i > 0 && isspace(UCH(buf[i])))
- buf[i--] = '\0';
+ return (int)strlen(buffer) - 1;
+}
- if (buf[i] == ']')
+/*
+ * Scan forward in the current line-buffer looking for a right-curly bracket.
+ *
+ * Parameters begin with a left-curly bracket, and continue until there are no
+ * more interesting characters after the last right-curly bracket on the
+ * current line. Bison documents parameters as separated like this:
+ * {type param1} {type2 param2}
+ * but also accepts commas (although some versions of bison mishandle this)
+ * {type param1, type2 param2}
+ */
+static int
+more_curly(void)
+{
+ char *save = cptr;
+ int result = 0;
+ int finish = 0;
+ do
{
- int level = 1;
- while (i >= 0 && level > 0 && buf[i] != '[')
+ switch (next_inline())
{
- if (buf[i] == ']')
- ++level;
- else if (buf[i] == '[')
- --level;
- i--;
+ case 0:
+ case '\n':
+ finish = 1;
+ break;
+ case R_CURL:
+ finish = 1;
+ result = 1;
+ break;
}
- if (i <= 0)
- unexpected_EOF();
- type2 = i--;
- }
- else
- {
- type2 = i + 1;
+ ++cptr;
}
+ while (!finish);
+ cptr = save;
+ return result;
+}
- while (i > 0 && (isalnum(UCH(buf[i])) ||
- UCH(buf[i]) == '_'))
- i--;
-
- if (!isspace(UCH(buf[i])) && buf[i] != '*')
- goto out;
-
- name = i + 1;
+static void
+save_param(int k, char *buffer, int name, int type2)
+{
+ param *head, *p;
p = TMALLOC(param, 1);
NO_SPACE(p);
- p->type2 = strdup(buf + type2);
+ p->type2 = strdup(buffer + type2);
NO_SPACE(p->type2);
+ buffer[type2] = '\0';
+ (void)trim_blanks(p->type2);
- buf[type2] = '\0';
-
- p->name = strdup(buf + name);
+ p->name = strdup(buffer + name);
NO_SPACE(p->name);
+ buffer[name] = '\0';
+ (void)trim_blanks(p->name);
- buf[name] = '\0';
- p->type = buf;
+ p->type = strdup(buffer);
+ NO_SPACE(p->type);
+ (void)trim_blanks(p->type);
if (k == LEX_PARAM)
head = lex_param;
@@ -750,9 +783,169 @@ copy_param(int k)
parse_param = p;
}
p->next = NULL;
+}
+
+/*
+ * Keep a linked list of parameters. This may be multi-line, if the trailing
+ * right-curly bracket is absent.
+ */
+static void
+copy_param(int k)
+{
+ int c;
+ int name, type2;
+ int curly = 0;
+ char *buf = 0;
+ int i = -1;
+ size_t buf_size = 0;
+ int st_lineno = lineno;
+ char *comma;
+
+ do
+ {
+ int state = curly;
+ c = next_inline();
+ switch (c)
+ {
+ case EOF:
+ unexpected_EOF();
+ break;
+ case L_CURL:
+ if (curly == 1)
+ {
+ goto oops;
+ }
+ curly = 1;
+ st_lineno = lineno;
+ break;
+ case R_CURL:
+ if (curly != 1)
+ {
+ goto oops;
+ }
+ curly = 2;
+ break;
+ case '\n':
+ if (curly == 0)
+ {
+ goto oops;
+ }
+ break;
+ case '%':
+ if ((curly == 1) && (cptr == line))
+ {
+ lineno = st_lineno;
+ missing_brace();
+ }
+ /* FALLTHRU */
+ case '"':
+ case '\'':
+ goto oops;
+ default:
+ if (curly == 0 && !isspace(UCH(c)))
+ {
+ goto oops;
+ }
+ break;
+ }
+ if (buf == 0)
+ {
+ buf_size = (size_t) linesize;
+ buf = TMALLOC(char, buf_size);
+ }
+ else if (c == '\n')
+ {
+ get_line();
+ if (line == 0)
+ unexpected_EOF();
+ --cptr;
+ buf_size += (size_t) linesize;
+ buf = TREALLOC(char, buf, buf_size);
+ }
+ NO_SPACE(buf);
+ if (curly)
+ {
+ if ((state == 2) && (c == L_CURL))
+ {
+ buf[++i] = ',';
+ }
+ else if ((state == 2) && isspace(UCH(c)))
+ {
+ ;
+ }
+ else if ((c != L_CURL) && (c != R_CURL))
+ {
+ buf[++i] = (char)c;
+ }
+ }
+ cptr++;
+ }
+ while (curly < 2 || more_curly());
+
+ if (i == 0)
+ {
+ if (curly == 1)
+ {
+ lineno = st_lineno;
+ missing_brace();
+ }
+ goto oops;
+ }
+
+ buf[i--] = '\0';
+ i = trim_blanks(buf);
+
+ comma = buf - 1;
+ do
+ {
+ char *parms = (comma + 1);
+ comma = strchr(parms, ',');
+ if (comma != 0)
+ *comma = '\0';
+
+ (void)trim_blanks(parms);
+ i = (int)strlen(parms) - 1;
+ if (i < 0)
+ {
+ goto oops;
+ }
+
+ if (parms[i] == ']')
+ {
+ int level = 1;
+ while (i >= 0 && level > 0 && parms[i] != '[')
+ {
+ if (parms[i] == ']')
+ ++level;
+ else if (parms[i] == '[')
+ --level;
+ i--;
+ }
+ if (i <= 0)
+ unexpected_EOF();
+ type2 = i--;
+ }
+ else
+ {
+ type2 = i + 1;
+ }
+
+ while (i > 0 && (isalnum(UCH(parms[i])) || UCH(parms[i]) == '_'))
+ i--;
+
+ if (!isspace(UCH(parms[i])) && parms[i] != '*')
+ goto oops;
+
+ name = i + 1;
+
+ save_param(k, parms, name, type2);
+ }
+ while (comma != 0);
+ FREE(buf);
return;
- out:
+ oops:
+ FREE(buf);
syntax_error(lineno, line, cptr);
}
@@ -1634,10 +1827,11 @@ compile_arg(char **theptr, char *yyvaltag)
{
offsets = TMALLOC(Value_t, maxoffset + 1);
NO_SPACE(offsets);
+
+ for (j = 0, i++; i < nitems; i++)
+ if (pitem[i]->class != ARGUMENT)
+ offsets[++j] = (Value_t) (i - nitems + 1);
}
- for (j = 0, i++; i < nitems; i++)
- if (pitem[i]->class != ARGUMENT)
- offsets[++j] = (Value_t) (i - nitems + 1);
rhs = pitem + nitems - 1;
if (yyvaltag)
@@ -1664,7 +1858,7 @@ compile_arg(char **theptr, char *yyvaltag)
dollar_warning(rescan_lineno, val);
i = val - maxoffset;
}
- else
+ else if (maxoffset > 0)
{
i = offsets[val];
if (!tag && !(tag = rhs[i]->tag) && havetags)
@@ -2020,14 +2214,6 @@ add_symbol(void)
pitem[nitems - 1] = bp;
}
-static char *
-after_blanks(char *s)
-{
- while (*s != '\0' && isspace(UCH(*s)))
- ++s;
- return s;
-}
-
static void
copy_action(void)
{
@@ -2084,12 +2270,13 @@ copy_action(void)
{
offsets = TMALLOC(Value_t, maxoffset + 1);
NO_SPACE(offsets);
- }
- for (j = 0, i++; i < nitems; i++)
- {
- if (pitem[i]->class != ARGUMENT)
+
+ for (j = 0, i++; i < nitems; i++)
{
- offsets[++j] = (Value_t) (i - nitems + 1);
+ if (pitem[i]->class != ARGUMENT)
+ {
+ offsets[++j] = (Value_t) (i - nitems + 1);
+ }
}
}
rhs = pitem + nitems - 1;
@@ -2177,7 +2364,7 @@ copy_action(void)
{
++cptr;
i = get_number();
- if (havetags)
+ if (havetags && offsets)
{
if (i <= 0 || i > maxoffset)
unknown_rhs(i);
OpenPOWER on IntegriCloud