1*0a6a1f1dSLionel Sambuc /* $NetBSD: reader.c,v 1.12 2015/01/04 19:30:26 joerg Exp $ */
284d9c625SLionel Sambuc
3*0a6a1f1dSLionel Sambuc /* Id: reader.c,v 1.58 2014/10/06 22:15:08 tom Exp */
44a17663cSThomas Veerman
54a17663cSThomas Veerman #include "defs.h"
64a17663cSThomas Veerman
74a17663cSThomas Veerman #include <sys/cdefs.h>
8*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: reader.c,v 1.12 2015/01/04 19:30:26 joerg Exp $");
94a17663cSThomas Veerman
104a17663cSThomas Veerman /* The line size must be a positive integer. One hundred was chosen */
114a17663cSThomas Veerman /* because few lines in Yacc input grammars exceed 100 characters. */
124a17663cSThomas Veerman /* Note that if a line exceeds LINESIZE characters, the line buffer */
134a17663cSThomas Veerman /* will be expanded to accomodate it. */
144a17663cSThomas Veerman
154a17663cSThomas Veerman #define LINESIZE 100
164a17663cSThomas Veerman
174a17663cSThomas Veerman #define L_CURL '{'
184a17663cSThomas Veerman #define R_CURL '}'
19*0a6a1f1dSLionel Sambuc #define L_PAREN '('
20*0a6a1f1dSLionel Sambuc #define R_PAREN ')'
21*0a6a1f1dSLionel Sambuc #define L_BRAC '['
22*0a6a1f1dSLionel Sambuc #define R_BRAC ']'
23*0a6a1f1dSLionel Sambuc
24*0a6a1f1dSLionel Sambuc /* the maximum number of arguments (inherited attributes) to a non-terminal */
25*0a6a1f1dSLionel Sambuc /* this is a hard limit, but seems more than adequate */
26*0a6a1f1dSLionel Sambuc #define MAXARGS 20
274a17663cSThomas Veerman
284a17663cSThomas Veerman static void start_rule(bucket *bp, int s_lineno);
29*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
30*0a6a1f1dSLionel Sambuc static void copy_initial_action(void);
31*0a6a1f1dSLionel Sambuc static void copy_destructor(void);
32*0a6a1f1dSLionel Sambuc static char *process_destructor_XX(char *code, char *tag);
33*0a6a1f1dSLionel Sambuc #endif
344a17663cSThomas Veerman
354a17663cSThomas Veerman static char *cache;
364a17663cSThomas Veerman static int cinc, cache_size;
374a17663cSThomas Veerman
384a17663cSThomas Veerman int ntags;
39*0a6a1f1dSLionel Sambuc static int tagmax, havetags;
404a17663cSThomas Veerman static char **tag_table;
414a17663cSThomas Veerman
424a17663cSThomas Veerman static char saw_eof;
434a17663cSThomas Veerman char unionized;
444a17663cSThomas Veerman char *cptr, *line;
454a17663cSThomas Veerman static int linesize;
464a17663cSThomas Veerman
474a17663cSThomas Veerman static bucket *goal;
484a17663cSThomas Veerman static Value_t prec;
494a17663cSThomas Veerman static int gensym;
504a17663cSThomas Veerman static char last_was_action;
514a17663cSThomas Veerman
524a17663cSThomas Veerman static int maxitems;
534a17663cSThomas Veerman static bucket **pitem;
544a17663cSThomas Veerman
554a17663cSThomas Veerman static int maxrules;
564a17663cSThomas Veerman static bucket **plhs;
574a17663cSThomas Veerman
584a17663cSThomas Veerman static size_t name_pool_size;
594a17663cSThomas Veerman static char *name_pool;
604a17663cSThomas Veerman
614a17663cSThomas Veerman char line_format[] = "#line %d \"%s\"\n";
624a17663cSThomas Veerman
634a17663cSThomas Veerman param *lex_param;
644a17663cSThomas Veerman param *parse_param;
654a17663cSThomas Veerman
66*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
67*0a6a1f1dSLionel Sambuc int destructor = 0; /* =1 if at least one %destructor */
68*0a6a1f1dSLionel Sambuc
69*0a6a1f1dSLionel Sambuc static bucket *default_destructor[3] =
70*0a6a1f1dSLionel Sambuc {0, 0, 0};
71*0a6a1f1dSLionel Sambuc
72*0a6a1f1dSLionel Sambuc #define UNTYPED_DEFAULT 0
73*0a6a1f1dSLionel Sambuc #define TYPED_DEFAULT 1
74*0a6a1f1dSLionel Sambuc #define TYPE_SPECIFIED 2
75*0a6a1f1dSLionel Sambuc
76*0a6a1f1dSLionel Sambuc static bucket *
lookup_type_destructor(char * tag)77*0a6a1f1dSLionel Sambuc lookup_type_destructor(char *tag)
78*0a6a1f1dSLionel Sambuc {
79*0a6a1f1dSLionel Sambuc const char fmt[] = "%.*s destructor";
80*0a6a1f1dSLionel Sambuc char name[1024] = "\0";
81*0a6a1f1dSLionel Sambuc bucket *bp, **bpp = &default_destructor[TYPE_SPECIFIED];
82*0a6a1f1dSLionel Sambuc
83*0a6a1f1dSLionel Sambuc while ((bp = *bpp) != NULL)
84*0a6a1f1dSLionel Sambuc {
85*0a6a1f1dSLionel Sambuc if (bp->tag == tag)
86*0a6a1f1dSLionel Sambuc return (bp);
87*0a6a1f1dSLionel Sambuc bpp = &bp->link;
88*0a6a1f1dSLionel Sambuc }
89*0a6a1f1dSLionel Sambuc
90*0a6a1f1dSLionel Sambuc sprintf(name, fmt, (int)(sizeof(name) - sizeof(fmt)), tag);
91*0a6a1f1dSLionel Sambuc *bpp = bp = make_bucket(name);
92*0a6a1f1dSLionel Sambuc bp->tag = tag;
93*0a6a1f1dSLionel Sambuc
94*0a6a1f1dSLionel Sambuc return (bp);
95*0a6a1f1dSLionel Sambuc }
96*0a6a1f1dSLionel Sambuc #endif /* defined(YYBTYACC) */
97*0a6a1f1dSLionel Sambuc
984a17663cSThomas Veerman static void
cachec(int c)994a17663cSThomas Veerman cachec(int c)
1004a17663cSThomas Veerman {
1014a17663cSThomas Veerman assert(cinc >= 0);
1024a17663cSThomas Veerman if (cinc >= cache_size)
1034a17663cSThomas Veerman {
1044a17663cSThomas Veerman cache_size += 256;
10584d9c625SLionel Sambuc cache = TREALLOC(char, cache, cache_size);
1064a17663cSThomas Veerman NO_SPACE(cache);
1074a17663cSThomas Veerman }
1084a17663cSThomas Veerman cache[cinc] = (char)c;
1094a17663cSThomas Veerman ++cinc;
1104a17663cSThomas Veerman }
1114a17663cSThomas Veerman
1124a17663cSThomas Veerman static void
get_line(void)1134a17663cSThomas Veerman get_line(void)
1144a17663cSThomas Veerman {
1154a17663cSThomas Veerman FILE *f = input_file;
1164a17663cSThomas Veerman int c;
1174a17663cSThomas Veerman int i;
1184a17663cSThomas Veerman
1194a17663cSThomas Veerman if (saw_eof || (c = getc(f)) == EOF)
1204a17663cSThomas Veerman {
1214a17663cSThomas Veerman if (line)
1224a17663cSThomas Veerman {
1234a17663cSThomas Veerman FREE(line);
1244a17663cSThomas Veerman line = 0;
1254a17663cSThomas Veerman }
1264a17663cSThomas Veerman cptr = 0;
1274a17663cSThomas Veerman saw_eof = 1;
1284a17663cSThomas Veerman return;
1294a17663cSThomas Veerman }
1304a17663cSThomas Veerman
1314a17663cSThomas Veerman if (line == 0 || linesize != (LINESIZE + 1))
1324a17663cSThomas Veerman {
1334a17663cSThomas Veerman if (line)
1344a17663cSThomas Veerman FREE(line);
1354a17663cSThomas Veerman linesize = LINESIZE + 1;
13684d9c625SLionel Sambuc line = TMALLOC(char, linesize);
1374a17663cSThomas Veerman NO_SPACE(line);
1384a17663cSThomas Veerman }
1394a17663cSThomas Veerman
1404a17663cSThomas Veerman i = 0;
1414a17663cSThomas Veerman ++lineno;
1424a17663cSThomas Veerman for (;;)
1434a17663cSThomas Veerman {
144*0a6a1f1dSLionel Sambuc line[i++] = (char)c;
1454a17663cSThomas Veerman if (c == '\n')
146*0a6a1f1dSLionel Sambuc break;
147*0a6a1f1dSLionel Sambuc if ((i + 3) >= linesize)
1484a17663cSThomas Veerman {
1494a17663cSThomas Veerman linesize += LINESIZE;
15084d9c625SLionel Sambuc line = TREALLOC(char, line, linesize);
1514a17663cSThomas Veerman NO_SPACE(line);
1524a17663cSThomas Veerman }
1534a17663cSThomas Veerman c = getc(f);
1544a17663cSThomas Veerman if (c == EOF)
1554a17663cSThomas Veerman {
156*0a6a1f1dSLionel Sambuc line[i++] = '\n';
1574a17663cSThomas Veerman saw_eof = 1;
158*0a6a1f1dSLionel Sambuc break;
159*0a6a1f1dSLionel Sambuc }
160*0a6a1f1dSLionel Sambuc }
161*0a6a1f1dSLionel Sambuc line[i] = '\0';
1624a17663cSThomas Veerman cptr = line;
1634a17663cSThomas Veerman return;
1644a17663cSThomas Veerman }
1654a17663cSThomas Veerman
1664a17663cSThomas Veerman static char *
dup_line(void)1674a17663cSThomas Veerman dup_line(void)
1684a17663cSThomas Veerman {
1694a17663cSThomas Veerman char *p, *s, *t;
1704a17663cSThomas Veerman
1714a17663cSThomas Veerman if (line == 0)
1724a17663cSThomas Veerman return (0);
1734a17663cSThomas Veerman s = line;
1744a17663cSThomas Veerman while (*s != '\n')
1754a17663cSThomas Veerman ++s;
17684d9c625SLionel Sambuc p = TMALLOC(char, s - line + 1);
1774a17663cSThomas Veerman NO_SPACE(p);
1784a17663cSThomas Veerman
1794a17663cSThomas Veerman s = line;
1804a17663cSThomas Veerman t = p;
1814a17663cSThomas Veerman while ((*t++ = *s++) != '\n')
1824a17663cSThomas Veerman continue;
1834a17663cSThomas Veerman return (p);
1844a17663cSThomas Veerman }
1854a17663cSThomas Veerman
1864a17663cSThomas Veerman static void
skip_comment(void)1874a17663cSThomas Veerman skip_comment(void)
1884a17663cSThomas Veerman {
1894a17663cSThomas Veerman char *s;
190*0a6a1f1dSLionel Sambuc struct ainfo a;
191*0a6a1f1dSLionel Sambuc a.a_lineno = lineno;
192*0a6a1f1dSLionel Sambuc a.a_line = dup_line();
193*0a6a1f1dSLionel Sambuc a.a_cptr = a.a_line + (cptr - line);
1944a17663cSThomas Veerman
1954a17663cSThomas Veerman s = cptr + 2;
1964a17663cSThomas Veerman for (;;)
1974a17663cSThomas Veerman {
1984a17663cSThomas Veerman if (*s == '*' && s[1] == '/')
1994a17663cSThomas Veerman {
2004a17663cSThomas Veerman cptr = s + 2;
201*0a6a1f1dSLionel Sambuc FREE(a.a_line);
2024a17663cSThomas Veerman return;
2034a17663cSThomas Veerman }
2044a17663cSThomas Veerman if (*s == '\n')
2054a17663cSThomas Veerman {
2064a17663cSThomas Veerman get_line();
2074a17663cSThomas Veerman if (line == 0)
208*0a6a1f1dSLionel Sambuc unterminated_comment(&a);
2094a17663cSThomas Veerman s = cptr;
2104a17663cSThomas Veerman }
2114a17663cSThomas Veerman else
2124a17663cSThomas Veerman ++s;
2134a17663cSThomas Veerman }
2144a17663cSThomas Veerman }
2154a17663cSThomas Veerman
2164a17663cSThomas Veerman static int
next_inline(void)217*0a6a1f1dSLionel Sambuc next_inline(void)
2184a17663cSThomas Veerman {
2194a17663cSThomas Veerman char *s;
2204a17663cSThomas Veerman
2214a17663cSThomas Veerman if (line == 0)
2224a17663cSThomas Veerman {
2234a17663cSThomas Veerman get_line();
2244a17663cSThomas Veerman if (line == 0)
2254a17663cSThomas Veerman return (EOF);
2264a17663cSThomas Veerman }
2274a17663cSThomas Veerman
2284a17663cSThomas Veerman s = cptr;
2294a17663cSThomas Veerman for (;;)
2304a17663cSThomas Veerman {
2314a17663cSThomas Veerman switch (*s)
2324a17663cSThomas Veerman {
2334a17663cSThomas Veerman case '/':
2344a17663cSThomas Veerman if (s[1] == '*')
2354a17663cSThomas Veerman {
2364a17663cSThomas Veerman cptr = s;
2374a17663cSThomas Veerman skip_comment();
2384a17663cSThomas Veerman s = cptr;
2394a17663cSThomas Veerman break;
2404a17663cSThomas Veerman }
2414a17663cSThomas Veerman else if (s[1] == '/')
2424a17663cSThomas Veerman {
2434a17663cSThomas Veerman get_line();
2444a17663cSThomas Veerman if (line == 0)
2454a17663cSThomas Veerman return (EOF);
2464a17663cSThomas Veerman s = cptr;
2474a17663cSThomas Veerman break;
2484a17663cSThomas Veerman }
2494a17663cSThomas Veerman /* FALLTHRU */
2504a17663cSThomas Veerman
2514a17663cSThomas Veerman default:
2524a17663cSThomas Veerman cptr = s;
2534a17663cSThomas Veerman return (*s);
2544a17663cSThomas Veerman }
2554a17663cSThomas Veerman }
2564a17663cSThomas Veerman }
2574a17663cSThomas Veerman
2584a17663cSThomas Veerman static int
nextc(void)259*0a6a1f1dSLionel Sambuc nextc(void)
2604a17663cSThomas Veerman {
261*0a6a1f1dSLionel Sambuc int ch;
262*0a6a1f1dSLionel Sambuc int finish = 0;
2634a17663cSThomas Veerman
264*0a6a1f1dSLionel Sambuc do
2654a17663cSThomas Veerman {
266*0a6a1f1dSLionel Sambuc switch (ch = next_inline())
267*0a6a1f1dSLionel Sambuc {
268*0a6a1f1dSLionel Sambuc case '\n':
269*0a6a1f1dSLionel Sambuc get_line();
2704a17663cSThomas Veerman break;
271*0a6a1f1dSLionel Sambuc case ' ':
272*0a6a1f1dSLionel Sambuc case '\t':
273*0a6a1f1dSLionel Sambuc case '\f':
274*0a6a1f1dSLionel Sambuc case '\r':
275*0a6a1f1dSLionel Sambuc case '\v':
276*0a6a1f1dSLionel Sambuc case ',':
277*0a6a1f1dSLionel Sambuc case ';':
278*0a6a1f1dSLionel Sambuc ++cptr;
279*0a6a1f1dSLionel Sambuc break;
280*0a6a1f1dSLionel Sambuc case '\\':
281*0a6a1f1dSLionel Sambuc ch = '%';
282*0a6a1f1dSLionel Sambuc /* FALLTHRU */
283*0a6a1f1dSLionel Sambuc default:
284*0a6a1f1dSLionel Sambuc finish = 1;
2854a17663cSThomas Veerman break;
2864a17663cSThomas Veerman }
2874a17663cSThomas Veerman }
288*0a6a1f1dSLionel Sambuc while (!finish);
289*0a6a1f1dSLionel Sambuc
290*0a6a1f1dSLionel Sambuc return ch;
291*0a6a1f1dSLionel Sambuc }
292*0a6a1f1dSLionel Sambuc /* *INDENT-OFF* */
293*0a6a1f1dSLionel Sambuc static struct keyword
294*0a6a1f1dSLionel Sambuc {
295*0a6a1f1dSLionel Sambuc char name[14];
296*0a6a1f1dSLionel Sambuc int token;
297*0a6a1f1dSLionel Sambuc }
298*0a6a1f1dSLionel Sambuc keywords[] = {
299*0a6a1f1dSLionel Sambuc { "binary", NONASSOC },
300*0a6a1f1dSLionel Sambuc { "debug", XXXDEBUG },
301*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
302*0a6a1f1dSLionel Sambuc { "destructor", DESTRUCTOR },
303*0a6a1f1dSLionel Sambuc #endif
304*0a6a1f1dSLionel Sambuc { "error-verbose",ERROR_VERBOSE },
305*0a6a1f1dSLionel Sambuc { "expect", EXPECT },
306*0a6a1f1dSLionel Sambuc { "expect-rr", EXPECT_RR },
307*0a6a1f1dSLionel Sambuc { "ident", IDENT },
308*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
309*0a6a1f1dSLionel Sambuc { "initial-action", INITIAL_ACTION },
310*0a6a1f1dSLionel Sambuc #endif
311*0a6a1f1dSLionel Sambuc { "left", LEFT },
312*0a6a1f1dSLionel Sambuc { "lex-param", LEX_PARAM },
313*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
314*0a6a1f1dSLionel Sambuc { "locations", LOCATIONS },
315*0a6a1f1dSLionel Sambuc #endif
316*0a6a1f1dSLionel Sambuc { "nonassoc", NONASSOC },
317*0a6a1f1dSLionel Sambuc { "parse-param", PARSE_PARAM },
318*0a6a1f1dSLionel Sambuc { "pure-parser", PURE_PARSER },
319*0a6a1f1dSLionel Sambuc { "right", RIGHT },
320*0a6a1f1dSLionel Sambuc { "start", START },
321*0a6a1f1dSLionel Sambuc { "term", TOKEN },
322*0a6a1f1dSLionel Sambuc { "token", TOKEN },
323*0a6a1f1dSLionel Sambuc { "token-table", TOKEN_TABLE },
324*0a6a1f1dSLionel Sambuc { "type", TYPE },
325*0a6a1f1dSLionel Sambuc { "union", UNION },
326*0a6a1f1dSLionel Sambuc { "yacc", POSIX_YACC },
327*0a6a1f1dSLionel Sambuc };
328*0a6a1f1dSLionel Sambuc /* *INDENT-ON* */
329*0a6a1f1dSLionel Sambuc
330*0a6a1f1dSLionel Sambuc static int
compare_keys(const void * a,const void * b)331*0a6a1f1dSLionel Sambuc compare_keys(const void *a, const void *b)
332*0a6a1f1dSLionel Sambuc {
333*0a6a1f1dSLionel Sambuc const struct keyword *p = (const struct keyword *)a;
334*0a6a1f1dSLionel Sambuc const struct keyword *q = (const struct keyword *)b;
335*0a6a1f1dSLionel Sambuc return strcmp(p->name, q->name);
3364a17663cSThomas Veerman }
3374a17663cSThomas Veerman
3384a17663cSThomas Veerman static int
keyword(void)3394a17663cSThomas Veerman keyword(void)
3404a17663cSThomas Veerman {
3414a17663cSThomas Veerman int c;
3424a17663cSThomas Veerman char *t_cptr = cptr;
343*0a6a1f1dSLionel Sambuc struct keyword *key;
3444a17663cSThomas Veerman
3454a17663cSThomas Veerman c = *++cptr;
3464a17663cSThomas Veerman if (isalpha(c))
3474a17663cSThomas Veerman {
3484a17663cSThomas Veerman cinc = 0;
3494a17663cSThomas Veerman for (;;)
3504a17663cSThomas Veerman {
3514a17663cSThomas Veerman if (isalpha(c))
3524a17663cSThomas Veerman {
3534a17663cSThomas Veerman if (isupper(c))
3544a17663cSThomas Veerman c = tolower(c);
3554a17663cSThomas Veerman cachec(c);
3564a17663cSThomas Veerman }
3574a17663cSThomas Veerman else if (isdigit(c)
3584a17663cSThomas Veerman || c == '-'
3594a17663cSThomas Veerman || c == '.'
3604a17663cSThomas Veerman || c == '$')
3614a17663cSThomas Veerman {
3624a17663cSThomas Veerman cachec(c);
3634a17663cSThomas Veerman }
364*0a6a1f1dSLionel Sambuc else if (c == '_')
365*0a6a1f1dSLionel Sambuc {
366*0a6a1f1dSLionel Sambuc /* treat keywords spelled with '_' as if it were '-' */
367*0a6a1f1dSLionel Sambuc cachec('-');
368*0a6a1f1dSLionel Sambuc }
3694a17663cSThomas Veerman else
3704a17663cSThomas Veerman {
3714a17663cSThomas Veerman break;
3724a17663cSThomas Veerman }
3734a17663cSThomas Veerman c = *++cptr;
3744a17663cSThomas Veerman }
3754a17663cSThomas Veerman cachec(NUL);
3764a17663cSThomas Veerman
377*0a6a1f1dSLionel Sambuc if ((key = bsearch(cache, keywords,
378*0a6a1f1dSLionel Sambuc sizeof(keywords) / sizeof(*key),
379*0a6a1f1dSLionel Sambuc sizeof(*key), compare_keys)))
380*0a6a1f1dSLionel Sambuc return key->token;
3814a17663cSThomas Veerman }
3824a17663cSThomas Veerman else
3834a17663cSThomas Veerman {
3844a17663cSThomas Veerman ++cptr;
3854a17663cSThomas Veerman if (c == L_CURL)
3864a17663cSThomas Veerman return (TEXT);
3874a17663cSThomas Veerman if (c == '%' || c == '\\')
3884a17663cSThomas Veerman return (MARK);
3894a17663cSThomas Veerman if (c == '<')
3904a17663cSThomas Veerman return (LEFT);
3914a17663cSThomas Veerman if (c == '>')
3924a17663cSThomas Veerman return (RIGHT);
3934a17663cSThomas Veerman if (c == '0')
3944a17663cSThomas Veerman return (TOKEN);
3954a17663cSThomas Veerman if (c == '2')
3964a17663cSThomas Veerman return (NONASSOC);
3974a17663cSThomas Veerman }
3984a17663cSThomas Veerman syntax_error(lineno, line, t_cptr);
3994a17663cSThomas Veerman }
4004a17663cSThomas Veerman
4014a17663cSThomas Veerman
4024a17663cSThomas Veerman static void
copy_ident(void)4034a17663cSThomas Veerman copy_ident(void)
4044a17663cSThomas Veerman {
4054a17663cSThomas Veerman int c;
4064a17663cSThomas Veerman FILE *f = output_file;
4074a17663cSThomas Veerman
4084a17663cSThomas Veerman c = nextc();
4094a17663cSThomas Veerman if (c == EOF)
4104a17663cSThomas Veerman unexpected_EOF();
4114a17663cSThomas Veerman if (c != '"')
4124a17663cSThomas Veerman syntax_error(lineno, line, cptr);
4134a17663cSThomas Veerman ++outline;
4144a17663cSThomas Veerman fprintf(f, "#ident \"");
4154a17663cSThomas Veerman for (;;)
4164a17663cSThomas Veerman {
4174a17663cSThomas Veerman c = *++cptr;
4184a17663cSThomas Veerman if (c == '\n')
4194a17663cSThomas Veerman {
4204a17663cSThomas Veerman fprintf(f, "\"\n");
4214a17663cSThomas Veerman return;
4224a17663cSThomas Veerman }
4234a17663cSThomas Veerman putc(c, f);
4244a17663cSThomas Veerman if (c == '"')
4254a17663cSThomas Veerman {
4264a17663cSThomas Veerman putc('\n', f);
4274a17663cSThomas Veerman ++cptr;
4284a17663cSThomas Veerman return;
4294a17663cSThomas Veerman }
4304a17663cSThomas Veerman }
4314a17663cSThomas Veerman }
4324a17663cSThomas Veerman
433*0a6a1f1dSLionel Sambuc static char *
copy_string(int quote)434*0a6a1f1dSLionel Sambuc copy_string(int quote)
435*0a6a1f1dSLionel Sambuc {
436*0a6a1f1dSLionel Sambuc struct mstring *temp = msnew();
437*0a6a1f1dSLionel Sambuc int c;
438*0a6a1f1dSLionel Sambuc struct ainfo a;
439*0a6a1f1dSLionel Sambuc a.a_lineno = lineno;
440*0a6a1f1dSLionel Sambuc a.a_line = dup_line();
441*0a6a1f1dSLionel Sambuc a.a_cptr = a.a_line + (cptr - line - 1);
442*0a6a1f1dSLionel Sambuc
443*0a6a1f1dSLionel Sambuc for (;;)
444*0a6a1f1dSLionel Sambuc {
445*0a6a1f1dSLionel Sambuc c = *cptr++;
446*0a6a1f1dSLionel Sambuc mputc(temp, c);
447*0a6a1f1dSLionel Sambuc if (c == quote)
448*0a6a1f1dSLionel Sambuc {
449*0a6a1f1dSLionel Sambuc FREE(a.a_line);
450*0a6a1f1dSLionel Sambuc return msdone(temp);
451*0a6a1f1dSLionel Sambuc }
452*0a6a1f1dSLionel Sambuc if (c == '\n')
453*0a6a1f1dSLionel Sambuc unterminated_string(&a);
454*0a6a1f1dSLionel Sambuc if (c == '\\')
455*0a6a1f1dSLionel Sambuc {
456*0a6a1f1dSLionel Sambuc c = *cptr++;
457*0a6a1f1dSLionel Sambuc mputc(temp, c);
458*0a6a1f1dSLionel Sambuc if (c == '\n')
459*0a6a1f1dSLionel Sambuc {
460*0a6a1f1dSLionel Sambuc get_line();
461*0a6a1f1dSLionel Sambuc if (line == 0)
462*0a6a1f1dSLionel Sambuc unterminated_string(&a);
463*0a6a1f1dSLionel Sambuc }
464*0a6a1f1dSLionel Sambuc }
465*0a6a1f1dSLionel Sambuc }
466*0a6a1f1dSLionel Sambuc }
467*0a6a1f1dSLionel Sambuc
468*0a6a1f1dSLionel Sambuc static char *
copy_comment(void)469*0a6a1f1dSLionel Sambuc copy_comment(void)
470*0a6a1f1dSLionel Sambuc {
471*0a6a1f1dSLionel Sambuc struct mstring *temp = msnew();
472*0a6a1f1dSLionel Sambuc int c;
473*0a6a1f1dSLionel Sambuc
474*0a6a1f1dSLionel Sambuc c = *cptr;
475*0a6a1f1dSLionel Sambuc if (c == '/')
476*0a6a1f1dSLionel Sambuc {
477*0a6a1f1dSLionel Sambuc mputc(temp, '*');
478*0a6a1f1dSLionel Sambuc while ((c = *++cptr) != '\n')
479*0a6a1f1dSLionel Sambuc {
480*0a6a1f1dSLionel Sambuc mputc(temp, c);
481*0a6a1f1dSLionel Sambuc if (c == '*' && cptr[1] == '/')
482*0a6a1f1dSLionel Sambuc mputc(temp, ' ');
483*0a6a1f1dSLionel Sambuc }
484*0a6a1f1dSLionel Sambuc mputc(temp, '*');
485*0a6a1f1dSLionel Sambuc mputc(temp, '/');
486*0a6a1f1dSLionel Sambuc }
487*0a6a1f1dSLionel Sambuc else if (c == '*')
488*0a6a1f1dSLionel Sambuc {
489*0a6a1f1dSLionel Sambuc struct ainfo a;
490*0a6a1f1dSLionel Sambuc a.a_lineno = lineno;
491*0a6a1f1dSLionel Sambuc a.a_line = dup_line();
492*0a6a1f1dSLionel Sambuc a.a_cptr = a.a_line + (cptr - line - 1);
493*0a6a1f1dSLionel Sambuc
494*0a6a1f1dSLionel Sambuc mputc(temp, c);
495*0a6a1f1dSLionel Sambuc ++cptr;
496*0a6a1f1dSLionel Sambuc for (;;)
497*0a6a1f1dSLionel Sambuc {
498*0a6a1f1dSLionel Sambuc c = *cptr++;
499*0a6a1f1dSLionel Sambuc mputc(temp, c);
500*0a6a1f1dSLionel Sambuc if (c == '*' && *cptr == '/')
501*0a6a1f1dSLionel Sambuc {
502*0a6a1f1dSLionel Sambuc mputc(temp, '/');
503*0a6a1f1dSLionel Sambuc ++cptr;
504*0a6a1f1dSLionel Sambuc FREE(a.a_line);
505*0a6a1f1dSLionel Sambuc return msdone(temp);
506*0a6a1f1dSLionel Sambuc }
507*0a6a1f1dSLionel Sambuc if (c == '\n')
508*0a6a1f1dSLionel Sambuc {
509*0a6a1f1dSLionel Sambuc get_line();
510*0a6a1f1dSLionel Sambuc if (line == 0)
511*0a6a1f1dSLionel Sambuc unterminated_comment(&a);
512*0a6a1f1dSLionel Sambuc }
513*0a6a1f1dSLionel Sambuc }
514*0a6a1f1dSLionel Sambuc }
515*0a6a1f1dSLionel Sambuc return msdone(temp);
516*0a6a1f1dSLionel Sambuc }
517*0a6a1f1dSLionel Sambuc
5184a17663cSThomas Veerman static void
copy_text(void)5194a17663cSThomas Veerman copy_text(void)
5204a17663cSThomas Veerman {
5214a17663cSThomas Veerman int c;
5224a17663cSThomas Veerman FILE *f = text_file;
5234a17663cSThomas Veerman int need_newline = 0;
524*0a6a1f1dSLionel Sambuc struct ainfo a;
525*0a6a1f1dSLionel Sambuc a.a_lineno = lineno;
526*0a6a1f1dSLionel Sambuc a.a_line = dup_line();
527*0a6a1f1dSLionel Sambuc a.a_cptr = a.a_line + (cptr - line - 2);
5284a17663cSThomas Veerman
5294a17663cSThomas Veerman if (*cptr == '\n')
5304a17663cSThomas Veerman {
5314a17663cSThomas Veerman get_line();
5324a17663cSThomas Veerman if (line == 0)
533*0a6a1f1dSLionel Sambuc unterminated_text(&a);
5344a17663cSThomas Veerman }
5354a17663cSThomas Veerman if (!lflag)
5364a17663cSThomas Veerman fprintf(f, line_format, lineno, input_file_name);
5374a17663cSThomas Veerman
5384a17663cSThomas Veerman loop:
5394a17663cSThomas Veerman c = *cptr++;
5404a17663cSThomas Veerman switch (c)
5414a17663cSThomas Veerman {
5424a17663cSThomas Veerman case '\n':
5434a17663cSThomas Veerman putc('\n', f);
5444a17663cSThomas Veerman need_newline = 0;
5454a17663cSThomas Veerman get_line();
5464a17663cSThomas Veerman if (line)
5474a17663cSThomas Veerman goto loop;
548*0a6a1f1dSLionel Sambuc unterminated_text(&a);
5494a17663cSThomas Veerman
5504a17663cSThomas Veerman case '\'':
5514a17663cSThomas Veerman case '"':
5524a17663cSThomas Veerman putc(c, f);
5534a17663cSThomas Veerman {
554*0a6a1f1dSLionel Sambuc char *s = copy_string(c);
555*0a6a1f1dSLionel Sambuc fputs(s, f);
556*0a6a1f1dSLionel Sambuc free(s);
557*0a6a1f1dSLionel Sambuc }
5584a17663cSThomas Veerman need_newline = 1;
5594a17663cSThomas Veerman goto loop;
5604a17663cSThomas Veerman
5614a17663cSThomas Veerman case '/':
5624a17663cSThomas Veerman putc(c, f);
5634a17663cSThomas Veerman {
564*0a6a1f1dSLionel Sambuc char *s = copy_comment();
565*0a6a1f1dSLionel Sambuc fputs(s, f);
566*0a6a1f1dSLionel Sambuc free(s);
5674a17663cSThomas Veerman }
5684a17663cSThomas Veerman need_newline = 1;
5694a17663cSThomas Veerman goto loop;
5704a17663cSThomas Veerman
5714a17663cSThomas Veerman case '%':
5724a17663cSThomas Veerman case '\\':
5734a17663cSThomas Veerman if (*cptr == R_CURL)
5744a17663cSThomas Veerman {
5754a17663cSThomas Veerman if (need_newline)
5764a17663cSThomas Veerman putc('\n', f);
5774a17663cSThomas Veerman ++cptr;
578*0a6a1f1dSLionel Sambuc FREE(a.a_line);
5794a17663cSThomas Veerman return;
5804a17663cSThomas Veerman }
5814a17663cSThomas Veerman /* FALLTHRU */
5824a17663cSThomas Veerman
5834a17663cSThomas Veerman default:
5844a17663cSThomas Veerman putc(c, f);
5854a17663cSThomas Veerman need_newline = 1;
5864a17663cSThomas Veerman goto loop;
5874a17663cSThomas Veerman }
5884a17663cSThomas Veerman }
5894a17663cSThomas Veerman
5904a17663cSThomas Veerman static void
puts_both(const char * s)5914a17663cSThomas Veerman puts_both(const char *s)
5924a17663cSThomas Veerman {
5934a17663cSThomas Veerman fputs(s, text_file);
5944a17663cSThomas Veerman if (dflag)
5954a17663cSThomas Veerman fputs(s, union_file);
5964a17663cSThomas Veerman }
5974a17663cSThomas Veerman
5984a17663cSThomas Veerman static void
putc_both(int c)5994a17663cSThomas Veerman putc_both(int c)
6004a17663cSThomas Veerman {
6014a17663cSThomas Veerman putc(c, text_file);
6024a17663cSThomas Veerman if (dflag)
6034a17663cSThomas Veerman putc(c, union_file);
6044a17663cSThomas Veerman }
6054a17663cSThomas Veerman
6064a17663cSThomas Veerman static void
copy_union(void)6074a17663cSThomas Veerman copy_union(void)
6084a17663cSThomas Veerman {
6094a17663cSThomas Veerman int c;
6104a17663cSThomas Veerman int depth;
611*0a6a1f1dSLionel Sambuc struct ainfo a;
612*0a6a1f1dSLionel Sambuc a.a_lineno = lineno;
613*0a6a1f1dSLionel Sambuc a.a_line = dup_line();
614*0a6a1f1dSLionel Sambuc a.a_cptr = a.a_line + (cptr - line - 6);
6154a17663cSThomas Veerman
6164a17663cSThomas Veerman if (unionized)
6174a17663cSThomas Veerman over_unionized(cptr - 6);
6184a17663cSThomas Veerman unionized = 1;
6194a17663cSThomas Veerman
6204a17663cSThomas Veerman if (!lflag)
6214a17663cSThomas Veerman fprintf(text_file, line_format, lineno, input_file_name);
6224a17663cSThomas Veerman
6234a17663cSThomas Veerman puts_both("#ifdef YYSTYPE\n");
6244a17663cSThomas Veerman puts_both("#undef YYSTYPE_IS_DECLARED\n");
6254a17663cSThomas Veerman puts_both("#define YYSTYPE_IS_DECLARED 1\n");
6264a17663cSThomas Veerman puts_both("#endif\n");
6274a17663cSThomas Veerman puts_both("#ifndef YYSTYPE_IS_DECLARED\n");
6284a17663cSThomas Veerman puts_both("#define YYSTYPE_IS_DECLARED 1\n");
6294a17663cSThomas Veerman puts_both("typedef union");
6304a17663cSThomas Veerman
6314a17663cSThomas Veerman depth = 0;
6324a17663cSThomas Veerman loop:
6334a17663cSThomas Veerman c = *cptr++;
6344a17663cSThomas Veerman putc_both(c);
6354a17663cSThomas Veerman switch (c)
6364a17663cSThomas Veerman {
6374a17663cSThomas Veerman case '\n':
6384a17663cSThomas Veerman get_line();
6394a17663cSThomas Veerman if (line == 0)
640*0a6a1f1dSLionel Sambuc unterminated_union(&a);
6414a17663cSThomas Veerman goto loop;
6424a17663cSThomas Veerman
6434a17663cSThomas Veerman case L_CURL:
6444a17663cSThomas Veerman ++depth;
6454a17663cSThomas Veerman goto loop;
6464a17663cSThomas Veerman
6474a17663cSThomas Veerman case R_CURL:
6484a17663cSThomas Veerman if (--depth == 0)
6494a17663cSThomas Veerman {
6504a17663cSThomas Veerman puts_both(" YYSTYPE;\n");
6514a17663cSThomas Veerman puts_both("#endif /* !YYSTYPE_IS_DECLARED */\n");
652*0a6a1f1dSLionel Sambuc FREE(a.a_line);
6534a17663cSThomas Veerman return;
6544a17663cSThomas Veerman }
6554a17663cSThomas Veerman goto loop;
6564a17663cSThomas Veerman
6574a17663cSThomas Veerman case '\'':
6584a17663cSThomas Veerman case '"':
6594a17663cSThomas Veerman {
660*0a6a1f1dSLionel Sambuc char *s = copy_string(c);
661*0a6a1f1dSLionel Sambuc puts_both(s);
662*0a6a1f1dSLionel Sambuc free(s);
663*0a6a1f1dSLionel Sambuc }
6644a17663cSThomas Veerman goto loop;
6654a17663cSThomas Veerman
6664a17663cSThomas Veerman case '/':
6674a17663cSThomas Veerman {
668*0a6a1f1dSLionel Sambuc char *s = copy_comment();
669*0a6a1f1dSLionel Sambuc puts_both(s);
670*0a6a1f1dSLionel Sambuc free(s);
6714a17663cSThomas Veerman }
6724a17663cSThomas Veerman goto loop;
6734a17663cSThomas Veerman
6744a17663cSThomas Veerman default:
6754a17663cSThomas Veerman goto loop;
6764a17663cSThomas Veerman }
6774a17663cSThomas Veerman }
6784a17663cSThomas Veerman
679*0a6a1f1dSLionel Sambuc static char *
after_blanks(char * s)680*0a6a1f1dSLionel Sambuc after_blanks(char *s)
681*0a6a1f1dSLionel Sambuc {
682*0a6a1f1dSLionel Sambuc while (*s != '\0' && isspace(UCH(*s)))
683*0a6a1f1dSLionel Sambuc ++s;
684*0a6a1f1dSLionel Sambuc return s;
685*0a6a1f1dSLionel Sambuc }
686*0a6a1f1dSLionel Sambuc
6874a17663cSThomas Veerman /*
688*0a6a1f1dSLionel Sambuc * Trim leading/trailing blanks, and collapse multiple embedded blanks to a
689*0a6a1f1dSLionel Sambuc * single space. Return index to last character in the buffer.
6904a17663cSThomas Veerman */
691*0a6a1f1dSLionel Sambuc static int
trim_blanks(char * buffer)692*0a6a1f1dSLionel Sambuc trim_blanks(char *buffer)
693*0a6a1f1dSLionel Sambuc {
694*0a6a1f1dSLionel Sambuc if (*buffer != '\0')
695*0a6a1f1dSLionel Sambuc {
696*0a6a1f1dSLionel Sambuc char *d = buffer;
697*0a6a1f1dSLionel Sambuc char *s = after_blanks(d);
698*0a6a1f1dSLionel Sambuc
699*0a6a1f1dSLionel Sambuc while ((*d++ = *s++) != '\0')
700*0a6a1f1dSLionel Sambuc {
701*0a6a1f1dSLionel Sambuc ;
702*0a6a1f1dSLionel Sambuc }
703*0a6a1f1dSLionel Sambuc
704*0a6a1f1dSLionel Sambuc --d;
705*0a6a1f1dSLionel Sambuc while ((--d != buffer) && isspace(UCH(*d)))
706*0a6a1f1dSLionel Sambuc *d = '\0';
707*0a6a1f1dSLionel Sambuc
708*0a6a1f1dSLionel Sambuc for (s = d = buffer; (*d++ = *s++) != '\0';)
709*0a6a1f1dSLionel Sambuc {
710*0a6a1f1dSLionel Sambuc if (isspace(UCH(*s)))
711*0a6a1f1dSLionel Sambuc {
712*0a6a1f1dSLionel Sambuc *s = ' ';
713*0a6a1f1dSLionel Sambuc while (isspace(UCH(*s)))
714*0a6a1f1dSLionel Sambuc {
715*0a6a1f1dSLionel Sambuc *s++ = ' ';
716*0a6a1f1dSLionel Sambuc }
717*0a6a1f1dSLionel Sambuc --s;
718*0a6a1f1dSLionel Sambuc }
719*0a6a1f1dSLionel Sambuc }
720*0a6a1f1dSLionel Sambuc }
721*0a6a1f1dSLionel Sambuc
722*0a6a1f1dSLionel Sambuc return (int)strlen(buffer) - 1;
723*0a6a1f1dSLionel Sambuc }
724*0a6a1f1dSLionel Sambuc
725*0a6a1f1dSLionel Sambuc /*
726*0a6a1f1dSLionel Sambuc * Scan forward in the current line-buffer looking for a right-curly bracket.
727*0a6a1f1dSLionel Sambuc *
728*0a6a1f1dSLionel Sambuc * Parameters begin with a left-curly bracket, and continue until there are no
729*0a6a1f1dSLionel Sambuc * more interesting characters after the last right-curly bracket on the
730*0a6a1f1dSLionel Sambuc * current line. Bison documents parameters as separated like this:
731*0a6a1f1dSLionel Sambuc * {type param1} {type2 param2}
732*0a6a1f1dSLionel Sambuc * but also accepts commas (although some versions of bison mishandle this)
733*0a6a1f1dSLionel Sambuc * {type param1, type2 param2}
734*0a6a1f1dSLionel Sambuc */
735*0a6a1f1dSLionel Sambuc static int
more_curly(void)736*0a6a1f1dSLionel Sambuc more_curly(void)
737*0a6a1f1dSLionel Sambuc {
738*0a6a1f1dSLionel Sambuc char *save = cptr;
739*0a6a1f1dSLionel Sambuc int result = 0;
740*0a6a1f1dSLionel Sambuc int finish = 0;
741*0a6a1f1dSLionel Sambuc do
742*0a6a1f1dSLionel Sambuc {
743*0a6a1f1dSLionel Sambuc switch (next_inline())
744*0a6a1f1dSLionel Sambuc {
745*0a6a1f1dSLionel Sambuc case 0:
746*0a6a1f1dSLionel Sambuc case '\n':
747*0a6a1f1dSLionel Sambuc finish = 1;
748*0a6a1f1dSLionel Sambuc break;
749*0a6a1f1dSLionel Sambuc case R_CURL:
750*0a6a1f1dSLionel Sambuc finish = 1;
751*0a6a1f1dSLionel Sambuc result = 1;
752*0a6a1f1dSLionel Sambuc break;
753*0a6a1f1dSLionel Sambuc }
754*0a6a1f1dSLionel Sambuc ++cptr;
755*0a6a1f1dSLionel Sambuc }
756*0a6a1f1dSLionel Sambuc while (!finish);
757*0a6a1f1dSLionel Sambuc cptr = save;
758*0a6a1f1dSLionel Sambuc return result;
759*0a6a1f1dSLionel Sambuc }
760*0a6a1f1dSLionel Sambuc
7614a17663cSThomas Veerman static void
save_param(int k,char * buffer,int name,int type2)762*0a6a1f1dSLionel Sambuc save_param(int k, char *buffer, int name, int type2)
7634a17663cSThomas Veerman {
7644a17663cSThomas Veerman param *head, *p;
7654a17663cSThomas Veerman
76684d9c625SLionel Sambuc p = TMALLOC(param, 1);
7674a17663cSThomas Veerman NO_SPACE(p);
7684a17663cSThomas Veerman
769*0a6a1f1dSLionel Sambuc p->type2 = strdup(buffer + type2);
7704a17663cSThomas Veerman NO_SPACE(p->type2);
771*0a6a1f1dSLionel Sambuc buffer[type2] = '\0';
772*0a6a1f1dSLionel Sambuc (void)trim_blanks(p->type2);
7734a17663cSThomas Veerman
774*0a6a1f1dSLionel Sambuc p->name = strdup(buffer + name);
7754a17663cSThomas Veerman NO_SPACE(p->name);
776*0a6a1f1dSLionel Sambuc buffer[name] = '\0';
777*0a6a1f1dSLionel Sambuc (void)trim_blanks(p->name);
7784a17663cSThomas Veerman
779*0a6a1f1dSLionel Sambuc p->type = strdup(buffer);
780*0a6a1f1dSLionel Sambuc NO_SPACE(p->type);
781*0a6a1f1dSLionel Sambuc (void)trim_blanks(p->type);
7824a17663cSThomas Veerman
7834a17663cSThomas Veerman if (k == LEX_PARAM)
7844a17663cSThomas Veerman head = lex_param;
7854a17663cSThomas Veerman else
7864a17663cSThomas Veerman head = parse_param;
7874a17663cSThomas Veerman
7884a17663cSThomas Veerman if (head != NULL)
7894a17663cSThomas Veerman {
7904a17663cSThomas Veerman while (head->next)
7914a17663cSThomas Veerman head = head->next;
7924a17663cSThomas Veerman head->next = p;
7934a17663cSThomas Veerman }
7944a17663cSThomas Veerman else
7954a17663cSThomas Veerman {
7964a17663cSThomas Veerman if (k == LEX_PARAM)
7974a17663cSThomas Veerman lex_param = p;
7984a17663cSThomas Veerman else
7994a17663cSThomas Veerman parse_param = p;
8004a17663cSThomas Veerman }
8014a17663cSThomas Veerman p->next = NULL;
802*0a6a1f1dSLionel Sambuc }
803*0a6a1f1dSLionel Sambuc
804*0a6a1f1dSLionel Sambuc /*
805*0a6a1f1dSLionel Sambuc * Keep a linked list of parameters. This may be multi-line, if the trailing
806*0a6a1f1dSLionel Sambuc * right-curly bracket is absent.
807*0a6a1f1dSLionel Sambuc */
808*0a6a1f1dSLionel Sambuc static void
copy_param(int k)809*0a6a1f1dSLionel Sambuc copy_param(int k)
810*0a6a1f1dSLionel Sambuc {
811*0a6a1f1dSLionel Sambuc int c;
812*0a6a1f1dSLionel Sambuc int name, type2;
813*0a6a1f1dSLionel Sambuc int curly = 0;
814*0a6a1f1dSLionel Sambuc char *buf = 0;
815*0a6a1f1dSLionel Sambuc int i = -1;
816*0a6a1f1dSLionel Sambuc size_t buf_size = 0;
817*0a6a1f1dSLionel Sambuc int st_lineno = lineno;
818*0a6a1f1dSLionel Sambuc char *comma;
819*0a6a1f1dSLionel Sambuc
820*0a6a1f1dSLionel Sambuc do
821*0a6a1f1dSLionel Sambuc {
822*0a6a1f1dSLionel Sambuc int state = curly;
823*0a6a1f1dSLionel Sambuc c = next_inline();
824*0a6a1f1dSLionel Sambuc switch (c)
825*0a6a1f1dSLionel Sambuc {
826*0a6a1f1dSLionel Sambuc case EOF:
827*0a6a1f1dSLionel Sambuc unexpected_EOF();
828*0a6a1f1dSLionel Sambuc break;
829*0a6a1f1dSLionel Sambuc case L_CURL:
830*0a6a1f1dSLionel Sambuc if (curly == 1)
831*0a6a1f1dSLionel Sambuc {
832*0a6a1f1dSLionel Sambuc goto oops;
833*0a6a1f1dSLionel Sambuc }
834*0a6a1f1dSLionel Sambuc curly = 1;
835*0a6a1f1dSLionel Sambuc st_lineno = lineno;
836*0a6a1f1dSLionel Sambuc break;
837*0a6a1f1dSLionel Sambuc case R_CURL:
838*0a6a1f1dSLionel Sambuc if (curly != 1)
839*0a6a1f1dSLionel Sambuc {
840*0a6a1f1dSLionel Sambuc goto oops;
841*0a6a1f1dSLionel Sambuc }
842*0a6a1f1dSLionel Sambuc curly = 2;
843*0a6a1f1dSLionel Sambuc break;
844*0a6a1f1dSLionel Sambuc case '\n':
845*0a6a1f1dSLionel Sambuc if (curly == 0)
846*0a6a1f1dSLionel Sambuc {
847*0a6a1f1dSLionel Sambuc goto oops;
848*0a6a1f1dSLionel Sambuc }
849*0a6a1f1dSLionel Sambuc break;
850*0a6a1f1dSLionel Sambuc case '%':
851*0a6a1f1dSLionel Sambuc if ((curly == 1) && (cptr == line))
852*0a6a1f1dSLionel Sambuc {
853*0a6a1f1dSLionel Sambuc lineno = st_lineno;
854*0a6a1f1dSLionel Sambuc missing_brace();
855*0a6a1f1dSLionel Sambuc }
856*0a6a1f1dSLionel Sambuc /* FALLTHRU */
857*0a6a1f1dSLionel Sambuc case '"':
858*0a6a1f1dSLionel Sambuc case '\'':
859*0a6a1f1dSLionel Sambuc goto oops;
860*0a6a1f1dSLionel Sambuc default:
861*0a6a1f1dSLionel Sambuc if (curly == 0 && !isspace(UCH(c)))
862*0a6a1f1dSLionel Sambuc {
863*0a6a1f1dSLionel Sambuc goto oops;
864*0a6a1f1dSLionel Sambuc }
865*0a6a1f1dSLionel Sambuc break;
866*0a6a1f1dSLionel Sambuc }
867*0a6a1f1dSLionel Sambuc if (buf == 0)
868*0a6a1f1dSLionel Sambuc {
869*0a6a1f1dSLionel Sambuc buf_size = (size_t) linesize;
870*0a6a1f1dSLionel Sambuc buf = TMALLOC(char, buf_size);
871*0a6a1f1dSLionel Sambuc }
872*0a6a1f1dSLionel Sambuc else if (c == '\n')
873*0a6a1f1dSLionel Sambuc {
874*0a6a1f1dSLionel Sambuc get_line();
875*0a6a1f1dSLionel Sambuc if (line == 0)
876*0a6a1f1dSLionel Sambuc unexpected_EOF();
877*0a6a1f1dSLionel Sambuc --cptr;
878*0a6a1f1dSLionel Sambuc buf_size += (size_t) linesize;
879*0a6a1f1dSLionel Sambuc buf = TREALLOC(char, buf, buf_size);
880*0a6a1f1dSLionel Sambuc }
881*0a6a1f1dSLionel Sambuc NO_SPACE(buf);
882*0a6a1f1dSLionel Sambuc if (curly)
883*0a6a1f1dSLionel Sambuc {
884*0a6a1f1dSLionel Sambuc if ((state == 2) && (c == L_CURL))
885*0a6a1f1dSLionel Sambuc {
886*0a6a1f1dSLionel Sambuc buf[++i] = ',';
887*0a6a1f1dSLionel Sambuc }
888*0a6a1f1dSLionel Sambuc else if ((state == 2) && isspace(UCH(c)))
889*0a6a1f1dSLionel Sambuc {
890*0a6a1f1dSLionel Sambuc ;
891*0a6a1f1dSLionel Sambuc }
892*0a6a1f1dSLionel Sambuc else if ((c != L_CURL) && (c != R_CURL))
893*0a6a1f1dSLionel Sambuc {
894*0a6a1f1dSLionel Sambuc buf[++i] = (char)c;
895*0a6a1f1dSLionel Sambuc }
896*0a6a1f1dSLionel Sambuc }
897*0a6a1f1dSLionel Sambuc cptr++;
898*0a6a1f1dSLionel Sambuc }
899*0a6a1f1dSLionel Sambuc while (curly < 2 || more_curly());
900*0a6a1f1dSLionel Sambuc
901*0a6a1f1dSLionel Sambuc if (i == 0)
902*0a6a1f1dSLionel Sambuc {
903*0a6a1f1dSLionel Sambuc if (curly == 1)
904*0a6a1f1dSLionel Sambuc {
905*0a6a1f1dSLionel Sambuc lineno = st_lineno;
906*0a6a1f1dSLionel Sambuc missing_brace();
907*0a6a1f1dSLionel Sambuc }
908*0a6a1f1dSLionel Sambuc goto oops;
909*0a6a1f1dSLionel Sambuc }
910*0a6a1f1dSLionel Sambuc
911*0a6a1f1dSLionel Sambuc buf[++i] = '\0';
912*0a6a1f1dSLionel Sambuc i = trim_blanks(buf);
913*0a6a1f1dSLionel Sambuc
914*0a6a1f1dSLionel Sambuc comma = buf - 1;
915*0a6a1f1dSLionel Sambuc do
916*0a6a1f1dSLionel Sambuc {
917*0a6a1f1dSLionel Sambuc char *parms = (comma + 1);
918*0a6a1f1dSLionel Sambuc comma = strchr(parms, ',');
919*0a6a1f1dSLionel Sambuc if (comma != 0)
920*0a6a1f1dSLionel Sambuc *comma = '\0';
921*0a6a1f1dSLionel Sambuc
922*0a6a1f1dSLionel Sambuc (void)trim_blanks(parms);
923*0a6a1f1dSLionel Sambuc i = (int)strlen(parms) - 1;
924*0a6a1f1dSLionel Sambuc if (i < 0)
925*0a6a1f1dSLionel Sambuc {
926*0a6a1f1dSLionel Sambuc goto oops;
927*0a6a1f1dSLionel Sambuc }
928*0a6a1f1dSLionel Sambuc
929*0a6a1f1dSLionel Sambuc if (parms[i] == ']')
930*0a6a1f1dSLionel Sambuc {
931*0a6a1f1dSLionel Sambuc int level = 1;
932*0a6a1f1dSLionel Sambuc while (i >= 0 && level > 0 && parms[i] != '[')
933*0a6a1f1dSLionel Sambuc {
934*0a6a1f1dSLionel Sambuc if (parms[i] == ']')
935*0a6a1f1dSLionel Sambuc ++level;
936*0a6a1f1dSLionel Sambuc else if (parms[i] == '[')
937*0a6a1f1dSLionel Sambuc --level;
938*0a6a1f1dSLionel Sambuc i--;
939*0a6a1f1dSLionel Sambuc }
940*0a6a1f1dSLionel Sambuc if (i <= 0)
941*0a6a1f1dSLionel Sambuc unexpected_EOF();
942*0a6a1f1dSLionel Sambuc type2 = i--;
943*0a6a1f1dSLionel Sambuc }
944*0a6a1f1dSLionel Sambuc else
945*0a6a1f1dSLionel Sambuc {
946*0a6a1f1dSLionel Sambuc type2 = i + 1;
947*0a6a1f1dSLionel Sambuc }
948*0a6a1f1dSLionel Sambuc
949*0a6a1f1dSLionel Sambuc while (i > 0 && (isalnum(UCH(parms[i])) || UCH(parms[i]) == '_'))
950*0a6a1f1dSLionel Sambuc i--;
951*0a6a1f1dSLionel Sambuc
952*0a6a1f1dSLionel Sambuc if (!isspace(UCH(parms[i])) && parms[i] != '*')
953*0a6a1f1dSLionel Sambuc goto oops;
954*0a6a1f1dSLionel Sambuc
955*0a6a1f1dSLionel Sambuc name = i + 1;
956*0a6a1f1dSLionel Sambuc
957*0a6a1f1dSLionel Sambuc save_param(k, parms, name, type2);
958*0a6a1f1dSLionel Sambuc }
959*0a6a1f1dSLionel Sambuc while (comma != 0);
960*0a6a1f1dSLionel Sambuc FREE(buf);
9614a17663cSThomas Veerman return;
9624a17663cSThomas Veerman
963*0a6a1f1dSLionel Sambuc oops:
964*0a6a1f1dSLionel Sambuc FREE(buf);
9654a17663cSThomas Veerman syntax_error(lineno, line, cptr);
9664a17663cSThomas Veerman }
9674a17663cSThomas Veerman
9684a17663cSThomas Veerman static int
hexval(int c)9694a17663cSThomas Veerman hexval(int c)
9704a17663cSThomas Veerman {
9714a17663cSThomas Veerman if (c >= '0' && c <= '9')
9724a17663cSThomas Veerman return (c - '0');
9734a17663cSThomas Veerman if (c >= 'A' && c <= 'F')
9744a17663cSThomas Veerman return (c - 'A' + 10);
9754a17663cSThomas Veerman if (c >= 'a' && c <= 'f')
9764a17663cSThomas Veerman return (c - 'a' + 10);
9774a17663cSThomas Veerman return (-1);
9784a17663cSThomas Veerman }
9794a17663cSThomas Veerman
9804a17663cSThomas Veerman static bucket *
get_literal(void)9814a17663cSThomas Veerman get_literal(void)
9824a17663cSThomas Veerman {
9834a17663cSThomas Veerman int c, quote;
9844a17663cSThomas Veerman int i;
9854a17663cSThomas Veerman int n;
9864a17663cSThomas Veerman char *s;
9874a17663cSThomas Veerman bucket *bp;
988*0a6a1f1dSLionel Sambuc struct ainfo a;
989*0a6a1f1dSLionel Sambuc a.a_lineno = lineno;
990*0a6a1f1dSLionel Sambuc a.a_line = dup_line();
991*0a6a1f1dSLionel Sambuc a.a_cptr = a.a_line + (cptr - line);
9924a17663cSThomas Veerman
9934a17663cSThomas Veerman quote = *cptr++;
9944a17663cSThomas Veerman cinc = 0;
9954a17663cSThomas Veerman for (;;)
9964a17663cSThomas Veerman {
9974a17663cSThomas Veerman c = *cptr++;
9984a17663cSThomas Veerman if (c == quote)
9994a17663cSThomas Veerman break;
10004a17663cSThomas Veerman if (c == '\n')
1001*0a6a1f1dSLionel Sambuc unterminated_string(&a);
10024a17663cSThomas Veerman if (c == '\\')
10034a17663cSThomas Veerman {
10044a17663cSThomas Veerman char *c_cptr = cptr - 1;
10054a17663cSThomas Veerman
10064a17663cSThomas Veerman c = *cptr++;
10074a17663cSThomas Veerman switch (c)
10084a17663cSThomas Veerman {
10094a17663cSThomas Veerman case '\n':
10104a17663cSThomas Veerman get_line();
10114a17663cSThomas Veerman if (line == 0)
1012*0a6a1f1dSLionel Sambuc unterminated_string(&a);
10134a17663cSThomas Veerman continue;
10144a17663cSThomas Veerman
10154a17663cSThomas Veerman case '0':
10164a17663cSThomas Veerman case '1':
10174a17663cSThomas Veerman case '2':
10184a17663cSThomas Veerman case '3':
10194a17663cSThomas Veerman case '4':
10204a17663cSThomas Veerman case '5':
10214a17663cSThomas Veerman case '6':
10224a17663cSThomas Veerman case '7':
10234a17663cSThomas Veerman n = c - '0';
10244a17663cSThomas Veerman c = *cptr;
10254a17663cSThomas Veerman if (IS_OCTAL(c))
10264a17663cSThomas Veerman {
10274a17663cSThomas Veerman n = (n << 3) + (c - '0');
10284a17663cSThomas Veerman c = *++cptr;
10294a17663cSThomas Veerman if (IS_OCTAL(c))
10304a17663cSThomas Veerman {
10314a17663cSThomas Veerman n = (n << 3) + (c - '0');
10324a17663cSThomas Veerman ++cptr;
10334a17663cSThomas Veerman }
10344a17663cSThomas Veerman }
10354a17663cSThomas Veerman if (n > MAXCHAR)
10364a17663cSThomas Veerman illegal_character(c_cptr);
10374a17663cSThomas Veerman c = n;
10384a17663cSThomas Veerman break;
10394a17663cSThomas Veerman
10404a17663cSThomas Veerman case 'x':
10414a17663cSThomas Veerman c = *cptr++;
10424a17663cSThomas Veerman n = hexval(c);
10434a17663cSThomas Veerman if (n < 0 || n >= 16)
10444a17663cSThomas Veerman illegal_character(c_cptr);
10454a17663cSThomas Veerman for (;;)
10464a17663cSThomas Veerman {
10474a17663cSThomas Veerman c = *cptr;
10484a17663cSThomas Veerman i = hexval(c);
10494a17663cSThomas Veerman if (i < 0 || i >= 16)
10504a17663cSThomas Veerman break;
10514a17663cSThomas Veerman ++cptr;
10524a17663cSThomas Veerman n = (n << 4) + i;
10534a17663cSThomas Veerman if (n > MAXCHAR)
10544a17663cSThomas Veerman illegal_character(c_cptr);
10554a17663cSThomas Veerman }
10564a17663cSThomas Veerman c = n;
10574a17663cSThomas Veerman break;
10584a17663cSThomas Veerman
10594a17663cSThomas Veerman case 'a':
10604a17663cSThomas Veerman c = 7;
10614a17663cSThomas Veerman break;
10624a17663cSThomas Veerman case 'b':
10634a17663cSThomas Veerman c = '\b';
10644a17663cSThomas Veerman break;
10654a17663cSThomas Veerman case 'f':
10664a17663cSThomas Veerman c = '\f';
10674a17663cSThomas Veerman break;
10684a17663cSThomas Veerman case 'n':
10694a17663cSThomas Veerman c = '\n';
10704a17663cSThomas Veerman break;
10714a17663cSThomas Veerman case 'r':
10724a17663cSThomas Veerman c = '\r';
10734a17663cSThomas Veerman break;
10744a17663cSThomas Veerman case 't':
10754a17663cSThomas Veerman c = '\t';
10764a17663cSThomas Veerman break;
10774a17663cSThomas Veerman case 'v':
10784a17663cSThomas Veerman c = '\v';
10794a17663cSThomas Veerman break;
10804a17663cSThomas Veerman }
10814a17663cSThomas Veerman }
10824a17663cSThomas Veerman cachec(c);
10834a17663cSThomas Veerman }
1084*0a6a1f1dSLionel Sambuc FREE(a.a_line);
10854a17663cSThomas Veerman
10864a17663cSThomas Veerman n = cinc;
108784d9c625SLionel Sambuc s = TMALLOC(char, n);
10884a17663cSThomas Veerman NO_SPACE(s);
10894a17663cSThomas Veerman
10904a17663cSThomas Veerman for (i = 0; i < n; ++i)
10914a17663cSThomas Veerman s[i] = cache[i];
10924a17663cSThomas Veerman
10934a17663cSThomas Veerman cinc = 0;
10944a17663cSThomas Veerman if (n == 1)
10954a17663cSThomas Veerman cachec('\'');
10964a17663cSThomas Veerman else
10974a17663cSThomas Veerman cachec('"');
10984a17663cSThomas Veerman
10994a17663cSThomas Veerman for (i = 0; i < n; ++i)
11004a17663cSThomas Veerman {
11014a17663cSThomas Veerman c = UCH(s[i]);
11024a17663cSThomas Veerman if (c == '\\' || c == cache[0])
11034a17663cSThomas Veerman {
11044a17663cSThomas Veerman cachec('\\');
11054a17663cSThomas Veerman cachec(c);
11064a17663cSThomas Veerman }
11074a17663cSThomas Veerman else if (isprint(c))
11084a17663cSThomas Veerman cachec(c);
11094a17663cSThomas Veerman else
11104a17663cSThomas Veerman {
11114a17663cSThomas Veerman cachec('\\');
11124a17663cSThomas Veerman switch (c)
11134a17663cSThomas Veerman {
11144a17663cSThomas Veerman case 7:
11154a17663cSThomas Veerman cachec('a');
11164a17663cSThomas Veerman break;
11174a17663cSThomas Veerman case '\b':
11184a17663cSThomas Veerman cachec('b');
11194a17663cSThomas Veerman break;
11204a17663cSThomas Veerman case '\f':
11214a17663cSThomas Veerman cachec('f');
11224a17663cSThomas Veerman break;
11234a17663cSThomas Veerman case '\n':
11244a17663cSThomas Veerman cachec('n');
11254a17663cSThomas Veerman break;
11264a17663cSThomas Veerman case '\r':
11274a17663cSThomas Veerman cachec('r');
11284a17663cSThomas Veerman break;
11294a17663cSThomas Veerman case '\t':
11304a17663cSThomas Veerman cachec('t');
11314a17663cSThomas Veerman break;
11324a17663cSThomas Veerman case '\v':
11334a17663cSThomas Veerman cachec('v');
11344a17663cSThomas Veerman break;
11354a17663cSThomas Veerman default:
11364a17663cSThomas Veerman cachec(((c >> 6) & 7) + '0');
11374a17663cSThomas Veerman cachec(((c >> 3) & 7) + '0');
11384a17663cSThomas Veerman cachec((c & 7) + '0');
11394a17663cSThomas Veerman break;
11404a17663cSThomas Veerman }
11414a17663cSThomas Veerman }
11424a17663cSThomas Veerman }
11434a17663cSThomas Veerman
11444a17663cSThomas Veerman if (n == 1)
11454a17663cSThomas Veerman cachec('\'');
11464a17663cSThomas Veerman else
11474a17663cSThomas Veerman cachec('"');
11484a17663cSThomas Veerman
11494a17663cSThomas Veerman cachec(NUL);
11504a17663cSThomas Veerman bp = lookup(cache);
11514a17663cSThomas Veerman bp->class = TERM;
11524a17663cSThomas Veerman if (n == 1 && bp->value == UNDEFINED)
11534a17663cSThomas Veerman bp->value = UCH(*s);
11544a17663cSThomas Veerman FREE(s);
11554a17663cSThomas Veerman
11564a17663cSThomas Veerman return (bp);
11574a17663cSThomas Veerman }
11584a17663cSThomas Veerman
11594a17663cSThomas Veerman static int
is_reserved(char * name)11604a17663cSThomas Veerman is_reserved(char *name)
11614a17663cSThomas Veerman {
11624a17663cSThomas Veerman char *s;
11634a17663cSThomas Veerman
11644a17663cSThomas Veerman if (strcmp(name, ".") == 0 ||
11654a17663cSThomas Veerman strcmp(name, "$accept") == 0 ||
11664a17663cSThomas Veerman strcmp(name, "$end") == 0)
11674a17663cSThomas Veerman return (1);
11684a17663cSThomas Veerman
11694a17663cSThomas Veerman if (name[0] == '$' && name[1] == '$' && isdigit(UCH(name[2])))
11704a17663cSThomas Veerman {
11714a17663cSThomas Veerman s = name + 3;
11724a17663cSThomas Veerman while (isdigit(UCH(*s)))
11734a17663cSThomas Veerman ++s;
11744a17663cSThomas Veerman if (*s == NUL)
11754a17663cSThomas Veerman return (1);
11764a17663cSThomas Veerman }
11774a17663cSThomas Veerman
11784a17663cSThomas Veerman return (0);
11794a17663cSThomas Veerman }
11804a17663cSThomas Veerman
11814a17663cSThomas Veerman static bucket *
get_name(void)11824a17663cSThomas Veerman get_name(void)
11834a17663cSThomas Veerman {
11844a17663cSThomas Veerman int c;
11854a17663cSThomas Veerman
11864a17663cSThomas Veerman cinc = 0;
11874a17663cSThomas Veerman for (c = *cptr; IS_IDENT(c); c = *++cptr)
11884a17663cSThomas Veerman cachec(c);
11894a17663cSThomas Veerman cachec(NUL);
11904a17663cSThomas Veerman
11914a17663cSThomas Veerman if (is_reserved(cache))
11924a17663cSThomas Veerman used_reserved(cache);
11934a17663cSThomas Veerman
11944a17663cSThomas Veerman return (lookup(cache));
11954a17663cSThomas Veerman }
11964a17663cSThomas Veerman
11974a17663cSThomas Veerman static Value_t
get_number(void)11984a17663cSThomas Veerman get_number(void)
11994a17663cSThomas Veerman {
12004a17663cSThomas Veerman int c;
12014a17663cSThomas Veerman Value_t n;
12024a17663cSThomas Veerman
12034a17663cSThomas Veerman n = 0;
12044a17663cSThomas Veerman for (c = *cptr; isdigit(c); c = *++cptr)
12054a17663cSThomas Veerman n = (Value_t) (10 * n + (c - '0'));
12064a17663cSThomas Veerman
12074a17663cSThomas Veerman return (n);
12084a17663cSThomas Veerman }
12094a17663cSThomas Veerman
12104a17663cSThomas Veerman static char *
cache_tag(char * tag,size_t len)1211*0a6a1f1dSLionel Sambuc cache_tag(char *tag, size_t len)
1212*0a6a1f1dSLionel Sambuc {
1213*0a6a1f1dSLionel Sambuc int i;
1214*0a6a1f1dSLionel Sambuc char *s;
1215*0a6a1f1dSLionel Sambuc
1216*0a6a1f1dSLionel Sambuc for (i = 0; i < ntags; ++i)
1217*0a6a1f1dSLionel Sambuc {
1218*0a6a1f1dSLionel Sambuc if (strncmp(tag, tag_table[i], len) == 0 &&
1219*0a6a1f1dSLionel Sambuc tag_table[i][len] == NUL)
1220*0a6a1f1dSLionel Sambuc return (tag_table[i]);
1221*0a6a1f1dSLionel Sambuc }
1222*0a6a1f1dSLionel Sambuc
1223*0a6a1f1dSLionel Sambuc if (ntags >= tagmax)
1224*0a6a1f1dSLionel Sambuc {
1225*0a6a1f1dSLionel Sambuc tagmax += 16;
1226*0a6a1f1dSLionel Sambuc tag_table =
1227*0a6a1f1dSLionel Sambuc (tag_table
1228*0a6a1f1dSLionel Sambuc ? TREALLOC(char *, tag_table, tagmax)
1229*0a6a1f1dSLionel Sambuc : TMALLOC(char *, tagmax));
1230*0a6a1f1dSLionel Sambuc NO_SPACE(tag_table);
1231*0a6a1f1dSLionel Sambuc }
1232*0a6a1f1dSLionel Sambuc
1233*0a6a1f1dSLionel Sambuc s = TMALLOC(char, len + 1);
1234*0a6a1f1dSLionel Sambuc NO_SPACE(s);
1235*0a6a1f1dSLionel Sambuc
1236*0a6a1f1dSLionel Sambuc strncpy(s, tag, len);
1237*0a6a1f1dSLionel Sambuc s[len] = 0;
1238*0a6a1f1dSLionel Sambuc tag_table[ntags++] = s;
1239*0a6a1f1dSLionel Sambuc return s;
1240*0a6a1f1dSLionel Sambuc }
1241*0a6a1f1dSLionel Sambuc
1242*0a6a1f1dSLionel Sambuc static char *
get_tag(void)12434a17663cSThomas Veerman get_tag(void)
12444a17663cSThomas Veerman {
12454a17663cSThomas Veerman int c;
12464a17663cSThomas Veerman int t_lineno = lineno;
12474a17663cSThomas Veerman char *t_line = dup_line();
12484a17663cSThomas Veerman char *t_cptr = t_line + (cptr - line);
12494a17663cSThomas Veerman
12504a17663cSThomas Veerman ++cptr;
12514a17663cSThomas Veerman c = nextc();
12524a17663cSThomas Veerman if (c == EOF)
12534a17663cSThomas Veerman unexpected_EOF();
12544a17663cSThomas Veerman if (!isalpha(c) && c != '_' && c != '$')
12554a17663cSThomas Veerman illegal_tag(t_lineno, t_line, t_cptr);
12564a17663cSThomas Veerman
12574a17663cSThomas Veerman cinc = 0;
12584a17663cSThomas Veerman do
12594a17663cSThomas Veerman {
12604a17663cSThomas Veerman cachec(c);
12614a17663cSThomas Veerman c = *++cptr;
12624a17663cSThomas Veerman }
12634a17663cSThomas Veerman while (IS_IDENT(c));
12644a17663cSThomas Veerman cachec(NUL);
12654a17663cSThomas Veerman
12664a17663cSThomas Veerman c = nextc();
12674a17663cSThomas Veerman if (c == EOF)
12684a17663cSThomas Veerman unexpected_EOF();
12694a17663cSThomas Veerman if (c != '>')
12704a17663cSThomas Veerman illegal_tag(t_lineno, t_line, t_cptr);
12714a17663cSThomas Veerman ++cptr;
12724a17663cSThomas Veerman
12734a17663cSThomas Veerman FREE(t_line);
1274*0a6a1f1dSLionel Sambuc havetags = 1;
1275*0a6a1f1dSLionel Sambuc return cache_tag(cache, (size_t) cinc);
12764a17663cSThomas Veerman }
12774a17663cSThomas Veerman
1278*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
1279*0a6a1f1dSLionel Sambuc static char *
scan_id(void)1280*0a6a1f1dSLionel Sambuc scan_id(void)
12814a17663cSThomas Veerman {
1282*0a6a1f1dSLionel Sambuc char *b = cptr;
12834a17663cSThomas Veerman
1284*0a6a1f1dSLionel Sambuc while (isalnum((unsigned char)*cptr) || *cptr == '_' || *cptr == '$')
1285*0a6a1f1dSLionel Sambuc cptr++;
1286*0a6a1f1dSLionel Sambuc return cache_tag(b, (size_t) (cptr - b));
12874a17663cSThomas Veerman }
1288*0a6a1f1dSLionel Sambuc #endif
12894a17663cSThomas Veerman
12904a17663cSThomas Veerman static void
declare_tokens(int assoc)12914a17663cSThomas Veerman declare_tokens(int assoc)
12924a17663cSThomas Veerman {
12934a17663cSThomas Veerman int c;
12944a17663cSThomas Veerman bucket *bp;
12954a17663cSThomas Veerman Value_t value;
12964a17663cSThomas Veerman char *tag = 0;
12974a17663cSThomas Veerman
12984a17663cSThomas Veerman if (assoc != TOKEN)
12994a17663cSThomas Veerman ++prec;
13004a17663cSThomas Veerman
13014a17663cSThomas Veerman c = nextc();
13024a17663cSThomas Veerman if (c == EOF)
13034a17663cSThomas Veerman unexpected_EOF();
13044a17663cSThomas Veerman if (c == '<')
13054a17663cSThomas Veerman {
13064a17663cSThomas Veerman tag = get_tag();
13074a17663cSThomas Veerman c = nextc();
13084a17663cSThomas Veerman if (c == EOF)
13094a17663cSThomas Veerman unexpected_EOF();
13104a17663cSThomas Veerman }
13114a17663cSThomas Veerman
13124a17663cSThomas Veerman for (;;)
13134a17663cSThomas Veerman {
13144a17663cSThomas Veerman if (isalpha(c) || c == '_' || c == '.' || c == '$')
13154a17663cSThomas Veerman bp = get_name();
13164a17663cSThomas Veerman else if (c == '\'' || c == '"')
13174a17663cSThomas Veerman bp = get_literal();
13184a17663cSThomas Veerman else
13194a17663cSThomas Veerman return;
13204a17663cSThomas Veerman
13214a17663cSThomas Veerman if (bp == goal)
13224a17663cSThomas Veerman tokenized_start(bp->name);
13234a17663cSThomas Veerman bp->class = TERM;
13244a17663cSThomas Veerman
13254a17663cSThomas Veerman if (tag)
13264a17663cSThomas Veerman {
13274a17663cSThomas Veerman if (bp->tag && tag != bp->tag)
13284a17663cSThomas Veerman retyped_warning(bp->name);
13294a17663cSThomas Veerman bp->tag = tag;
13304a17663cSThomas Veerman }
13314a17663cSThomas Veerman
13324a17663cSThomas Veerman if (assoc != TOKEN)
13334a17663cSThomas Veerman {
13344a17663cSThomas Veerman if (bp->prec && prec != bp->prec)
13354a17663cSThomas Veerman reprec_warning(bp->name);
13364a17663cSThomas Veerman bp->assoc = (Assoc_t) assoc;
13374a17663cSThomas Veerman bp->prec = prec;
13384a17663cSThomas Veerman }
13394a17663cSThomas Veerman
13404a17663cSThomas Veerman c = nextc();
13414a17663cSThomas Veerman if (c == EOF)
13424a17663cSThomas Veerman unexpected_EOF();
13434a17663cSThomas Veerman
13444a17663cSThomas Veerman if (isdigit(c))
13454a17663cSThomas Veerman {
13464a17663cSThomas Veerman value = get_number();
13474a17663cSThomas Veerman if (bp->value != UNDEFINED && value != bp->value)
13484a17663cSThomas Veerman revalued_warning(bp->name);
13494a17663cSThomas Veerman bp->value = value;
13504a17663cSThomas Veerman c = nextc();
13514a17663cSThomas Veerman if (c == EOF)
13524a17663cSThomas Veerman unexpected_EOF();
13534a17663cSThomas Veerman }
13544a17663cSThomas Veerman }
13554a17663cSThomas Veerman }
13564a17663cSThomas Veerman
13574a17663cSThomas Veerman /*
13584a17663cSThomas Veerman * %expect requires special handling
13594a17663cSThomas Veerman * as it really isn't part of the yacc
13604a17663cSThomas Veerman * grammar only a flag for yacc proper.
13614a17663cSThomas Veerman */
13624a17663cSThomas Veerman static void
declare_expect(int assoc)13634a17663cSThomas Veerman declare_expect(int assoc)
13644a17663cSThomas Veerman {
13654a17663cSThomas Veerman int c;
13664a17663cSThomas Veerman
13674a17663cSThomas Veerman if (assoc != EXPECT && assoc != EXPECT_RR)
13684a17663cSThomas Veerman ++prec;
13694a17663cSThomas Veerman
13704a17663cSThomas Veerman /*
13714a17663cSThomas Veerman * Stay away from nextc - doesn't
13724a17663cSThomas Veerman * detect EOL and will read to EOF.
13734a17663cSThomas Veerman */
13744a17663cSThomas Veerman c = *++cptr;
13754a17663cSThomas Veerman if (c == EOF)
13764a17663cSThomas Veerman unexpected_EOF();
13774a17663cSThomas Veerman
13784a17663cSThomas Veerman for (;;)
13794a17663cSThomas Veerman {
13804a17663cSThomas Veerman if (isdigit(c))
13814a17663cSThomas Veerman {
13824a17663cSThomas Veerman if (assoc == EXPECT)
13834a17663cSThomas Veerman SRexpect = get_number();
13844a17663cSThomas Veerman else
13854a17663cSThomas Veerman RRexpect = get_number();
13864a17663cSThomas Veerman break;
13874a17663cSThomas Veerman }
13884a17663cSThomas Veerman /*
13894a17663cSThomas Veerman * Looking for number before EOL.
13904a17663cSThomas Veerman * Spaces, tabs, and numbers are ok,
13914a17663cSThomas Veerman * words, punc., etc. are syntax errors.
13924a17663cSThomas Veerman */
13934a17663cSThomas Veerman else if (c == '\n' || isalpha(c) || !isspace(c))
13944a17663cSThomas Veerman {
13954a17663cSThomas Veerman syntax_error(lineno, line, cptr);
13964a17663cSThomas Veerman }
13974a17663cSThomas Veerman else
13984a17663cSThomas Veerman {
13994a17663cSThomas Veerman c = *++cptr;
14004a17663cSThomas Veerman if (c == EOF)
14014a17663cSThomas Veerman unexpected_EOF();
14024a17663cSThomas Veerman }
14034a17663cSThomas Veerman }
14044a17663cSThomas Veerman }
14054a17663cSThomas Veerman
1406*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
14074a17663cSThomas Veerman static void
declare_argtypes(bucket * bp)1408*0a6a1f1dSLionel Sambuc declare_argtypes(bucket *bp)
14094a17663cSThomas Veerman {
1410*0a6a1f1dSLionel Sambuc char *tags[MAXARGS];
1411*0a6a1f1dSLionel Sambuc int args = 0, c;
14124a17663cSThomas Veerman
1413*0a6a1f1dSLionel Sambuc if (bp->args >= 0)
1414*0a6a1f1dSLionel Sambuc retyped_warning(bp->name);
1415*0a6a1f1dSLionel Sambuc cptr++; /* skip open paren */
1416*0a6a1f1dSLionel Sambuc for (;;)
1417*0a6a1f1dSLionel Sambuc {
14184a17663cSThomas Veerman c = nextc();
14194a17663cSThomas Veerman if (c == EOF)
14204a17663cSThomas Veerman unexpected_EOF();
14214a17663cSThomas Veerman if (c != '<')
14224a17663cSThomas Veerman syntax_error(lineno, line, cptr);
1423*0a6a1f1dSLionel Sambuc tags[args++] = get_tag();
1424*0a6a1f1dSLionel Sambuc c = nextc();
1425*0a6a1f1dSLionel Sambuc if (c == R_PAREN)
1426*0a6a1f1dSLionel Sambuc break;
1427*0a6a1f1dSLionel Sambuc if (c == EOF)
1428*0a6a1f1dSLionel Sambuc unexpected_EOF();
1429*0a6a1f1dSLionel Sambuc }
1430*0a6a1f1dSLionel Sambuc cptr++; /* skip close paren */
1431*0a6a1f1dSLionel Sambuc bp->args = args;
1432*0a6a1f1dSLionel Sambuc bp->argnames = TMALLOC(char *, args);
1433*0a6a1f1dSLionel Sambuc NO_SPACE(bp->argnames);
1434*0a6a1f1dSLionel Sambuc bp->argtags = CALLOC(sizeof(char *), args + 1);
1435*0a6a1f1dSLionel Sambuc NO_SPACE(bp->argtags);
1436*0a6a1f1dSLionel Sambuc while (--args >= 0)
1437*0a6a1f1dSLionel Sambuc {
1438*0a6a1f1dSLionel Sambuc bp->argtags[args] = tags[args];
1439*0a6a1f1dSLionel Sambuc bp->argnames[args] = NULL;
1440*0a6a1f1dSLionel Sambuc }
1441*0a6a1f1dSLionel Sambuc }
1442*0a6a1f1dSLionel Sambuc #endif
1443*0a6a1f1dSLionel Sambuc
1444*0a6a1f1dSLionel Sambuc static void
declare_types(void)1445*0a6a1f1dSLionel Sambuc declare_types(void)
1446*0a6a1f1dSLionel Sambuc {
1447*0a6a1f1dSLionel Sambuc int c;
1448*0a6a1f1dSLionel Sambuc bucket *bp;
1449*0a6a1f1dSLionel Sambuc char *tag = NULL;
1450*0a6a1f1dSLionel Sambuc
1451*0a6a1f1dSLionel Sambuc c = nextc();
1452*0a6a1f1dSLionel Sambuc if (c == EOF)
1453*0a6a1f1dSLionel Sambuc unexpected_EOF();
1454*0a6a1f1dSLionel Sambuc if (c == '<')
14554a17663cSThomas Veerman tag = get_tag();
14564a17663cSThomas Veerman
14574a17663cSThomas Veerman for (;;)
14584a17663cSThomas Veerman {
14594a17663cSThomas Veerman c = nextc();
1460*0a6a1f1dSLionel Sambuc if (c == EOF)
1461*0a6a1f1dSLionel Sambuc unexpected_EOF();
14624a17663cSThomas Veerman if (isalpha(c) || c == '_' || c == '.' || c == '$')
1463*0a6a1f1dSLionel Sambuc {
14644a17663cSThomas Veerman bp = get_name();
1465*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
1466*0a6a1f1dSLionel Sambuc if (nextc() == L_PAREN)
1467*0a6a1f1dSLionel Sambuc declare_argtypes(bp);
1468*0a6a1f1dSLionel Sambuc else
1469*0a6a1f1dSLionel Sambuc bp->args = 0;
1470*0a6a1f1dSLionel Sambuc #endif
1471*0a6a1f1dSLionel Sambuc }
14724a17663cSThomas Veerman else if (c == '\'' || c == '"')
1473*0a6a1f1dSLionel Sambuc {
14744a17663cSThomas Veerman bp = get_literal();
1475*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
1476*0a6a1f1dSLionel Sambuc bp->args = 0;
1477*0a6a1f1dSLionel Sambuc #endif
1478*0a6a1f1dSLionel Sambuc }
14794a17663cSThomas Veerman else
14804a17663cSThomas Veerman return;
14814a17663cSThomas Veerman
1482*0a6a1f1dSLionel Sambuc if (tag)
1483*0a6a1f1dSLionel Sambuc {
14844a17663cSThomas Veerman if (bp->tag && tag != bp->tag)
14854a17663cSThomas Veerman retyped_warning(bp->name);
14864a17663cSThomas Veerman bp->tag = tag;
14874a17663cSThomas Veerman }
14884a17663cSThomas Veerman }
1489*0a6a1f1dSLionel Sambuc }
14904a17663cSThomas Veerman
14914a17663cSThomas Veerman static void
declare_start(void)14924a17663cSThomas Veerman declare_start(void)
14934a17663cSThomas Veerman {
14944a17663cSThomas Veerman int c;
14954a17663cSThomas Veerman bucket *bp;
14964a17663cSThomas Veerman
14974a17663cSThomas Veerman c = nextc();
14984a17663cSThomas Veerman if (c == EOF)
14994a17663cSThomas Veerman unexpected_EOF();
15004a17663cSThomas Veerman if (!isalpha(c) && c != '_' && c != '.' && c != '$')
15014a17663cSThomas Veerman syntax_error(lineno, line, cptr);
15024a17663cSThomas Veerman bp = get_name();
15034a17663cSThomas Veerman if (bp->class == TERM)
15044a17663cSThomas Veerman terminal_start(bp->name);
15054a17663cSThomas Veerman if (goal && goal != bp)
15064a17663cSThomas Veerman restarted_warning();
15074a17663cSThomas Veerman goal = bp;
15084a17663cSThomas Veerman }
15094a17663cSThomas Veerman
15104a17663cSThomas Veerman static void
read_declarations(void)15114a17663cSThomas Veerman read_declarations(void)
15124a17663cSThomas Veerman {
15134a17663cSThomas Veerman int c, k;
15144a17663cSThomas Veerman
15154a17663cSThomas Veerman cache_size = 256;
151684d9c625SLionel Sambuc cache = TMALLOC(char, cache_size);
15174a17663cSThomas Veerman NO_SPACE(cache);
15184a17663cSThomas Veerman
15194a17663cSThomas Veerman for (;;)
15204a17663cSThomas Veerman {
15214a17663cSThomas Veerman c = nextc();
15224a17663cSThomas Veerman if (c == EOF)
15234a17663cSThomas Veerman unexpected_EOF();
15244a17663cSThomas Veerman if (c != '%')
15254a17663cSThomas Veerman syntax_error(lineno, line, cptr);
15264a17663cSThomas Veerman switch (k = keyword())
15274a17663cSThomas Veerman {
15284a17663cSThomas Veerman case MARK:
15294a17663cSThomas Veerman return;
15304a17663cSThomas Veerman
15314a17663cSThomas Veerman case IDENT:
15324a17663cSThomas Veerman copy_ident();
15334a17663cSThomas Veerman break;
15344a17663cSThomas Veerman
15354a17663cSThomas Veerman case TEXT:
15364a17663cSThomas Veerman copy_text();
15374a17663cSThomas Veerman break;
15384a17663cSThomas Veerman
15394a17663cSThomas Veerman case UNION:
15404a17663cSThomas Veerman copy_union();
15414a17663cSThomas Veerman break;
15424a17663cSThomas Veerman
15434a17663cSThomas Veerman case TOKEN:
15444a17663cSThomas Veerman case LEFT:
15454a17663cSThomas Veerman case RIGHT:
15464a17663cSThomas Veerman case NONASSOC:
15474a17663cSThomas Veerman declare_tokens(k);
15484a17663cSThomas Veerman break;
15494a17663cSThomas Veerman
15504a17663cSThomas Veerman case EXPECT:
15514a17663cSThomas Veerman case EXPECT_RR:
15524a17663cSThomas Veerman declare_expect(k);
15534a17663cSThomas Veerman break;
15544a17663cSThomas Veerman
15554a17663cSThomas Veerman case TYPE:
15564a17663cSThomas Veerman declare_types();
15574a17663cSThomas Veerman break;
15584a17663cSThomas Veerman
15594a17663cSThomas Veerman case START:
15604a17663cSThomas Veerman declare_start();
15614a17663cSThomas Veerman break;
15624a17663cSThomas Veerman
15634a17663cSThomas Veerman case PURE_PARSER:
15644a17663cSThomas Veerman pure_parser = 1;
15654a17663cSThomas Veerman break;
15664a17663cSThomas Veerman
15674a17663cSThomas Veerman case PARSE_PARAM:
15684a17663cSThomas Veerman case LEX_PARAM:
15694a17663cSThomas Veerman copy_param(k);
15704a17663cSThomas Veerman break;
15714a17663cSThomas Veerman
1572*0a6a1f1dSLionel Sambuc case TOKEN_TABLE:
1573*0a6a1f1dSLionel Sambuc token_table = 1;
1574*0a6a1f1dSLionel Sambuc break;
1575*0a6a1f1dSLionel Sambuc
1576*0a6a1f1dSLionel Sambuc case ERROR_VERBOSE:
1577*0a6a1f1dSLionel Sambuc error_verbose = 1;
1578*0a6a1f1dSLionel Sambuc break;
1579*0a6a1f1dSLionel Sambuc
1580*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
1581*0a6a1f1dSLionel Sambuc case LOCATIONS:
1582*0a6a1f1dSLionel Sambuc locations = 1;
1583*0a6a1f1dSLionel Sambuc break;
1584*0a6a1f1dSLionel Sambuc
1585*0a6a1f1dSLionel Sambuc case DESTRUCTOR:
1586*0a6a1f1dSLionel Sambuc destructor = 1;
1587*0a6a1f1dSLionel Sambuc copy_destructor();
1588*0a6a1f1dSLionel Sambuc break;
1589*0a6a1f1dSLionel Sambuc case INITIAL_ACTION:
1590*0a6a1f1dSLionel Sambuc copy_initial_action();
1591*0a6a1f1dSLionel Sambuc break;
1592*0a6a1f1dSLionel Sambuc #endif
1593*0a6a1f1dSLionel Sambuc
1594*0a6a1f1dSLionel Sambuc case XXXDEBUG:
1595*0a6a1f1dSLionel Sambuc /* XXX: FIXME */
1596*0a6a1f1dSLionel Sambuc break;
1597*0a6a1f1dSLionel Sambuc
15984a17663cSThomas Veerman case POSIX_YACC:
15994a17663cSThomas Veerman /* noop for bison compatibility. byacc is already designed to be posix
16004a17663cSThomas Veerman * yacc compatible. */
16014a17663cSThomas Veerman break;
16024a17663cSThomas Veerman }
16034a17663cSThomas Veerman }
16044a17663cSThomas Veerman }
16054a17663cSThomas Veerman
16064a17663cSThomas Veerman static void
initialize_grammar(void)16074a17663cSThomas Veerman initialize_grammar(void)
16084a17663cSThomas Veerman {
16094a17663cSThomas Veerman nitems = 4;
16104a17663cSThomas Veerman maxitems = 300;
16114a17663cSThomas Veerman
161284d9c625SLionel Sambuc pitem = TMALLOC(bucket *, maxitems);
16134a17663cSThomas Veerman NO_SPACE(pitem);
16144a17663cSThomas Veerman
16154a17663cSThomas Veerman pitem[0] = 0;
16164a17663cSThomas Veerman pitem[1] = 0;
16174a17663cSThomas Veerman pitem[2] = 0;
16184a17663cSThomas Veerman pitem[3] = 0;
16194a17663cSThomas Veerman
16204a17663cSThomas Veerman nrules = 3;
16214a17663cSThomas Veerman maxrules = 100;
16224a17663cSThomas Veerman
162384d9c625SLionel Sambuc plhs = TMALLOC(bucket *, maxrules);
16244a17663cSThomas Veerman NO_SPACE(plhs);
16254a17663cSThomas Veerman
16264a17663cSThomas Veerman plhs[0] = 0;
16274a17663cSThomas Veerman plhs[1] = 0;
16284a17663cSThomas Veerman plhs[2] = 0;
16294a17663cSThomas Veerman
163084d9c625SLionel Sambuc rprec = TMALLOC(Value_t, maxrules);
16314a17663cSThomas Veerman NO_SPACE(rprec);
16324a17663cSThomas Veerman
16334a17663cSThomas Veerman rprec[0] = 0;
16344a17663cSThomas Veerman rprec[1] = 0;
16354a17663cSThomas Veerman rprec[2] = 0;
16364a17663cSThomas Veerman
163784d9c625SLionel Sambuc rassoc = TMALLOC(Assoc_t, maxrules);
16384a17663cSThomas Veerman NO_SPACE(rassoc);
16394a17663cSThomas Veerman
16404a17663cSThomas Veerman rassoc[0] = TOKEN;
16414a17663cSThomas Veerman rassoc[1] = TOKEN;
16424a17663cSThomas Veerman rassoc[2] = TOKEN;
16434a17663cSThomas Veerman }
16444a17663cSThomas Veerman
16454a17663cSThomas Veerman static void
expand_items(void)16464a17663cSThomas Veerman expand_items(void)
16474a17663cSThomas Veerman {
16484a17663cSThomas Veerman maxitems += 300;
164984d9c625SLionel Sambuc pitem = TREALLOC(bucket *, pitem, maxitems);
16504a17663cSThomas Veerman NO_SPACE(pitem);
16514a17663cSThomas Veerman }
16524a17663cSThomas Veerman
16534a17663cSThomas Veerman static void
expand_rules(void)16544a17663cSThomas Veerman expand_rules(void)
16554a17663cSThomas Veerman {
16564a17663cSThomas Veerman maxrules += 100;
16574a17663cSThomas Veerman
165884d9c625SLionel Sambuc plhs = TREALLOC(bucket *, plhs, maxrules);
16594a17663cSThomas Veerman NO_SPACE(plhs);
16604a17663cSThomas Veerman
166184d9c625SLionel Sambuc rprec = TREALLOC(Value_t, rprec, maxrules);
16624a17663cSThomas Veerman NO_SPACE(rprec);
16634a17663cSThomas Veerman
166484d9c625SLionel Sambuc rassoc = TREALLOC(Assoc_t, rassoc, maxrules);
16654a17663cSThomas Veerman NO_SPACE(rassoc);
16664a17663cSThomas Veerman }
16674a17663cSThomas Veerman
1668*0a6a1f1dSLionel Sambuc /* set immediately prior to where copy_args() could be called, and incremented by
1669*0a6a1f1dSLionel Sambuc the various routines that will rescan the argument list as appropriate */
1670*0a6a1f1dSLionel Sambuc static int rescan_lineno;
1671*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
1672*0a6a1f1dSLionel Sambuc
1673*0a6a1f1dSLionel Sambuc static char *
copy_args(int * alen)1674*0a6a1f1dSLionel Sambuc copy_args(int *alen)
1675*0a6a1f1dSLionel Sambuc {
1676*0a6a1f1dSLionel Sambuc struct mstring *s = msnew();
1677*0a6a1f1dSLionel Sambuc int depth = 0, len = 1;
1678*0a6a1f1dSLionel Sambuc char c, quote = 0;
1679*0a6a1f1dSLionel Sambuc struct ainfo a;
1680*0a6a1f1dSLionel Sambuc
1681*0a6a1f1dSLionel Sambuc a.a_lineno = lineno;
1682*0a6a1f1dSLionel Sambuc a.a_line = dup_line();
1683*0a6a1f1dSLionel Sambuc a.a_cptr = a.a_line + (cptr - line - 1);
1684*0a6a1f1dSLionel Sambuc
1685*0a6a1f1dSLionel Sambuc while ((c = *cptr++) != R_PAREN || depth || quote)
1686*0a6a1f1dSLionel Sambuc {
1687*0a6a1f1dSLionel Sambuc if (c == ',' && !quote && !depth)
1688*0a6a1f1dSLionel Sambuc {
1689*0a6a1f1dSLionel Sambuc len++;
1690*0a6a1f1dSLionel Sambuc mputc(s, 0);
1691*0a6a1f1dSLionel Sambuc continue;
1692*0a6a1f1dSLionel Sambuc }
1693*0a6a1f1dSLionel Sambuc mputc(s, c);
1694*0a6a1f1dSLionel Sambuc if (c == '\n')
1695*0a6a1f1dSLionel Sambuc {
1696*0a6a1f1dSLionel Sambuc get_line();
1697*0a6a1f1dSLionel Sambuc if (!line)
1698*0a6a1f1dSLionel Sambuc {
1699*0a6a1f1dSLionel Sambuc if (quote)
1700*0a6a1f1dSLionel Sambuc unterminated_string(&a);
1701*0a6a1f1dSLionel Sambuc else
1702*0a6a1f1dSLionel Sambuc unterminated_arglist(&a);
1703*0a6a1f1dSLionel Sambuc }
1704*0a6a1f1dSLionel Sambuc }
1705*0a6a1f1dSLionel Sambuc else if (quote)
1706*0a6a1f1dSLionel Sambuc {
1707*0a6a1f1dSLionel Sambuc if (c == quote)
1708*0a6a1f1dSLionel Sambuc quote = 0;
1709*0a6a1f1dSLionel Sambuc else if (c == '\\')
1710*0a6a1f1dSLionel Sambuc {
1711*0a6a1f1dSLionel Sambuc if (*cptr != '\n')
1712*0a6a1f1dSLionel Sambuc mputc(s, *cptr++);
1713*0a6a1f1dSLionel Sambuc }
1714*0a6a1f1dSLionel Sambuc }
1715*0a6a1f1dSLionel Sambuc else
1716*0a6a1f1dSLionel Sambuc {
1717*0a6a1f1dSLionel Sambuc if (c == L_PAREN)
1718*0a6a1f1dSLionel Sambuc depth++;
1719*0a6a1f1dSLionel Sambuc else if (c == R_PAREN)
1720*0a6a1f1dSLionel Sambuc depth--;
1721*0a6a1f1dSLionel Sambuc else if (c == '\"' || c == '\'')
1722*0a6a1f1dSLionel Sambuc quote = c;
1723*0a6a1f1dSLionel Sambuc }
1724*0a6a1f1dSLionel Sambuc }
1725*0a6a1f1dSLionel Sambuc if (alen)
1726*0a6a1f1dSLionel Sambuc *alen = len;
1727*0a6a1f1dSLionel Sambuc FREE(a.a_line);
1728*0a6a1f1dSLionel Sambuc return msdone(s);
1729*0a6a1f1dSLionel Sambuc }
1730*0a6a1f1dSLionel Sambuc
1731*0a6a1f1dSLionel Sambuc static char *
parse_id(char * p,char ** save)1732*0a6a1f1dSLionel Sambuc parse_id(char *p, char **save)
1733*0a6a1f1dSLionel Sambuc {
1734*0a6a1f1dSLionel Sambuc char *b;
1735*0a6a1f1dSLionel Sambuc
1736*0a6a1f1dSLionel Sambuc while (isspace((unsigned char)*p))
1737*0a6a1f1dSLionel Sambuc if (*p++ == '\n')
1738*0a6a1f1dSLionel Sambuc rescan_lineno++;
1739*0a6a1f1dSLionel Sambuc if (!isalpha((unsigned char)*p) && *p != '_')
1740*0a6a1f1dSLionel Sambuc return NULL;
1741*0a6a1f1dSLionel Sambuc b = p;
1742*0a6a1f1dSLionel Sambuc while (isalnum((unsigned char)*p) || *p == '_' || *p == '$')
1743*0a6a1f1dSLionel Sambuc p++;
1744*0a6a1f1dSLionel Sambuc if (save)
1745*0a6a1f1dSLionel Sambuc {
1746*0a6a1f1dSLionel Sambuc *save = cache_tag(b, (size_t) (p - b));
1747*0a6a1f1dSLionel Sambuc }
1748*0a6a1f1dSLionel Sambuc return p;
1749*0a6a1f1dSLionel Sambuc }
1750*0a6a1f1dSLionel Sambuc
1751*0a6a1f1dSLionel Sambuc static char *
parse_int(char * p,int * save)1752*0a6a1f1dSLionel Sambuc parse_int(char *p, int *save)
1753*0a6a1f1dSLionel Sambuc {
1754*0a6a1f1dSLionel Sambuc int neg = 0, val = 0;
1755*0a6a1f1dSLionel Sambuc
1756*0a6a1f1dSLionel Sambuc while (isspace((unsigned char)*p))
1757*0a6a1f1dSLionel Sambuc if (*p++ == '\n')
1758*0a6a1f1dSLionel Sambuc rescan_lineno++;
1759*0a6a1f1dSLionel Sambuc if (*p == '-')
1760*0a6a1f1dSLionel Sambuc {
1761*0a6a1f1dSLionel Sambuc neg = 1;
1762*0a6a1f1dSLionel Sambuc p++;
1763*0a6a1f1dSLionel Sambuc }
1764*0a6a1f1dSLionel Sambuc if (!isdigit((unsigned char)*p))
1765*0a6a1f1dSLionel Sambuc return NULL;
1766*0a6a1f1dSLionel Sambuc while (isdigit((unsigned char)*p))
1767*0a6a1f1dSLionel Sambuc val = val * 10 + *p++ - '0';
1768*0a6a1f1dSLionel Sambuc if (neg)
1769*0a6a1f1dSLionel Sambuc val = -val;
1770*0a6a1f1dSLionel Sambuc if (save)
1771*0a6a1f1dSLionel Sambuc *save = val;
1772*0a6a1f1dSLionel Sambuc return p;
1773*0a6a1f1dSLionel Sambuc }
1774*0a6a1f1dSLionel Sambuc
1775*0a6a1f1dSLionel Sambuc static void
parse_arginfo(bucket * a,char * args,int argslen)1776*0a6a1f1dSLionel Sambuc parse_arginfo(bucket *a, char *args, int argslen)
1777*0a6a1f1dSLionel Sambuc {
1778*0a6a1f1dSLionel Sambuc char *p = args, *tmp;
1779*0a6a1f1dSLionel Sambuc int i, redec = 0;
1780*0a6a1f1dSLionel Sambuc
1781*0a6a1f1dSLionel Sambuc if (a->args > 0)
1782*0a6a1f1dSLionel Sambuc {
1783*0a6a1f1dSLionel Sambuc if (a->args != argslen)
1784*0a6a1f1dSLionel Sambuc arg_number_disagree_warning(rescan_lineno, a->name);
1785*0a6a1f1dSLionel Sambuc redec = 1;
1786*0a6a1f1dSLionel Sambuc }
1787*0a6a1f1dSLionel Sambuc else
1788*0a6a1f1dSLionel Sambuc {
1789*0a6a1f1dSLionel Sambuc if ((a->args = argslen) == 0)
1790*0a6a1f1dSLionel Sambuc return;
1791*0a6a1f1dSLionel Sambuc a->argnames = TMALLOC(char *, argslen);
1792*0a6a1f1dSLionel Sambuc NO_SPACE(a->argnames);
1793*0a6a1f1dSLionel Sambuc a->argtags = TMALLOC(char *, argslen);
1794*0a6a1f1dSLionel Sambuc NO_SPACE(a->argtags);
1795*0a6a1f1dSLionel Sambuc }
1796*0a6a1f1dSLionel Sambuc if (!args)
1797*0a6a1f1dSLionel Sambuc return;
1798*0a6a1f1dSLionel Sambuc for (i = 0; i < argslen; i++)
1799*0a6a1f1dSLionel Sambuc {
1800*0a6a1f1dSLionel Sambuc while (isspace((unsigned char)*p))
1801*0a6a1f1dSLionel Sambuc if (*p++ == '\n')
1802*0a6a1f1dSLionel Sambuc rescan_lineno++;
1803*0a6a1f1dSLionel Sambuc if (*p++ != '$')
1804*0a6a1f1dSLionel Sambuc bad_formals();
1805*0a6a1f1dSLionel Sambuc while (isspace((unsigned char)*p))
1806*0a6a1f1dSLionel Sambuc if (*p++ == '\n')
1807*0a6a1f1dSLionel Sambuc rescan_lineno++;
1808*0a6a1f1dSLionel Sambuc if (*p == '<')
1809*0a6a1f1dSLionel Sambuc {
1810*0a6a1f1dSLionel Sambuc havetags = 1;
1811*0a6a1f1dSLionel Sambuc if (!(p = parse_id(p + 1, &tmp)))
1812*0a6a1f1dSLionel Sambuc bad_formals();
1813*0a6a1f1dSLionel Sambuc while (isspace((unsigned char)*p))
1814*0a6a1f1dSLionel Sambuc if (*p++ == '\n')
1815*0a6a1f1dSLionel Sambuc rescan_lineno++;
1816*0a6a1f1dSLionel Sambuc if (*p++ != '>')
1817*0a6a1f1dSLionel Sambuc bad_formals();
1818*0a6a1f1dSLionel Sambuc if (redec)
1819*0a6a1f1dSLionel Sambuc {
1820*0a6a1f1dSLionel Sambuc if (a->argtags[i] != tmp)
1821*0a6a1f1dSLionel Sambuc arg_type_disagree_warning(rescan_lineno, i + 1, a->name);
1822*0a6a1f1dSLionel Sambuc }
1823*0a6a1f1dSLionel Sambuc else
1824*0a6a1f1dSLionel Sambuc a->argtags[i] = tmp;
1825*0a6a1f1dSLionel Sambuc }
1826*0a6a1f1dSLionel Sambuc else if (!redec)
1827*0a6a1f1dSLionel Sambuc a->argtags[i] = NULL;
1828*0a6a1f1dSLionel Sambuc if (!(p = parse_id(p, &a->argnames[i])))
1829*0a6a1f1dSLionel Sambuc bad_formals();
1830*0a6a1f1dSLionel Sambuc while (isspace((unsigned char)*p))
1831*0a6a1f1dSLionel Sambuc if (*p++ == '\n')
1832*0a6a1f1dSLionel Sambuc rescan_lineno++;
1833*0a6a1f1dSLionel Sambuc if (*p++)
1834*0a6a1f1dSLionel Sambuc bad_formals();
1835*0a6a1f1dSLionel Sambuc }
1836*0a6a1f1dSLionel Sambuc free(args);
1837*0a6a1f1dSLionel Sambuc }
1838*0a6a1f1dSLionel Sambuc
1839*0a6a1f1dSLionel Sambuc static char *
compile_arg(char ** theptr,char * yyvaltag)1840*0a6a1f1dSLionel Sambuc compile_arg(char **theptr, char *yyvaltag)
1841*0a6a1f1dSLionel Sambuc {
1842*0a6a1f1dSLionel Sambuc char *p = *theptr;
1843*0a6a1f1dSLionel Sambuc struct mstring *c = msnew();
1844*0a6a1f1dSLionel Sambuc int i, j, n;
1845*0a6a1f1dSLionel Sambuc Value_t *offsets = NULL, maxoffset;
1846*0a6a1f1dSLionel Sambuc bucket **rhs;
1847*0a6a1f1dSLionel Sambuc
1848*0a6a1f1dSLionel Sambuc maxoffset = 0;
1849*0a6a1f1dSLionel Sambuc n = 0;
1850*0a6a1f1dSLionel Sambuc for (i = nitems - 1; pitem[i]; --i)
1851*0a6a1f1dSLionel Sambuc {
1852*0a6a1f1dSLionel Sambuc n++;
1853*0a6a1f1dSLionel Sambuc if (pitem[i]->class != ARGUMENT)
1854*0a6a1f1dSLionel Sambuc maxoffset++;
1855*0a6a1f1dSLionel Sambuc }
1856*0a6a1f1dSLionel Sambuc if (maxoffset > 0)
1857*0a6a1f1dSLionel Sambuc {
1858*0a6a1f1dSLionel Sambuc offsets = TMALLOC(Value_t, maxoffset + 1);
1859*0a6a1f1dSLionel Sambuc NO_SPACE(offsets);
1860*0a6a1f1dSLionel Sambuc
1861*0a6a1f1dSLionel Sambuc for (j = 0, i++; i < nitems; i++)
1862*0a6a1f1dSLionel Sambuc if (pitem[i]->class != ARGUMENT)
1863*0a6a1f1dSLionel Sambuc offsets[++j] = (Value_t) (i - nitems + 1);
1864*0a6a1f1dSLionel Sambuc }
1865*0a6a1f1dSLionel Sambuc rhs = pitem + nitems - 1;
1866*0a6a1f1dSLionel Sambuc
1867*0a6a1f1dSLionel Sambuc if (yyvaltag)
1868*0a6a1f1dSLionel Sambuc msprintf(c, "yyval.%s = ", yyvaltag);
1869*0a6a1f1dSLionel Sambuc else
1870*0a6a1f1dSLionel Sambuc msprintf(c, "yyval = ");
1871*0a6a1f1dSLionel Sambuc while (*p)
1872*0a6a1f1dSLionel Sambuc {
1873*0a6a1f1dSLionel Sambuc if (*p == '$')
1874*0a6a1f1dSLionel Sambuc {
1875*0a6a1f1dSLionel Sambuc char *tag = NULL;
1876*0a6a1f1dSLionel Sambuc if (*++p == '<')
1877*0a6a1f1dSLionel Sambuc if (!(p = parse_id(++p, &tag)) || *p++ != '>')
1878*0a6a1f1dSLionel Sambuc illegal_tag(rescan_lineno, NULL, NULL);
1879*0a6a1f1dSLionel Sambuc if (isdigit((unsigned char)*p) || *p == '-')
1880*0a6a1f1dSLionel Sambuc {
1881*0a6a1f1dSLionel Sambuc int val;
1882*0a6a1f1dSLionel Sambuc if (!(p = parse_int(p, &val)))
1883*0a6a1f1dSLionel Sambuc dollar_error(rescan_lineno, NULL, NULL);
1884*0a6a1f1dSLionel Sambuc if (val <= 0)
1885*0a6a1f1dSLionel Sambuc i = val - n;
1886*0a6a1f1dSLionel Sambuc else if (val > maxoffset)
1887*0a6a1f1dSLionel Sambuc {
1888*0a6a1f1dSLionel Sambuc dollar_warning(rescan_lineno, val);
1889*0a6a1f1dSLionel Sambuc i = val - maxoffset;
1890*0a6a1f1dSLionel Sambuc }
1891*0a6a1f1dSLionel Sambuc else if (maxoffset > 0)
1892*0a6a1f1dSLionel Sambuc {
1893*0a6a1f1dSLionel Sambuc i = offsets[val];
1894*0a6a1f1dSLionel Sambuc if (!tag && !(tag = rhs[i]->tag) && havetags)
1895*0a6a1f1dSLionel Sambuc untyped_rhs(val, rhs[i]->name);
1896*0a6a1f1dSLionel Sambuc }
1897*0a6a1f1dSLionel Sambuc msprintf(c, "yystack.l_mark[%d]", i);
1898*0a6a1f1dSLionel Sambuc if (tag)
1899*0a6a1f1dSLionel Sambuc msprintf(c, ".%s", tag);
1900*0a6a1f1dSLionel Sambuc else if (havetags)
1901*0a6a1f1dSLionel Sambuc unknown_rhs(val);
1902*0a6a1f1dSLionel Sambuc }
1903*0a6a1f1dSLionel Sambuc else if (isalpha((unsigned char)*p) || *p == '_')
1904*0a6a1f1dSLionel Sambuc {
1905*0a6a1f1dSLionel Sambuc char *arg;
1906*0a6a1f1dSLionel Sambuc if (!(p = parse_id(p, &arg)))
1907*0a6a1f1dSLionel Sambuc dollar_error(rescan_lineno, NULL, NULL);
1908*0a6a1f1dSLionel Sambuc for (i = plhs[nrules]->args - 1; i >= 0; i--)
1909*0a6a1f1dSLionel Sambuc if (arg == plhs[nrules]->argnames[i])
1910*0a6a1f1dSLionel Sambuc break;
1911*0a6a1f1dSLionel Sambuc if (i < 0)
1912*0a6a1f1dSLionel Sambuc unknown_arg_warning(rescan_lineno, "$", arg, NULL, NULL);
1913*0a6a1f1dSLionel Sambuc else if (!tag)
1914*0a6a1f1dSLionel Sambuc tag = plhs[nrules]->argtags[i];
1915*0a6a1f1dSLionel Sambuc msprintf(c, "yystack.l_mark[%d]", i - plhs[nrules]->args + 1
1916*0a6a1f1dSLionel Sambuc - n);
1917*0a6a1f1dSLionel Sambuc if (tag)
1918*0a6a1f1dSLionel Sambuc msprintf(c, ".%s", tag);
1919*0a6a1f1dSLionel Sambuc else if (havetags)
1920*0a6a1f1dSLionel Sambuc untyped_arg_warning(rescan_lineno, "$", arg);
1921*0a6a1f1dSLionel Sambuc }
1922*0a6a1f1dSLionel Sambuc else
1923*0a6a1f1dSLionel Sambuc dollar_error(rescan_lineno, NULL, NULL);
1924*0a6a1f1dSLionel Sambuc }
1925*0a6a1f1dSLionel Sambuc else if (*p == '@')
1926*0a6a1f1dSLionel Sambuc {
1927*0a6a1f1dSLionel Sambuc at_error(rescan_lineno, NULL, NULL);
1928*0a6a1f1dSLionel Sambuc }
1929*0a6a1f1dSLionel Sambuc else
1930*0a6a1f1dSLionel Sambuc {
1931*0a6a1f1dSLionel Sambuc if (*p == '\n')
1932*0a6a1f1dSLionel Sambuc rescan_lineno++;
1933*0a6a1f1dSLionel Sambuc mputc(c, *p++);
1934*0a6a1f1dSLionel Sambuc }
1935*0a6a1f1dSLionel Sambuc }
1936*0a6a1f1dSLionel Sambuc *theptr = p;
1937*0a6a1f1dSLionel Sambuc if (maxoffset > 0)
1938*0a6a1f1dSLionel Sambuc FREE(offsets);
1939*0a6a1f1dSLionel Sambuc return msdone(c);
1940*0a6a1f1dSLionel Sambuc }
1941*0a6a1f1dSLionel Sambuc
1942*0a6a1f1dSLionel Sambuc #define ARG_CACHE_SIZE 1024
1943*0a6a1f1dSLionel Sambuc static struct arg_cache
1944*0a6a1f1dSLionel Sambuc {
1945*0a6a1f1dSLionel Sambuc struct arg_cache *next;
1946*0a6a1f1dSLionel Sambuc char *code;
1947*0a6a1f1dSLionel Sambuc int rule;
1948*0a6a1f1dSLionel Sambuc }
1949*0a6a1f1dSLionel Sambuc *arg_cache[ARG_CACHE_SIZE];
1950*0a6a1f1dSLionel Sambuc
1951*0a6a1f1dSLionel Sambuc static int
lookup_arg_cache(char * code)1952*0a6a1f1dSLionel Sambuc lookup_arg_cache(char *code)
1953*0a6a1f1dSLionel Sambuc {
1954*0a6a1f1dSLionel Sambuc struct arg_cache *entry;
1955*0a6a1f1dSLionel Sambuc
1956*0a6a1f1dSLionel Sambuc entry = arg_cache[strnshash(code) % ARG_CACHE_SIZE];
1957*0a6a1f1dSLionel Sambuc while (entry)
1958*0a6a1f1dSLionel Sambuc {
1959*0a6a1f1dSLionel Sambuc if (!strnscmp(entry->code, code))
1960*0a6a1f1dSLionel Sambuc return entry->rule;
1961*0a6a1f1dSLionel Sambuc entry = entry->next;
1962*0a6a1f1dSLionel Sambuc }
1963*0a6a1f1dSLionel Sambuc return -1;
1964*0a6a1f1dSLionel Sambuc }
1965*0a6a1f1dSLionel Sambuc
1966*0a6a1f1dSLionel Sambuc static void
insert_arg_cache(char * code,int rule)1967*0a6a1f1dSLionel Sambuc insert_arg_cache(char *code, int rule)
1968*0a6a1f1dSLionel Sambuc {
1969*0a6a1f1dSLionel Sambuc struct arg_cache *entry = NEW(struct arg_cache);
1970*0a6a1f1dSLionel Sambuc int i;
1971*0a6a1f1dSLionel Sambuc
1972*0a6a1f1dSLionel Sambuc NO_SPACE(entry);
1973*0a6a1f1dSLionel Sambuc i = strnshash(code) % ARG_CACHE_SIZE;
1974*0a6a1f1dSLionel Sambuc entry->code = code;
1975*0a6a1f1dSLionel Sambuc entry->rule = rule;
1976*0a6a1f1dSLionel Sambuc entry->next = arg_cache[i];
1977*0a6a1f1dSLionel Sambuc arg_cache[i] = entry;
1978*0a6a1f1dSLionel Sambuc }
1979*0a6a1f1dSLionel Sambuc
1980*0a6a1f1dSLionel Sambuc static void
clean_arg_cache(void)1981*0a6a1f1dSLionel Sambuc clean_arg_cache(void)
1982*0a6a1f1dSLionel Sambuc {
1983*0a6a1f1dSLionel Sambuc struct arg_cache *e, *t;
1984*0a6a1f1dSLionel Sambuc int i;
1985*0a6a1f1dSLionel Sambuc
1986*0a6a1f1dSLionel Sambuc for (i = 0; i < ARG_CACHE_SIZE; i++)
1987*0a6a1f1dSLionel Sambuc {
1988*0a6a1f1dSLionel Sambuc for (e = arg_cache[i]; (t = e); e = e->next, FREE(t))
1989*0a6a1f1dSLionel Sambuc free(e->code);
1990*0a6a1f1dSLionel Sambuc arg_cache[i] = NULL;
1991*0a6a1f1dSLionel Sambuc }
1992*0a6a1f1dSLionel Sambuc }
1993*0a6a1f1dSLionel Sambuc #endif
1994*0a6a1f1dSLionel Sambuc
19954a17663cSThomas Veerman static void
advance_to_start(void)19964a17663cSThomas Veerman advance_to_start(void)
19974a17663cSThomas Veerman {
19984a17663cSThomas Veerman int c;
19994a17663cSThomas Veerman bucket *bp;
20004a17663cSThomas Veerman char *s_cptr;
20014a17663cSThomas Veerman int s_lineno;
2002*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2003*0a6a1f1dSLionel Sambuc char *args = NULL;
2004*0a6a1f1dSLionel Sambuc int argslen = 0;
2005*0a6a1f1dSLionel Sambuc #endif
20064a17663cSThomas Veerman
20074a17663cSThomas Veerman for (;;)
20084a17663cSThomas Veerman {
20094a17663cSThomas Veerman c = nextc();
20104a17663cSThomas Veerman if (c != '%')
20114a17663cSThomas Veerman break;
20124a17663cSThomas Veerman s_cptr = cptr;
20134a17663cSThomas Veerman switch (keyword())
20144a17663cSThomas Veerman {
20154a17663cSThomas Veerman case MARK:
20164a17663cSThomas Veerman no_grammar();
20174a17663cSThomas Veerman
20184a17663cSThomas Veerman case TEXT:
20194a17663cSThomas Veerman copy_text();
20204a17663cSThomas Veerman break;
20214a17663cSThomas Veerman
20224a17663cSThomas Veerman case START:
20234a17663cSThomas Veerman declare_start();
20244a17663cSThomas Veerman break;
20254a17663cSThomas Veerman
20264a17663cSThomas Veerman default:
20274a17663cSThomas Veerman syntax_error(lineno, line, s_cptr);
20284a17663cSThomas Veerman }
20294a17663cSThomas Veerman }
20304a17663cSThomas Veerman
20314a17663cSThomas Veerman c = nextc();
20324a17663cSThomas Veerman if (!isalpha(c) && c != '_' && c != '.' && c != '_')
20334a17663cSThomas Veerman syntax_error(lineno, line, cptr);
20344a17663cSThomas Veerman bp = get_name();
20354a17663cSThomas Veerman if (goal == 0)
20364a17663cSThomas Veerman {
20374a17663cSThomas Veerman if (bp->class == TERM)
20384a17663cSThomas Veerman terminal_start(bp->name);
20394a17663cSThomas Veerman goal = bp;
20404a17663cSThomas Veerman }
20414a17663cSThomas Veerman
20424a17663cSThomas Veerman s_lineno = lineno;
20434a17663cSThomas Veerman c = nextc();
20444a17663cSThomas Veerman if (c == EOF)
20454a17663cSThomas Veerman unexpected_EOF();
2046*0a6a1f1dSLionel Sambuc rescan_lineno = lineno; /* line# for possible inherited args rescan */
2047*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2048*0a6a1f1dSLionel Sambuc if (c == L_PAREN)
2049*0a6a1f1dSLionel Sambuc {
2050*0a6a1f1dSLionel Sambuc ++cptr;
2051*0a6a1f1dSLionel Sambuc args = copy_args(&argslen);
2052*0a6a1f1dSLionel Sambuc NO_SPACE(args);
2053*0a6a1f1dSLionel Sambuc c = nextc();
2054*0a6a1f1dSLionel Sambuc }
2055*0a6a1f1dSLionel Sambuc #endif
20564a17663cSThomas Veerman if (c != ':')
20574a17663cSThomas Veerman syntax_error(lineno, line, cptr);
20584a17663cSThomas Veerman start_rule(bp, s_lineno);
2059*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2060*0a6a1f1dSLionel Sambuc parse_arginfo(bp, args, argslen);
2061*0a6a1f1dSLionel Sambuc #endif
20624a17663cSThomas Veerman ++cptr;
20634a17663cSThomas Veerman }
20644a17663cSThomas Veerman
20654a17663cSThomas Veerman static void
start_rule(bucket * bp,int s_lineno)20664a17663cSThomas Veerman start_rule(bucket *bp, int s_lineno)
20674a17663cSThomas Veerman {
20684a17663cSThomas Veerman if (bp->class == TERM)
20694a17663cSThomas Veerman terminal_lhs(s_lineno);
20704a17663cSThomas Veerman bp->class = NONTERM;
2071*0a6a1f1dSLionel Sambuc if (!bp->index)
2072*0a6a1f1dSLionel Sambuc bp->index = nrules;
20734a17663cSThomas Veerman if (nrules >= maxrules)
20744a17663cSThomas Veerman expand_rules();
20754a17663cSThomas Veerman plhs[nrules] = bp;
20764a17663cSThomas Veerman rprec[nrules] = UNDEFINED;
20774a17663cSThomas Veerman rassoc[nrules] = TOKEN;
20784a17663cSThomas Veerman }
20794a17663cSThomas Veerman
20804a17663cSThomas Veerman static void
end_rule(void)20814a17663cSThomas Veerman end_rule(void)
20824a17663cSThomas Veerman {
20834a17663cSThomas Veerman int i;
20844a17663cSThomas Veerman
20854a17663cSThomas Veerman if (!last_was_action && plhs[nrules]->tag)
20864a17663cSThomas Veerman {
20874a17663cSThomas Veerman if (pitem[nitems - 1])
20884a17663cSThomas Veerman {
20894a17663cSThomas Veerman for (i = nitems - 1; (i > 0) && pitem[i]; --i)
20904a17663cSThomas Veerman continue;
20914a17663cSThomas Veerman if (pitem[i + 1] == 0 || pitem[i + 1]->tag != plhs[nrules]->tag)
20924a17663cSThomas Veerman default_action_warning();
20934a17663cSThomas Veerman }
20944a17663cSThomas Veerman else
20954a17663cSThomas Veerman {
20964a17663cSThomas Veerman default_action_warning();
20974a17663cSThomas Veerman }
20984a17663cSThomas Veerman }
20994a17663cSThomas Veerman
21004a17663cSThomas Veerman last_was_action = 0;
21014a17663cSThomas Veerman if (nitems >= maxitems)
21024a17663cSThomas Veerman expand_items();
21034a17663cSThomas Veerman pitem[nitems] = 0;
21044a17663cSThomas Veerman ++nitems;
21054a17663cSThomas Veerman ++nrules;
21064a17663cSThomas Veerman }
21074a17663cSThomas Veerman
21084a17663cSThomas Veerman static void
insert_empty_rule(void)21094a17663cSThomas Veerman insert_empty_rule(void)
21104a17663cSThomas Veerman {
21114a17663cSThomas Veerman bucket *bp, **bpp;
21124a17663cSThomas Veerman
21134a17663cSThomas Veerman assert(cache);
21144a17663cSThomas Veerman sprintf(cache, "$$%d", ++gensym);
21154a17663cSThomas Veerman bp = make_bucket(cache);
21164a17663cSThomas Veerman last_symbol->next = bp;
21174a17663cSThomas Veerman last_symbol = bp;
21184a17663cSThomas Veerman bp->tag = plhs[nrules]->tag;
2119*0a6a1f1dSLionel Sambuc bp->class = ACTION;
2120*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2121*0a6a1f1dSLionel Sambuc bp->args = 0;
2122*0a6a1f1dSLionel Sambuc #endif
21234a17663cSThomas Veerman
2124*0a6a1f1dSLionel Sambuc nitems = (Value_t) (nitems + 2);
2125*0a6a1f1dSLionel Sambuc if (nitems > maxitems)
21264a17663cSThomas Veerman expand_items();
21274a17663cSThomas Veerman bpp = pitem + nitems - 1;
21284a17663cSThomas Veerman *bpp-- = bp;
21294a17663cSThomas Veerman while ((bpp[0] = bpp[-1]) != 0)
21304a17663cSThomas Veerman --bpp;
21314a17663cSThomas Veerman
21324a17663cSThomas Veerman if (++nrules >= maxrules)
21334a17663cSThomas Veerman expand_rules();
21344a17663cSThomas Veerman plhs[nrules] = plhs[nrules - 1];
21354a17663cSThomas Veerman plhs[nrules - 1] = bp;
21364a17663cSThomas Veerman rprec[nrules] = rprec[nrules - 1];
21374a17663cSThomas Veerman rprec[nrules - 1] = 0;
21384a17663cSThomas Veerman rassoc[nrules] = rassoc[nrules - 1];
21394a17663cSThomas Veerman rassoc[nrules - 1] = TOKEN;
21404a17663cSThomas Veerman }
21414a17663cSThomas Veerman
2142*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2143*0a6a1f1dSLionel Sambuc static char *
insert_arg_rule(char * arg,char * tag)2144*0a6a1f1dSLionel Sambuc insert_arg_rule(char *arg, char *tag)
2145*0a6a1f1dSLionel Sambuc {
2146*0a6a1f1dSLionel Sambuc int line_number = rescan_lineno;
2147*0a6a1f1dSLionel Sambuc char *code = compile_arg(&arg, tag);
2148*0a6a1f1dSLionel Sambuc int rule = lookup_arg_cache(code);
2149*0a6a1f1dSLionel Sambuc FILE *f = action_file;
2150*0a6a1f1dSLionel Sambuc
2151*0a6a1f1dSLionel Sambuc if (rule < 0)
2152*0a6a1f1dSLionel Sambuc {
2153*0a6a1f1dSLionel Sambuc rule = nrules;
2154*0a6a1f1dSLionel Sambuc insert_arg_cache(code, rule);
2155*0a6a1f1dSLionel Sambuc fprintf(f, "case %d:\n", rule - 2);
2156*0a6a1f1dSLionel Sambuc if (!lflag)
2157*0a6a1f1dSLionel Sambuc fprintf(f, line_format, line_number, input_file_name);
2158*0a6a1f1dSLionel Sambuc fprintf(f, "%s;\n", code);
2159*0a6a1f1dSLionel Sambuc fprintf(f, "break;\n");
2160*0a6a1f1dSLionel Sambuc insert_empty_rule();
2161*0a6a1f1dSLionel Sambuc plhs[rule]->tag = tag;
2162*0a6a1f1dSLionel Sambuc plhs[rule]->class = ARGUMENT;
2163*0a6a1f1dSLionel Sambuc }
2164*0a6a1f1dSLionel Sambuc else
2165*0a6a1f1dSLionel Sambuc {
2166*0a6a1f1dSLionel Sambuc if (++nitems > maxitems)
2167*0a6a1f1dSLionel Sambuc expand_items();
2168*0a6a1f1dSLionel Sambuc pitem[nitems - 1] = plhs[rule];
2169*0a6a1f1dSLionel Sambuc free(code);
2170*0a6a1f1dSLionel Sambuc }
2171*0a6a1f1dSLionel Sambuc return arg + 1;
2172*0a6a1f1dSLionel Sambuc }
2173*0a6a1f1dSLionel Sambuc #endif
2174*0a6a1f1dSLionel Sambuc
21754a17663cSThomas Veerman static void
add_symbol(void)21764a17663cSThomas Veerman add_symbol(void)
21774a17663cSThomas Veerman {
21784a17663cSThomas Veerman int c;
21794a17663cSThomas Veerman bucket *bp;
21804a17663cSThomas Veerman int s_lineno = lineno;
2181*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2182*0a6a1f1dSLionel Sambuc char *args = NULL;
2183*0a6a1f1dSLionel Sambuc int argslen = 0;
2184*0a6a1f1dSLionel Sambuc #endif
21854a17663cSThomas Veerman
21864a17663cSThomas Veerman c = *cptr;
21874a17663cSThomas Veerman if (c == '\'' || c == '"')
21884a17663cSThomas Veerman bp = get_literal();
21894a17663cSThomas Veerman else
21904a17663cSThomas Veerman bp = get_name();
21914a17663cSThomas Veerman
21924a17663cSThomas Veerman c = nextc();
2193*0a6a1f1dSLionel Sambuc rescan_lineno = lineno; /* line# for possible inherited args rescan */
2194*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2195*0a6a1f1dSLionel Sambuc if (c == L_PAREN)
2196*0a6a1f1dSLionel Sambuc {
2197*0a6a1f1dSLionel Sambuc ++cptr;
2198*0a6a1f1dSLionel Sambuc args = copy_args(&argslen);
2199*0a6a1f1dSLionel Sambuc NO_SPACE(args);
2200*0a6a1f1dSLionel Sambuc c = nextc();
2201*0a6a1f1dSLionel Sambuc }
2202*0a6a1f1dSLionel Sambuc #endif
22034a17663cSThomas Veerman if (c == ':')
22044a17663cSThomas Veerman {
22054a17663cSThomas Veerman end_rule();
22064a17663cSThomas Veerman start_rule(bp, s_lineno);
2207*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2208*0a6a1f1dSLionel Sambuc parse_arginfo(bp, args, argslen);
2209*0a6a1f1dSLionel Sambuc #endif
22104a17663cSThomas Veerman ++cptr;
22114a17663cSThomas Veerman return;
22124a17663cSThomas Veerman }
22134a17663cSThomas Veerman
22144a17663cSThomas Veerman if (last_was_action)
22154a17663cSThomas Veerman insert_empty_rule();
22164a17663cSThomas Veerman last_was_action = 0;
22174a17663cSThomas Veerman
2218*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2219*0a6a1f1dSLionel Sambuc if (bp->args < 0)
2220*0a6a1f1dSLionel Sambuc bp->args = argslen;
2221*0a6a1f1dSLionel Sambuc if (argslen == 0 && bp->args > 0 && pitem[nitems - 1] == NULL)
2222*0a6a1f1dSLionel Sambuc {
2223*0a6a1f1dSLionel Sambuc int i;
2224*0a6a1f1dSLionel Sambuc if (plhs[nrules]->args != bp->args)
2225*0a6a1f1dSLionel Sambuc wrong_number_args_warning("default ", bp->name);
2226*0a6a1f1dSLionel Sambuc for (i = bp->args - 1; i >= 0; i--)
2227*0a6a1f1dSLionel Sambuc if (plhs[nrules]->argtags[i] != bp->argtags[i])
2228*0a6a1f1dSLionel Sambuc wrong_type_for_arg_warning(i + 1, bp->name);
2229*0a6a1f1dSLionel Sambuc }
2230*0a6a1f1dSLionel Sambuc else if (bp->args != argslen)
2231*0a6a1f1dSLionel Sambuc wrong_number_args_warning("", bp->name);
2232*0a6a1f1dSLionel Sambuc if (bp->args > 0 && argslen > 0)
2233*0a6a1f1dSLionel Sambuc {
2234*0a6a1f1dSLionel Sambuc char *ap;
2235*0a6a1f1dSLionel Sambuc int i;
2236*0a6a1f1dSLionel Sambuc for (ap = args, i = 0; i < argslen; i++)
2237*0a6a1f1dSLionel Sambuc ap = insert_arg_rule(ap, bp->argtags[i]);
2238*0a6a1f1dSLionel Sambuc free(args);
2239*0a6a1f1dSLionel Sambuc }
2240*0a6a1f1dSLionel Sambuc #endif /* defined(YYBTYACC) */
2241*0a6a1f1dSLionel Sambuc
22424a17663cSThomas Veerman if (++nitems > maxitems)
22434a17663cSThomas Veerman expand_items();
22444a17663cSThomas Veerman pitem[nitems - 1] = bp;
22454a17663cSThomas Veerman }
22464a17663cSThomas Veerman
22474a17663cSThomas Veerman static void
copy_action(void)22484a17663cSThomas Veerman copy_action(void)
22494a17663cSThomas Veerman {
22504a17663cSThomas Veerman int c;
2251*0a6a1f1dSLionel Sambuc int i, j, n;
22524a17663cSThomas Veerman int depth;
2253*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2254*0a6a1f1dSLionel Sambuc int trialaction = 0;
2255*0a6a1f1dSLionel Sambuc int haveyyval = 0;
2256*0a6a1f1dSLionel Sambuc #endif
22574a17663cSThomas Veerman char *tag;
22584a17663cSThomas Veerman FILE *f = action_file;
2259*0a6a1f1dSLionel Sambuc struct ainfo a;
2260*0a6a1f1dSLionel Sambuc Value_t *offsets = NULL, maxoffset;
2261*0a6a1f1dSLionel Sambuc bucket **rhs;
2262*0a6a1f1dSLionel Sambuc
2263*0a6a1f1dSLionel Sambuc a.a_lineno = lineno;
2264*0a6a1f1dSLionel Sambuc a.a_line = dup_line();
2265*0a6a1f1dSLionel Sambuc a.a_cptr = a.a_line + (cptr - line);
22664a17663cSThomas Veerman
22674a17663cSThomas Veerman if (last_was_action)
22684a17663cSThomas Veerman insert_empty_rule();
22694a17663cSThomas Veerman last_was_action = 1;
22704a17663cSThomas Veerman
22714a17663cSThomas Veerman fprintf(f, "case %d:\n", nrules - 2);
2272*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2273*0a6a1f1dSLionel Sambuc if (backtrack)
2274*0a6a1f1dSLionel Sambuc {
2275*0a6a1f1dSLionel Sambuc if (*cptr != L_BRAC)
2276*0a6a1f1dSLionel Sambuc fprintf(f, " if (!yytrial)\n");
2277*0a6a1f1dSLionel Sambuc else
2278*0a6a1f1dSLionel Sambuc trialaction = 1;
2279*0a6a1f1dSLionel Sambuc }
2280*0a6a1f1dSLionel Sambuc #endif
22814a17663cSThomas Veerman if (!lflag)
22824a17663cSThomas Veerman fprintf(f, line_format, lineno, input_file_name);
22834a17663cSThomas Veerman if (*cptr == '=')
22844a17663cSThomas Veerman ++cptr;
22854a17663cSThomas Veerman
22864a17663cSThomas Veerman /* avoid putting curly-braces in first column, to ease editing */
22874a17663cSThomas Veerman if (*after_blanks(cptr) == L_CURL)
22884a17663cSThomas Veerman {
22894a17663cSThomas Veerman putc('\t', f);
22904a17663cSThomas Veerman cptr = after_blanks(cptr);
22914a17663cSThomas Veerman }
22924a17663cSThomas Veerman
2293*0a6a1f1dSLionel Sambuc maxoffset = 0;
22944a17663cSThomas Veerman n = 0;
22954a17663cSThomas Veerman for (i = nitems - 1; pitem[i]; --i)
2296*0a6a1f1dSLionel Sambuc {
22974a17663cSThomas Veerman ++n;
2298*0a6a1f1dSLionel Sambuc if (pitem[i]->class != ARGUMENT)
2299*0a6a1f1dSLionel Sambuc maxoffset++;
2300*0a6a1f1dSLionel Sambuc }
2301*0a6a1f1dSLionel Sambuc if (maxoffset > 0)
2302*0a6a1f1dSLionel Sambuc {
2303*0a6a1f1dSLionel Sambuc offsets = TMALLOC(Value_t, maxoffset + 1);
2304*0a6a1f1dSLionel Sambuc NO_SPACE(offsets);
2305*0a6a1f1dSLionel Sambuc
2306*0a6a1f1dSLionel Sambuc for (j = 0, i++; i < nitems; i++)
2307*0a6a1f1dSLionel Sambuc {
2308*0a6a1f1dSLionel Sambuc if (pitem[i]->class != ARGUMENT)
2309*0a6a1f1dSLionel Sambuc {
2310*0a6a1f1dSLionel Sambuc offsets[++j] = (Value_t) (i - nitems + 1);
2311*0a6a1f1dSLionel Sambuc }
2312*0a6a1f1dSLionel Sambuc }
2313*0a6a1f1dSLionel Sambuc }
2314*0a6a1f1dSLionel Sambuc rhs = pitem + nitems - 1;
23154a17663cSThomas Veerman
23164a17663cSThomas Veerman depth = 0;
23174a17663cSThomas Veerman loop:
23184a17663cSThomas Veerman c = *cptr;
23194a17663cSThomas Veerman if (c == '$')
23204a17663cSThomas Veerman {
23214a17663cSThomas Veerman if (cptr[1] == '<')
23224a17663cSThomas Veerman {
23234a17663cSThomas Veerman int d_lineno = lineno;
23244a17663cSThomas Veerman char *d_line = dup_line();
23254a17663cSThomas Veerman char *d_cptr = d_line + (cptr - line);
23264a17663cSThomas Veerman
23274a17663cSThomas Veerman ++cptr;
23284a17663cSThomas Veerman tag = get_tag();
23294a17663cSThomas Veerman c = *cptr;
23304a17663cSThomas Veerman if (c == '$')
23314a17663cSThomas Veerman {
23324a17663cSThomas Veerman fprintf(f, "yyval.%s", tag);
23334a17663cSThomas Veerman ++cptr;
23344a17663cSThomas Veerman FREE(d_line);
23354a17663cSThomas Veerman goto loop;
23364a17663cSThomas Veerman }
23374a17663cSThomas Veerman else if (isdigit(c))
23384a17663cSThomas Veerman {
23394a17663cSThomas Veerman i = get_number();
2340*0a6a1f1dSLionel Sambuc if (i == 0)
2341*0a6a1f1dSLionel Sambuc fprintf(f, "yystack.l_mark[%d].%s", -n, tag);
2342*0a6a1f1dSLionel Sambuc else if (i > maxoffset)
2343*0a6a1f1dSLionel Sambuc {
23444a17663cSThomas Veerman dollar_warning(d_lineno, i);
2345*0a6a1f1dSLionel Sambuc fprintf(f, "yystack.l_mark[%d].%s", i - maxoffset, tag);
2346*0a6a1f1dSLionel Sambuc }
2347*0a6a1f1dSLionel Sambuc else if (offsets)
2348*0a6a1f1dSLionel Sambuc fprintf(f, "yystack.l_mark[%d].%s", offsets[i], tag);
23494a17663cSThomas Veerman FREE(d_line);
23504a17663cSThomas Veerman goto loop;
23514a17663cSThomas Veerman }
23524a17663cSThomas Veerman else if (c == '-' && isdigit(UCH(cptr[1])))
23534a17663cSThomas Veerman {
23544a17663cSThomas Veerman ++cptr;
23554a17663cSThomas Veerman i = -get_number() - n;
23564a17663cSThomas Veerman fprintf(f, "yystack.l_mark[%d].%s", i, tag);
23574a17663cSThomas Veerman FREE(d_line);
23584a17663cSThomas Veerman goto loop;
23594a17663cSThomas Veerman }
2360*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2361*0a6a1f1dSLionel Sambuc else if (isalpha(c) || c == '_')
2362*0a6a1f1dSLionel Sambuc {
2363*0a6a1f1dSLionel Sambuc char *arg = scan_id();
2364*0a6a1f1dSLionel Sambuc for (i = plhs[nrules]->args - 1; i >= 0; i--)
2365*0a6a1f1dSLionel Sambuc if (arg == plhs[nrules]->argnames[i])
2366*0a6a1f1dSLionel Sambuc break;
2367*0a6a1f1dSLionel Sambuc if (i < 0)
2368*0a6a1f1dSLionel Sambuc unknown_arg_warning(d_lineno, "$", arg, d_line, d_cptr);
2369*0a6a1f1dSLionel Sambuc fprintf(f, "yystack.l_mark[%d].%s", i - plhs[nrules]->args +
2370*0a6a1f1dSLionel Sambuc 1 - n, tag);
2371*0a6a1f1dSLionel Sambuc FREE(d_line);
2372*0a6a1f1dSLionel Sambuc goto loop;
2373*0a6a1f1dSLionel Sambuc }
2374*0a6a1f1dSLionel Sambuc #endif
23754a17663cSThomas Veerman else
23764a17663cSThomas Veerman dollar_error(d_lineno, d_line, d_cptr);
23774a17663cSThomas Veerman }
23784a17663cSThomas Veerman else if (cptr[1] == '$')
23794a17663cSThomas Veerman {
2380*0a6a1f1dSLionel Sambuc if (havetags)
23814a17663cSThomas Veerman {
23824a17663cSThomas Veerman tag = plhs[nrules]->tag;
23834a17663cSThomas Veerman if (tag == 0)
23844a17663cSThomas Veerman untyped_lhs();
23854a17663cSThomas Veerman fprintf(f, "yyval.%s", tag);
23864a17663cSThomas Veerman }
23874a17663cSThomas Veerman else
23884a17663cSThomas Veerman fprintf(f, "yyval");
23894a17663cSThomas Veerman cptr += 2;
2390*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2391*0a6a1f1dSLionel Sambuc haveyyval = 1;
2392*0a6a1f1dSLionel Sambuc #endif
23934a17663cSThomas Veerman goto loop;
23944a17663cSThomas Veerman }
23954a17663cSThomas Veerman else if (isdigit(UCH(cptr[1])))
23964a17663cSThomas Veerman {
23974a17663cSThomas Veerman ++cptr;
23984a17663cSThomas Veerman i = get_number();
2399*0a6a1f1dSLionel Sambuc if (havetags && offsets)
24004a17663cSThomas Veerman {
2401*0a6a1f1dSLionel Sambuc if (i <= 0 || i > maxoffset)
24024a17663cSThomas Veerman unknown_rhs(i);
2403*0a6a1f1dSLionel Sambuc tag = rhs[offsets[i]]->tag;
24044a17663cSThomas Veerman if (tag == 0)
2405*0a6a1f1dSLionel Sambuc untyped_rhs(i, rhs[offsets[i]]->name);
2406*0a6a1f1dSLionel Sambuc fprintf(f, "yystack.l_mark[%d].%s", offsets[i], tag);
24074a17663cSThomas Veerman }
24084a17663cSThomas Veerman else
24094a17663cSThomas Veerman {
2410*0a6a1f1dSLionel Sambuc if (i == 0)
2411*0a6a1f1dSLionel Sambuc fprintf(f, "yystack.l_mark[%d]", -n);
2412*0a6a1f1dSLionel Sambuc else if (i > maxoffset)
2413*0a6a1f1dSLionel Sambuc {
24144a17663cSThomas Veerman dollar_warning(lineno, i);
2415*0a6a1f1dSLionel Sambuc fprintf(f, "yystack.l_mark[%d]", i - maxoffset);
2416*0a6a1f1dSLionel Sambuc }
2417*0a6a1f1dSLionel Sambuc else if (offsets)
2418*0a6a1f1dSLionel Sambuc fprintf(f, "yystack.l_mark[%d]", offsets[i]);
24194a17663cSThomas Veerman }
24204a17663cSThomas Veerman goto loop;
24214a17663cSThomas Veerman }
24224a17663cSThomas Veerman else if (cptr[1] == '-')
24234a17663cSThomas Veerman {
24244a17663cSThomas Veerman cptr += 2;
24254a17663cSThomas Veerman i = get_number();
2426*0a6a1f1dSLionel Sambuc if (havetags)
24274a17663cSThomas Veerman unknown_rhs(-i);
24284a17663cSThomas Veerman fprintf(f, "yystack.l_mark[%d]", -i - n);
24294a17663cSThomas Veerman goto loop;
24304a17663cSThomas Veerman }
2431*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2432*0a6a1f1dSLionel Sambuc else if (isalpha((unsigned char)cptr[1]) || cptr[1] == '_')
2433*0a6a1f1dSLionel Sambuc {
2434*0a6a1f1dSLionel Sambuc char *arg;
2435*0a6a1f1dSLionel Sambuc ++cptr;
2436*0a6a1f1dSLionel Sambuc arg = scan_id();
2437*0a6a1f1dSLionel Sambuc for (i = plhs[nrules]->args - 1; i >= 0; i--)
2438*0a6a1f1dSLionel Sambuc if (arg == plhs[nrules]->argnames[i])
2439*0a6a1f1dSLionel Sambuc break;
2440*0a6a1f1dSLionel Sambuc if (i < 0)
2441*0a6a1f1dSLionel Sambuc unknown_arg_warning(lineno, "$", arg, line, cptr);
2442*0a6a1f1dSLionel Sambuc tag = (i < 0 ? NULL : plhs[nrules]->argtags[i]);
2443*0a6a1f1dSLionel Sambuc fprintf(f, "yystack.l_mark[%d]", i - plhs[nrules]->args + 1 - n);
2444*0a6a1f1dSLionel Sambuc if (tag)
2445*0a6a1f1dSLionel Sambuc fprintf(f, ".%s", tag);
2446*0a6a1f1dSLionel Sambuc else if (havetags)
2447*0a6a1f1dSLionel Sambuc untyped_arg_warning(lineno, "$", arg);
2448*0a6a1f1dSLionel Sambuc goto loop;
24494a17663cSThomas Veerman }
2450*0a6a1f1dSLionel Sambuc #endif
2451*0a6a1f1dSLionel Sambuc }
2452*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2453*0a6a1f1dSLionel Sambuc if (c == '@')
2454*0a6a1f1dSLionel Sambuc {
2455*0a6a1f1dSLionel Sambuc if (!locations)
2456*0a6a1f1dSLionel Sambuc {
2457*0a6a1f1dSLionel Sambuc int l_lineno = lineno;
2458*0a6a1f1dSLionel Sambuc char *l_line = dup_line();
2459*0a6a1f1dSLionel Sambuc char *l_cptr = l_line + (cptr - line);
2460*0a6a1f1dSLionel Sambuc syntax_error(l_lineno, l_line, l_cptr);
2461*0a6a1f1dSLionel Sambuc }
2462*0a6a1f1dSLionel Sambuc if (cptr[1] == '$')
2463*0a6a1f1dSLionel Sambuc {
2464*0a6a1f1dSLionel Sambuc fprintf(f, "yyloc");
2465*0a6a1f1dSLionel Sambuc cptr += 2;
2466*0a6a1f1dSLionel Sambuc goto loop;
2467*0a6a1f1dSLionel Sambuc }
2468*0a6a1f1dSLionel Sambuc else if (isdigit(UCH(cptr[1])))
2469*0a6a1f1dSLionel Sambuc {
2470*0a6a1f1dSLionel Sambuc ++cptr;
2471*0a6a1f1dSLionel Sambuc i = get_number();
2472*0a6a1f1dSLionel Sambuc if (i == 0)
2473*0a6a1f1dSLionel Sambuc fprintf(f, "yystack.p_mark[%d]", -n);
2474*0a6a1f1dSLionel Sambuc else if (i > maxoffset)
2475*0a6a1f1dSLionel Sambuc {
2476*0a6a1f1dSLionel Sambuc at_warning(lineno, i);
2477*0a6a1f1dSLionel Sambuc fprintf(f, "yystack.p_mark[%d]", i - maxoffset);
2478*0a6a1f1dSLionel Sambuc }
2479*0a6a1f1dSLionel Sambuc else if (offsets)
2480*0a6a1f1dSLionel Sambuc fprintf(f, "yystack.p_mark[%d]", offsets[i]);
2481*0a6a1f1dSLionel Sambuc goto loop;
2482*0a6a1f1dSLionel Sambuc }
2483*0a6a1f1dSLionel Sambuc }
2484*0a6a1f1dSLionel Sambuc #endif
24854a17663cSThomas Veerman if (isalpha(c) || c == '_' || c == '$')
24864a17663cSThomas Veerman {
24874a17663cSThomas Veerman do
24884a17663cSThomas Veerman {
24894a17663cSThomas Veerman putc(c, f);
24904a17663cSThomas Veerman c = *++cptr;
24914a17663cSThomas Veerman }
24924a17663cSThomas Veerman while (isalnum(c) || c == '_' || c == '$');
24934a17663cSThomas Veerman goto loop;
24944a17663cSThomas Veerman }
24954a17663cSThomas Veerman ++cptr;
2496*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2497*0a6a1f1dSLionel Sambuc if (backtrack)
2498*0a6a1f1dSLionel Sambuc {
2499*0a6a1f1dSLionel Sambuc if (trialaction && c == L_BRAC && depth == 0)
2500*0a6a1f1dSLionel Sambuc {
2501*0a6a1f1dSLionel Sambuc ++depth;
2502*0a6a1f1dSLionel Sambuc putc(L_CURL, f);
2503*0a6a1f1dSLionel Sambuc goto loop;
2504*0a6a1f1dSLionel Sambuc }
2505*0a6a1f1dSLionel Sambuc if (trialaction && c == R_BRAC && depth == 1)
2506*0a6a1f1dSLionel Sambuc {
2507*0a6a1f1dSLionel Sambuc --depth;
2508*0a6a1f1dSLionel Sambuc putc(R_CURL, f);
2509*0a6a1f1dSLionel Sambuc c = nextc();
2510*0a6a1f1dSLionel Sambuc if (c == L_BRAC && !haveyyval)
2511*0a6a1f1dSLionel Sambuc {
2512*0a6a1f1dSLionel Sambuc goto loop;
2513*0a6a1f1dSLionel Sambuc }
2514*0a6a1f1dSLionel Sambuc if (c == L_CURL && !haveyyval)
2515*0a6a1f1dSLionel Sambuc {
2516*0a6a1f1dSLionel Sambuc fprintf(f, " if (!yytrial)\n");
2517*0a6a1f1dSLionel Sambuc if (!lflag)
2518*0a6a1f1dSLionel Sambuc fprintf(f, line_format, lineno, input_file_name);
2519*0a6a1f1dSLionel Sambuc trialaction = 0;
2520*0a6a1f1dSLionel Sambuc goto loop;
2521*0a6a1f1dSLionel Sambuc }
2522*0a6a1f1dSLionel Sambuc fprintf(f, "\nbreak;\n");
2523*0a6a1f1dSLionel Sambuc FREE(a.a_line);
2524*0a6a1f1dSLionel Sambuc if (maxoffset > 0)
2525*0a6a1f1dSLionel Sambuc FREE(offsets);
2526*0a6a1f1dSLionel Sambuc return;
2527*0a6a1f1dSLionel Sambuc }
2528*0a6a1f1dSLionel Sambuc }
2529*0a6a1f1dSLionel Sambuc #endif
2530*0a6a1f1dSLionel Sambuc putc(c, f);
25314a17663cSThomas Veerman switch (c)
25324a17663cSThomas Veerman {
25334a17663cSThomas Veerman case '\n':
25344a17663cSThomas Veerman get_line();
25354a17663cSThomas Veerman if (line)
25364a17663cSThomas Veerman goto loop;
2537*0a6a1f1dSLionel Sambuc unterminated_action(&a);
25384a17663cSThomas Veerman
25394a17663cSThomas Veerman case ';':
25404a17663cSThomas Veerman if (depth > 0)
25414a17663cSThomas Veerman goto loop;
25424a17663cSThomas Veerman fprintf(f, "\nbreak;\n");
2543*0a6a1f1dSLionel Sambuc free(a.a_line);
2544*0a6a1f1dSLionel Sambuc if (maxoffset > 0)
2545*0a6a1f1dSLionel Sambuc FREE(offsets);
25464a17663cSThomas Veerman return;
25474a17663cSThomas Veerman
2548*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2549*0a6a1f1dSLionel Sambuc case L_BRAC:
2550*0a6a1f1dSLionel Sambuc if (backtrack)
2551*0a6a1f1dSLionel Sambuc ++depth;
2552*0a6a1f1dSLionel Sambuc goto loop;
2553*0a6a1f1dSLionel Sambuc
2554*0a6a1f1dSLionel Sambuc case R_BRAC:
2555*0a6a1f1dSLionel Sambuc if (backtrack)
2556*0a6a1f1dSLionel Sambuc --depth;
2557*0a6a1f1dSLionel Sambuc goto loop;
2558*0a6a1f1dSLionel Sambuc #endif
2559*0a6a1f1dSLionel Sambuc
25604a17663cSThomas Veerman case L_CURL:
25614a17663cSThomas Veerman ++depth;
25624a17663cSThomas Veerman goto loop;
25634a17663cSThomas Veerman
25644a17663cSThomas Veerman case R_CURL:
25654a17663cSThomas Veerman if (--depth > 0)
25664a17663cSThomas Veerman goto loop;
2567*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2568*0a6a1f1dSLionel Sambuc if (backtrack)
2569*0a6a1f1dSLionel Sambuc {
2570*0a6a1f1dSLionel Sambuc c = nextc();
2571*0a6a1f1dSLionel Sambuc if (c == L_BRAC && !haveyyval)
2572*0a6a1f1dSLionel Sambuc {
2573*0a6a1f1dSLionel Sambuc trialaction = 1;
2574*0a6a1f1dSLionel Sambuc goto loop;
2575*0a6a1f1dSLionel Sambuc }
2576*0a6a1f1dSLionel Sambuc if (c == L_CURL && !haveyyval)
2577*0a6a1f1dSLionel Sambuc {
2578*0a6a1f1dSLionel Sambuc fprintf(f, " if (!yytrial)\n");
2579*0a6a1f1dSLionel Sambuc if (!lflag)
2580*0a6a1f1dSLionel Sambuc fprintf(f, line_format, lineno, input_file_name);
2581*0a6a1f1dSLionel Sambuc goto loop;
2582*0a6a1f1dSLionel Sambuc }
2583*0a6a1f1dSLionel Sambuc }
2584*0a6a1f1dSLionel Sambuc #endif
25854a17663cSThomas Veerman fprintf(f, "\nbreak;\n");
2586*0a6a1f1dSLionel Sambuc free(a.a_line);
2587*0a6a1f1dSLionel Sambuc if (maxoffset > 0)
2588*0a6a1f1dSLionel Sambuc FREE(offsets);
25894a17663cSThomas Veerman return;
25904a17663cSThomas Veerman
25914a17663cSThomas Veerman case '\'':
25924a17663cSThomas Veerman case '"':
25934a17663cSThomas Veerman {
2594*0a6a1f1dSLionel Sambuc char *s = copy_string(c);
2595*0a6a1f1dSLionel Sambuc fputs(s, f);
2596*0a6a1f1dSLionel Sambuc free(s);
2597*0a6a1f1dSLionel Sambuc }
2598*0a6a1f1dSLionel Sambuc goto loop;
25994a17663cSThomas Veerman
2600*0a6a1f1dSLionel Sambuc case '/':
2601*0a6a1f1dSLionel Sambuc {
2602*0a6a1f1dSLionel Sambuc char *s = copy_comment();
2603*0a6a1f1dSLionel Sambuc fputs(s, f);
2604*0a6a1f1dSLionel Sambuc free(s);
2605*0a6a1f1dSLionel Sambuc }
2606*0a6a1f1dSLionel Sambuc goto loop;
2607*0a6a1f1dSLionel Sambuc
2608*0a6a1f1dSLionel Sambuc default:
2609*0a6a1f1dSLionel Sambuc goto loop;
2610*0a6a1f1dSLionel Sambuc }
2611*0a6a1f1dSLionel Sambuc }
2612*0a6a1f1dSLionel Sambuc
2613*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2614*0a6a1f1dSLionel Sambuc static char *
get_code(struct ainfo * a,const char * loc)2615*0a6a1f1dSLionel Sambuc get_code(struct ainfo *a, const char *loc)
2616*0a6a1f1dSLionel Sambuc {
2617*0a6a1f1dSLionel Sambuc int c;
2618*0a6a1f1dSLionel Sambuc int depth;
2619*0a6a1f1dSLionel Sambuc char *tag;
2620*0a6a1f1dSLionel Sambuc struct mstring *code_mstr = msnew();
2621*0a6a1f1dSLionel Sambuc
2622*0a6a1f1dSLionel Sambuc if (!lflag)
2623*0a6a1f1dSLionel Sambuc msprintf(code_mstr, line_format, lineno, input_file_name);
2624*0a6a1f1dSLionel Sambuc
2625*0a6a1f1dSLionel Sambuc cptr = after_blanks(cptr);
2626*0a6a1f1dSLionel Sambuc if (*cptr == L_CURL)
2627*0a6a1f1dSLionel Sambuc /* avoid putting curly-braces in first column, to ease editing */
2628*0a6a1f1dSLionel Sambuc mputc(code_mstr, '\t');
2629*0a6a1f1dSLionel Sambuc else
2630*0a6a1f1dSLionel Sambuc syntax_error(lineno, line, cptr);
2631*0a6a1f1dSLionel Sambuc
2632*0a6a1f1dSLionel Sambuc a->a_lineno = lineno;
2633*0a6a1f1dSLionel Sambuc a->a_line = dup_line();
2634*0a6a1f1dSLionel Sambuc a->a_cptr = a->a_line + (cptr - line);
2635*0a6a1f1dSLionel Sambuc
2636*0a6a1f1dSLionel Sambuc depth = 0;
2637*0a6a1f1dSLionel Sambuc loop:
2638*0a6a1f1dSLionel Sambuc c = *cptr;
2639*0a6a1f1dSLionel Sambuc if (c == '$')
2640*0a6a1f1dSLionel Sambuc {
2641*0a6a1f1dSLionel Sambuc if (cptr[1] == '<')
2642*0a6a1f1dSLionel Sambuc {
2643*0a6a1f1dSLionel Sambuc int d_lineno = lineno;
2644*0a6a1f1dSLionel Sambuc char *d_line = dup_line();
2645*0a6a1f1dSLionel Sambuc char *d_cptr = d_line + (cptr - line);
2646*0a6a1f1dSLionel Sambuc
2647*0a6a1f1dSLionel Sambuc ++cptr;
2648*0a6a1f1dSLionel Sambuc tag = get_tag();
2649*0a6a1f1dSLionel Sambuc c = *cptr;
2650*0a6a1f1dSLionel Sambuc if (c == '$')
2651*0a6a1f1dSLionel Sambuc {
2652*0a6a1f1dSLionel Sambuc msprintf(code_mstr, "(*val).%s", tag);
2653*0a6a1f1dSLionel Sambuc ++cptr;
2654*0a6a1f1dSLionel Sambuc FREE(d_line);
2655*0a6a1f1dSLionel Sambuc goto loop;
2656*0a6a1f1dSLionel Sambuc }
2657*0a6a1f1dSLionel Sambuc else
2658*0a6a1f1dSLionel Sambuc dollar_error(d_lineno, d_line, d_cptr);
2659*0a6a1f1dSLionel Sambuc }
2660*0a6a1f1dSLionel Sambuc else if (cptr[1] == '$')
2661*0a6a1f1dSLionel Sambuc {
2662*0a6a1f1dSLionel Sambuc /* process '$$' later; replacement is context dependent */
2663*0a6a1f1dSLionel Sambuc msprintf(code_mstr, "$$");
2664*0a6a1f1dSLionel Sambuc cptr += 2;
2665*0a6a1f1dSLionel Sambuc goto loop;
2666*0a6a1f1dSLionel Sambuc }
2667*0a6a1f1dSLionel Sambuc }
2668*0a6a1f1dSLionel Sambuc if (c == '@' && cptr[1] == '$')
2669*0a6a1f1dSLionel Sambuc {
2670*0a6a1f1dSLionel Sambuc if (!locations)
2671*0a6a1f1dSLionel Sambuc {
2672*0a6a1f1dSLionel Sambuc int l_lineno = lineno;
2673*0a6a1f1dSLionel Sambuc char *l_line = dup_line();
2674*0a6a1f1dSLionel Sambuc char *l_cptr = l_line + (cptr - line);
2675*0a6a1f1dSLionel Sambuc syntax_error(l_lineno, l_line, l_cptr);
2676*0a6a1f1dSLionel Sambuc }
2677*0a6a1f1dSLionel Sambuc msprintf(code_mstr, "%s", loc);
2678*0a6a1f1dSLionel Sambuc cptr += 2;
2679*0a6a1f1dSLionel Sambuc goto loop;
2680*0a6a1f1dSLionel Sambuc }
2681*0a6a1f1dSLionel Sambuc if (isalpha(c) || c == '_' || c == '$')
2682*0a6a1f1dSLionel Sambuc {
2683*0a6a1f1dSLionel Sambuc do
2684*0a6a1f1dSLionel Sambuc {
2685*0a6a1f1dSLionel Sambuc mputc(code_mstr, c);
2686*0a6a1f1dSLionel Sambuc c = *++cptr;
2687*0a6a1f1dSLionel Sambuc }
2688*0a6a1f1dSLionel Sambuc while (isalnum(c) || c == '_' || c == '$');
2689*0a6a1f1dSLionel Sambuc goto loop;
2690*0a6a1f1dSLionel Sambuc }
2691*0a6a1f1dSLionel Sambuc ++cptr;
2692*0a6a1f1dSLionel Sambuc mputc(code_mstr, c);
2693*0a6a1f1dSLionel Sambuc switch (c)
2694*0a6a1f1dSLionel Sambuc {
2695*0a6a1f1dSLionel Sambuc case '\n':
2696*0a6a1f1dSLionel Sambuc get_line();
2697*0a6a1f1dSLionel Sambuc if (line)
2698*0a6a1f1dSLionel Sambuc goto loop;
2699*0a6a1f1dSLionel Sambuc unterminated_action(a);
2700*0a6a1f1dSLionel Sambuc
2701*0a6a1f1dSLionel Sambuc case L_CURL:
2702*0a6a1f1dSLionel Sambuc ++depth;
2703*0a6a1f1dSLionel Sambuc goto loop;
2704*0a6a1f1dSLionel Sambuc
2705*0a6a1f1dSLionel Sambuc case R_CURL:
2706*0a6a1f1dSLionel Sambuc if (--depth > 0)
2707*0a6a1f1dSLionel Sambuc goto loop;
2708*0a6a1f1dSLionel Sambuc goto out;
2709*0a6a1f1dSLionel Sambuc
2710*0a6a1f1dSLionel Sambuc case '\'':
2711*0a6a1f1dSLionel Sambuc case '"':
2712*0a6a1f1dSLionel Sambuc {
2713*0a6a1f1dSLionel Sambuc char *s = copy_string(c);
2714*0a6a1f1dSLionel Sambuc msprintf(code_mstr, "%s", s);
2715*0a6a1f1dSLionel Sambuc free(s);
2716*0a6a1f1dSLionel Sambuc }
2717*0a6a1f1dSLionel Sambuc goto loop;
2718*0a6a1f1dSLionel Sambuc
2719*0a6a1f1dSLionel Sambuc case '/':
2720*0a6a1f1dSLionel Sambuc {
2721*0a6a1f1dSLionel Sambuc char *s = copy_comment();
2722*0a6a1f1dSLionel Sambuc msprintf(code_mstr, "%s", s);
2723*0a6a1f1dSLionel Sambuc free(s);
2724*0a6a1f1dSLionel Sambuc }
2725*0a6a1f1dSLionel Sambuc goto loop;
2726*0a6a1f1dSLionel Sambuc
2727*0a6a1f1dSLionel Sambuc default:
2728*0a6a1f1dSLionel Sambuc goto loop;
2729*0a6a1f1dSLionel Sambuc }
2730*0a6a1f1dSLionel Sambuc out:
2731*0a6a1f1dSLionel Sambuc return msdone(code_mstr);
2732*0a6a1f1dSLionel Sambuc }
2733*0a6a1f1dSLionel Sambuc
2734*0a6a1f1dSLionel Sambuc static void
copy_initial_action(void)2735*0a6a1f1dSLionel Sambuc copy_initial_action(void)
2736*0a6a1f1dSLionel Sambuc {
2737*0a6a1f1dSLionel Sambuc struct ainfo a;
2738*0a6a1f1dSLionel Sambuc
2739*0a6a1f1dSLionel Sambuc initial_action = get_code(&a, "yyloc");
2740*0a6a1f1dSLionel Sambuc free(a.a_line);
2741*0a6a1f1dSLionel Sambuc }
2742*0a6a1f1dSLionel Sambuc
2743*0a6a1f1dSLionel Sambuc static void
copy_destructor(void)2744*0a6a1f1dSLionel Sambuc copy_destructor(void)
2745*0a6a1f1dSLionel Sambuc {
2746*0a6a1f1dSLionel Sambuc char *code_text;
2747*0a6a1f1dSLionel Sambuc int c;
2748*0a6a1f1dSLionel Sambuc struct ainfo a;
2749*0a6a1f1dSLionel Sambuc bucket *bp;
2750*0a6a1f1dSLionel Sambuc
2751*0a6a1f1dSLionel Sambuc code_text = get_code(&a, "(*loc)");
2752*0a6a1f1dSLionel Sambuc
2753*0a6a1f1dSLionel Sambuc for (;;)
2754*0a6a1f1dSLionel Sambuc {
2755*0a6a1f1dSLionel Sambuc c = nextc();
2756*0a6a1f1dSLionel Sambuc if (c == EOF)
2757*0a6a1f1dSLionel Sambuc unexpected_EOF();
2758*0a6a1f1dSLionel Sambuc if (c == '<')
2759*0a6a1f1dSLionel Sambuc {
2760*0a6a1f1dSLionel Sambuc if (cptr[1] == '>')
2761*0a6a1f1dSLionel Sambuc { /* "no semantic type" default destructor */
2762*0a6a1f1dSLionel Sambuc cptr += 2;
2763*0a6a1f1dSLionel Sambuc if ((bp = default_destructor[UNTYPED_DEFAULT]) == NULL)
2764*0a6a1f1dSLionel Sambuc {
2765*0a6a1f1dSLionel Sambuc static char untyped_default[] = "<>";
2766*0a6a1f1dSLionel Sambuc bp = make_bucket("untyped default");
2767*0a6a1f1dSLionel Sambuc bp->tag = untyped_default;
2768*0a6a1f1dSLionel Sambuc default_destructor[UNTYPED_DEFAULT] = bp;
2769*0a6a1f1dSLionel Sambuc }
2770*0a6a1f1dSLionel Sambuc if (bp->destructor != NULL)
2771*0a6a1f1dSLionel Sambuc destructor_redeclared_warning(&a);
2772*0a6a1f1dSLionel Sambuc else
2773*0a6a1f1dSLionel Sambuc /* replace "$$" with "(*val)" in destructor code */
2774*0a6a1f1dSLionel Sambuc bp->destructor = process_destructor_XX(code_text, NULL);
2775*0a6a1f1dSLionel Sambuc }
2776*0a6a1f1dSLionel Sambuc else if (cptr[1] == '*' && cptr[2] == '>')
2777*0a6a1f1dSLionel Sambuc { /* "no per-symbol or per-type" default destructor */
2778*0a6a1f1dSLionel Sambuc cptr += 3;
2779*0a6a1f1dSLionel Sambuc if ((bp = default_destructor[TYPED_DEFAULT]) == NULL)
2780*0a6a1f1dSLionel Sambuc {
2781*0a6a1f1dSLionel Sambuc static char typed_default[] = "<*>";
2782*0a6a1f1dSLionel Sambuc bp = make_bucket("typed default");
2783*0a6a1f1dSLionel Sambuc bp->tag = typed_default;
2784*0a6a1f1dSLionel Sambuc default_destructor[TYPED_DEFAULT] = bp;
2785*0a6a1f1dSLionel Sambuc }
2786*0a6a1f1dSLionel Sambuc if (bp->destructor != NULL)
2787*0a6a1f1dSLionel Sambuc destructor_redeclared_warning(&a);
2788*0a6a1f1dSLionel Sambuc else
2789*0a6a1f1dSLionel Sambuc {
2790*0a6a1f1dSLionel Sambuc /* postpone re-processing destructor $$s until end of grammar spec */
2791*0a6a1f1dSLionel Sambuc bp->destructor = TMALLOC(char, strlen(code_text) + 1);
2792*0a6a1f1dSLionel Sambuc NO_SPACE(bp->destructor);
2793*0a6a1f1dSLionel Sambuc strcpy(bp->destructor, code_text);
2794*0a6a1f1dSLionel Sambuc }
2795*0a6a1f1dSLionel Sambuc }
2796*0a6a1f1dSLionel Sambuc else
2797*0a6a1f1dSLionel Sambuc { /* "semantic type" default destructor */
2798*0a6a1f1dSLionel Sambuc char *tag = get_tag();
2799*0a6a1f1dSLionel Sambuc bp = lookup_type_destructor(tag);
2800*0a6a1f1dSLionel Sambuc if (bp->destructor != NULL)
2801*0a6a1f1dSLionel Sambuc destructor_redeclared_warning(&a);
2802*0a6a1f1dSLionel Sambuc else
2803*0a6a1f1dSLionel Sambuc /* replace "$$" with "(*val).tag" in destructor code */
2804*0a6a1f1dSLionel Sambuc bp->destructor = process_destructor_XX(code_text, tag);
2805*0a6a1f1dSLionel Sambuc }
2806*0a6a1f1dSLionel Sambuc }
2807*0a6a1f1dSLionel Sambuc else if (isalpha(c) || c == '_' || c == '.' || c == '$')
2808*0a6a1f1dSLionel Sambuc { /* "symbol" destructor */
2809*0a6a1f1dSLionel Sambuc bp = get_name();
2810*0a6a1f1dSLionel Sambuc if (bp->destructor != NULL)
2811*0a6a1f1dSLionel Sambuc destructor_redeclared_warning(&a);
2812*0a6a1f1dSLionel Sambuc else
2813*0a6a1f1dSLionel Sambuc {
2814*0a6a1f1dSLionel Sambuc /* postpone re-processing destructor $$s until end of grammar spec */
2815*0a6a1f1dSLionel Sambuc bp->destructor = TMALLOC(char, strlen(code_text) + 1);
2816*0a6a1f1dSLionel Sambuc NO_SPACE(bp->destructor);
2817*0a6a1f1dSLionel Sambuc strcpy(bp->destructor, code_text);
2818*0a6a1f1dSLionel Sambuc }
2819*0a6a1f1dSLionel Sambuc }
2820*0a6a1f1dSLionel Sambuc else
2821*0a6a1f1dSLionel Sambuc break;
2822*0a6a1f1dSLionel Sambuc }
2823*0a6a1f1dSLionel Sambuc free(a.a_line);
2824*0a6a1f1dSLionel Sambuc free(code_text);
2825*0a6a1f1dSLionel Sambuc }
2826*0a6a1f1dSLionel Sambuc
2827*0a6a1f1dSLionel Sambuc static char *
process_destructor_XX(char * code,char * tag)2828*0a6a1f1dSLionel Sambuc process_destructor_XX(char *code, char *tag)
2829*0a6a1f1dSLionel Sambuc {
2830*0a6a1f1dSLionel Sambuc int c;
2831*0a6a1f1dSLionel Sambuc int quote;
2832*0a6a1f1dSLionel Sambuc int depth;
2833*0a6a1f1dSLionel Sambuc struct mstring *new_code = msnew();
2834*0a6a1f1dSLionel Sambuc char *codeptr = code;
2835*0a6a1f1dSLionel Sambuc
2836*0a6a1f1dSLionel Sambuc depth = 0;
2837*0a6a1f1dSLionel Sambuc loop: /* step thru code */
2838*0a6a1f1dSLionel Sambuc c = *codeptr;
2839*0a6a1f1dSLionel Sambuc if (c == '$' && codeptr[1] == '$')
2840*0a6a1f1dSLionel Sambuc {
2841*0a6a1f1dSLionel Sambuc codeptr += 2;
2842*0a6a1f1dSLionel Sambuc if (tag == NULL)
2843*0a6a1f1dSLionel Sambuc msprintf(new_code, "(*val)");
2844*0a6a1f1dSLionel Sambuc else
2845*0a6a1f1dSLionel Sambuc msprintf(new_code, "(*val).%s", tag);
2846*0a6a1f1dSLionel Sambuc goto loop;
2847*0a6a1f1dSLionel Sambuc }
2848*0a6a1f1dSLionel Sambuc if (isalpha(c) || c == '_' || c == '$')
2849*0a6a1f1dSLionel Sambuc {
2850*0a6a1f1dSLionel Sambuc do
2851*0a6a1f1dSLionel Sambuc {
2852*0a6a1f1dSLionel Sambuc mputc(new_code, c);
2853*0a6a1f1dSLionel Sambuc c = *++codeptr;
2854*0a6a1f1dSLionel Sambuc }
2855*0a6a1f1dSLionel Sambuc while (isalnum(c) || c == '_' || c == '$');
2856*0a6a1f1dSLionel Sambuc goto loop;
2857*0a6a1f1dSLionel Sambuc }
2858*0a6a1f1dSLionel Sambuc ++codeptr;
2859*0a6a1f1dSLionel Sambuc mputc(new_code, c);
2860*0a6a1f1dSLionel Sambuc switch (c)
2861*0a6a1f1dSLionel Sambuc {
2862*0a6a1f1dSLionel Sambuc case L_CURL:
2863*0a6a1f1dSLionel Sambuc ++depth;
2864*0a6a1f1dSLionel Sambuc goto loop;
2865*0a6a1f1dSLionel Sambuc
2866*0a6a1f1dSLionel Sambuc case R_CURL:
2867*0a6a1f1dSLionel Sambuc if (--depth > 0)
2868*0a6a1f1dSLionel Sambuc goto loop;
2869*0a6a1f1dSLionel Sambuc return msdone(new_code);
2870*0a6a1f1dSLionel Sambuc
2871*0a6a1f1dSLionel Sambuc case '\'':
2872*0a6a1f1dSLionel Sambuc case '"':
28734a17663cSThomas Veerman quote = c;
28744a17663cSThomas Veerman for (;;)
28754a17663cSThomas Veerman {
2876*0a6a1f1dSLionel Sambuc c = *codeptr++;
2877*0a6a1f1dSLionel Sambuc mputc(new_code, c);
28784a17663cSThomas Veerman if (c == quote)
28794a17663cSThomas Veerman goto loop;
28804a17663cSThomas Veerman if (c == '\\')
28814a17663cSThomas Veerman {
2882*0a6a1f1dSLionel Sambuc c = *codeptr++;
2883*0a6a1f1dSLionel Sambuc mputc(new_code, c);
28844a17663cSThomas Veerman }
28854a17663cSThomas Veerman }
28864a17663cSThomas Veerman
28874a17663cSThomas Veerman case '/':
2888*0a6a1f1dSLionel Sambuc c = *codeptr;
28894a17663cSThomas Veerman if (c == '*')
28904a17663cSThomas Veerman {
2891*0a6a1f1dSLionel Sambuc mputc(new_code, c);
2892*0a6a1f1dSLionel Sambuc ++codeptr;
28934a17663cSThomas Veerman for (;;)
28944a17663cSThomas Veerman {
2895*0a6a1f1dSLionel Sambuc c = *codeptr++;
2896*0a6a1f1dSLionel Sambuc mputc(new_code, c);
2897*0a6a1f1dSLionel Sambuc if (c == '*' && *codeptr == '/')
28984a17663cSThomas Veerman {
2899*0a6a1f1dSLionel Sambuc mputc(new_code, '/');
2900*0a6a1f1dSLionel Sambuc ++codeptr;
29014a17663cSThomas Veerman goto loop;
29024a17663cSThomas Veerman }
29034a17663cSThomas Veerman }
29044a17663cSThomas Veerman }
29054a17663cSThomas Veerman goto loop;
29064a17663cSThomas Veerman
29074a17663cSThomas Veerman default:
29084a17663cSThomas Veerman goto loop;
29094a17663cSThomas Veerman }
29104a17663cSThomas Veerman }
2911*0a6a1f1dSLionel Sambuc #endif /* defined(YYBTYACC) */
29124a17663cSThomas Veerman
29134a17663cSThomas Veerman static int
mark_symbol(void)29144a17663cSThomas Veerman mark_symbol(void)
29154a17663cSThomas Veerman {
29164a17663cSThomas Veerman int c;
291784d9c625SLionel Sambuc bucket *bp = NULL;
29184a17663cSThomas Veerman
29194a17663cSThomas Veerman c = cptr[1];
29204a17663cSThomas Veerman if (c == '%' || c == '\\')
29214a17663cSThomas Veerman {
29224a17663cSThomas Veerman cptr += 2;
29234a17663cSThomas Veerman return (1);
29244a17663cSThomas Veerman }
29254a17663cSThomas Veerman
29264a17663cSThomas Veerman if (c == '=')
29274a17663cSThomas Veerman cptr += 2;
29284a17663cSThomas Veerman else if ((c == 'p' || c == 'P') &&
29294a17663cSThomas Veerman ((c = cptr[2]) == 'r' || c == 'R') &&
29304a17663cSThomas Veerman ((c = cptr[3]) == 'e' || c == 'E') &&
29314a17663cSThomas Veerman ((c = cptr[4]) == 'c' || c == 'C') &&
29324a17663cSThomas Veerman ((c = cptr[5], !IS_IDENT(c))))
29334a17663cSThomas Veerman cptr += 5;
29344a17663cSThomas Veerman else
29354a17663cSThomas Veerman syntax_error(lineno, line, cptr);
29364a17663cSThomas Veerman
29374a17663cSThomas Veerman c = nextc();
29384a17663cSThomas Veerman if (isalpha(c) || c == '_' || c == '.' || c == '$')
29394a17663cSThomas Veerman bp = get_name();
29404a17663cSThomas Veerman else if (c == '\'' || c == '"')
29414a17663cSThomas Veerman bp = get_literal();
29424a17663cSThomas Veerman else
29434a17663cSThomas Veerman {
29444a17663cSThomas Veerman syntax_error(lineno, line, cptr);
29454a17663cSThomas Veerman }
29464a17663cSThomas Veerman
29474a17663cSThomas Veerman if (rprec[nrules] != UNDEFINED && bp->prec != rprec[nrules])
29484a17663cSThomas Veerman prec_redeclared();
29494a17663cSThomas Veerman
29504a17663cSThomas Veerman rprec[nrules] = bp->prec;
29514a17663cSThomas Veerman rassoc[nrules] = bp->assoc;
29524a17663cSThomas Veerman return (0);
29534a17663cSThomas Veerman }
29544a17663cSThomas Veerman
29554a17663cSThomas Veerman static void
read_grammar(void)29564a17663cSThomas Veerman read_grammar(void)
29574a17663cSThomas Veerman {
29584a17663cSThomas Veerman int c;
29594a17663cSThomas Veerman
29604a17663cSThomas Veerman initialize_grammar();
29614a17663cSThomas Veerman advance_to_start();
29624a17663cSThomas Veerman
29634a17663cSThomas Veerman for (;;)
29644a17663cSThomas Veerman {
29654a17663cSThomas Veerman c = nextc();
29664a17663cSThomas Veerman if (c == EOF)
29674a17663cSThomas Veerman break;
29684a17663cSThomas Veerman if (isalpha(c)
29694a17663cSThomas Veerman || c == '_'
29704a17663cSThomas Veerman || c == '.'
29714a17663cSThomas Veerman || c == '$'
29724a17663cSThomas Veerman || c == '\''
29734a17663cSThomas Veerman || c == '"')
29744a17663cSThomas Veerman add_symbol();
2975*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2976*0a6a1f1dSLionel Sambuc else if (c == L_CURL || c == '=' || (backtrack && c == L_BRAC))
2977*0a6a1f1dSLionel Sambuc #else
29784a17663cSThomas Veerman else if (c == L_CURL || c == '=')
2979*0a6a1f1dSLionel Sambuc #endif
29804a17663cSThomas Veerman copy_action();
29814a17663cSThomas Veerman else if (c == '|')
29824a17663cSThomas Veerman {
29834a17663cSThomas Veerman end_rule();
29844a17663cSThomas Veerman start_rule(plhs[nrules - 1], 0);
29854a17663cSThomas Veerman ++cptr;
29864a17663cSThomas Veerman }
29874a17663cSThomas Veerman else if (c == '%')
29884a17663cSThomas Veerman {
29894a17663cSThomas Veerman if (mark_symbol())
29904a17663cSThomas Veerman break;
29914a17663cSThomas Veerman }
29924a17663cSThomas Veerman else
29934a17663cSThomas Veerman syntax_error(lineno, line, cptr);
29944a17663cSThomas Veerman }
29954a17663cSThomas Veerman end_rule();
2996*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
2997*0a6a1f1dSLionel Sambuc if (goal->args > 0)
2998*0a6a1f1dSLionel Sambuc start_requires_args(goal->name);
2999*0a6a1f1dSLionel Sambuc #endif
30004a17663cSThomas Veerman }
30014a17663cSThomas Veerman
30024a17663cSThomas Veerman static void
free_tags(void)30034a17663cSThomas Veerman free_tags(void)
30044a17663cSThomas Veerman {
30054a17663cSThomas Veerman int i;
30064a17663cSThomas Veerman
30074a17663cSThomas Veerman if (tag_table == 0)
30084a17663cSThomas Veerman return;
30094a17663cSThomas Veerman
30104a17663cSThomas Veerman for (i = 0; i < ntags; ++i)
30114a17663cSThomas Veerman {
30124a17663cSThomas Veerman assert(tag_table[i]);
30134a17663cSThomas Veerman FREE(tag_table[i]);
30144a17663cSThomas Veerman }
30154a17663cSThomas Veerman FREE(tag_table);
30164a17663cSThomas Veerman }
30174a17663cSThomas Veerman
30184a17663cSThomas Veerman static void
pack_names(void)30194a17663cSThomas Veerman pack_names(void)
30204a17663cSThomas Veerman {
30214a17663cSThomas Veerman bucket *bp;
30224a17663cSThomas Veerman char *p, *s, *t;
30234a17663cSThomas Veerman
30244a17663cSThomas Veerman name_pool_size = 13; /* 13 == sizeof("$end") + sizeof("$accept") */
30254a17663cSThomas Veerman for (bp = first_symbol; bp; bp = bp->next)
30264a17663cSThomas Veerman name_pool_size += strlen(bp->name) + 1;
30274a17663cSThomas Veerman
302884d9c625SLionel Sambuc name_pool = TMALLOC(char, name_pool_size);
30294a17663cSThomas Veerman NO_SPACE(name_pool);
30304a17663cSThomas Veerman
30314a17663cSThomas Veerman strlcpy(name_pool, "$accept", name_pool_size);
30324a17663cSThomas Veerman strlcpy(name_pool + 8, "$end", name_pool_size - 8);
30334a17663cSThomas Veerman t = name_pool + 13;
30344a17663cSThomas Veerman for (bp = first_symbol; bp; bp = bp->next)
30354a17663cSThomas Veerman {
30364a17663cSThomas Veerman p = t;
30374a17663cSThomas Veerman s = bp->name;
30384a17663cSThomas Veerman while ((*t++ = *s++) != 0)
30394a17663cSThomas Veerman continue;
30404a17663cSThomas Veerman FREE(bp->name);
30414a17663cSThomas Veerman bp->name = p;
30424a17663cSThomas Veerman }
30434a17663cSThomas Veerman }
30444a17663cSThomas Veerman
30454a17663cSThomas Veerman static void
check_symbols(void)30464a17663cSThomas Veerman check_symbols(void)
30474a17663cSThomas Veerman {
30484a17663cSThomas Veerman bucket *bp;
30494a17663cSThomas Veerman
30504a17663cSThomas Veerman if (goal->class == UNKNOWN)
30514a17663cSThomas Veerman undefined_goal(goal->name);
30524a17663cSThomas Veerman
30534a17663cSThomas Veerman for (bp = first_symbol; bp; bp = bp->next)
30544a17663cSThomas Veerman {
30554a17663cSThomas Veerman if (bp->class == UNKNOWN)
30564a17663cSThomas Veerman {
30574a17663cSThomas Veerman undefined_symbol_warning(bp->name);
30584a17663cSThomas Veerman bp->class = TERM;
30594a17663cSThomas Veerman }
30604a17663cSThomas Veerman }
30614a17663cSThomas Veerman }
30624a17663cSThomas Veerman
30634a17663cSThomas Veerman static void
protect_string(char * src,char ** des)30644a17663cSThomas Veerman protect_string(char *src, char **des)
30654a17663cSThomas Veerman {
30664a17663cSThomas Veerman unsigned len;
30674a17663cSThomas Veerman char *s;
30684a17663cSThomas Veerman char *d;
30694a17663cSThomas Veerman
30704a17663cSThomas Veerman *des = src;
30714a17663cSThomas Veerman if (src)
30724a17663cSThomas Veerman {
30734a17663cSThomas Veerman len = 1;
30744a17663cSThomas Veerman s = src;
30754a17663cSThomas Veerman while (*s)
30764a17663cSThomas Veerman {
30774a17663cSThomas Veerman if ('\\' == *s || '"' == *s)
30784a17663cSThomas Veerman len++;
30794a17663cSThomas Veerman s++;
30804a17663cSThomas Veerman len++;
30814a17663cSThomas Veerman }
30824a17663cSThomas Veerman
308384d9c625SLionel Sambuc *des = d = TMALLOC(char, len);
30844a17663cSThomas Veerman NO_SPACE(d);
30854a17663cSThomas Veerman
30864a17663cSThomas Veerman s = src;
30874a17663cSThomas Veerman while (*s)
30884a17663cSThomas Veerman {
30894a17663cSThomas Veerman if ('\\' == *s || '"' == *s)
30904a17663cSThomas Veerman *d++ = '\\';
30914a17663cSThomas Veerman *d++ = *s++;
30924a17663cSThomas Veerman }
30934a17663cSThomas Veerman *d = '\0';
30944a17663cSThomas Veerman }
30954a17663cSThomas Veerman }
30964a17663cSThomas Veerman
30974a17663cSThomas Veerman static void
pack_symbols(void)30984a17663cSThomas Veerman pack_symbols(void)
30994a17663cSThomas Veerman {
31004a17663cSThomas Veerman bucket *bp;
31014a17663cSThomas Veerman bucket **v;
31024a17663cSThomas Veerman Value_t i, j, k, n;
3103*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
3104*0a6a1f1dSLionel Sambuc Value_t max_tok_pval;
3105*0a6a1f1dSLionel Sambuc #endif
31064a17663cSThomas Veerman
31074a17663cSThomas Veerman nsyms = 2;
31084a17663cSThomas Veerman ntokens = 1;
31094a17663cSThomas Veerman for (bp = first_symbol; bp; bp = bp->next)
31104a17663cSThomas Veerman {
31114a17663cSThomas Veerman ++nsyms;
31124a17663cSThomas Veerman if (bp->class == TERM)
31134a17663cSThomas Veerman ++ntokens;
31144a17663cSThomas Veerman }
31154a17663cSThomas Veerman start_symbol = (Value_t) ntokens;
3116*0a6a1f1dSLionel Sambuc nvars = (Value_t) (nsyms - ntokens);
31174a17663cSThomas Veerman
311884d9c625SLionel Sambuc symbol_name = TMALLOC(char *, nsyms);
31194a17663cSThomas Veerman NO_SPACE(symbol_name);
31204a17663cSThomas Veerman
312184d9c625SLionel Sambuc symbol_value = TMALLOC(Value_t, nsyms);
31224a17663cSThomas Veerman NO_SPACE(symbol_value);
31234a17663cSThomas Veerman
3124*0a6a1f1dSLionel Sambuc symbol_prec = TMALLOC(Value_t, nsyms);
31254a17663cSThomas Veerman NO_SPACE(symbol_prec);
31264a17663cSThomas Veerman
312784d9c625SLionel Sambuc symbol_assoc = TMALLOC(char, nsyms);
31284a17663cSThomas Veerman NO_SPACE(symbol_assoc);
31294a17663cSThomas Veerman
3130*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
3131*0a6a1f1dSLionel Sambuc symbol_pval = TMALLOC(Value_t, nsyms);
3132*0a6a1f1dSLionel Sambuc NO_SPACE(symbol_pval);
3133*0a6a1f1dSLionel Sambuc
3134*0a6a1f1dSLionel Sambuc if (destructor)
3135*0a6a1f1dSLionel Sambuc {
3136*0a6a1f1dSLionel Sambuc symbol_destructor = CALLOC(sizeof(char *), nsyms);
3137*0a6a1f1dSLionel Sambuc NO_SPACE(symbol_destructor);
3138*0a6a1f1dSLionel Sambuc
3139*0a6a1f1dSLionel Sambuc symbol_type_tag = CALLOC(sizeof(char *), nsyms);
3140*0a6a1f1dSLionel Sambuc NO_SPACE(symbol_type_tag);
3141*0a6a1f1dSLionel Sambuc }
3142*0a6a1f1dSLionel Sambuc #endif
3143*0a6a1f1dSLionel Sambuc
314484d9c625SLionel Sambuc v = TMALLOC(bucket *, nsyms);
31454a17663cSThomas Veerman NO_SPACE(v);
31464a17663cSThomas Veerman
31474a17663cSThomas Veerman v[0] = 0;
31484a17663cSThomas Veerman v[start_symbol] = 0;
31494a17663cSThomas Veerman
31504a17663cSThomas Veerman i = 1;
31514a17663cSThomas Veerman j = (Value_t) (start_symbol + 1);
31524a17663cSThomas Veerman for (bp = first_symbol; bp; bp = bp->next)
31534a17663cSThomas Veerman {
31544a17663cSThomas Veerman if (bp->class == TERM)
31554a17663cSThomas Veerman v[i++] = bp;
31564a17663cSThomas Veerman else
31574a17663cSThomas Veerman v[j++] = bp;
31584a17663cSThomas Veerman }
31594a17663cSThomas Veerman assert(i == ntokens && j == nsyms);
31604a17663cSThomas Veerman
31614a17663cSThomas Veerman for (i = 1; i < ntokens; ++i)
31624a17663cSThomas Veerman v[i]->index = i;
31634a17663cSThomas Veerman
31644a17663cSThomas Veerman goal->index = (Index_t) (start_symbol + 1);
31654a17663cSThomas Veerman k = (Value_t) (start_symbol + 2);
31664a17663cSThomas Veerman while (++i < nsyms)
31674a17663cSThomas Veerman if (v[i] != goal)
31684a17663cSThomas Veerman {
31694a17663cSThomas Veerman v[i]->index = k;
31704a17663cSThomas Veerman ++k;
31714a17663cSThomas Veerman }
31724a17663cSThomas Veerman
31734a17663cSThomas Veerman goal->value = 0;
31744a17663cSThomas Veerman k = 1;
31754a17663cSThomas Veerman for (i = (Value_t) (start_symbol + 1); i < nsyms; ++i)
31764a17663cSThomas Veerman {
31774a17663cSThomas Veerman if (v[i] != goal)
31784a17663cSThomas Veerman {
31794a17663cSThomas Veerman v[i]->value = k;
31804a17663cSThomas Veerman ++k;
31814a17663cSThomas Veerman }
31824a17663cSThomas Veerman }
31834a17663cSThomas Veerman
31844a17663cSThomas Veerman k = 0;
31854a17663cSThomas Veerman for (i = 1; i < ntokens; ++i)
31864a17663cSThomas Veerman {
31874a17663cSThomas Veerman n = v[i]->value;
31884a17663cSThomas Veerman if (n > 256)
31894a17663cSThomas Veerman {
31904a17663cSThomas Veerman for (j = k++; j > 0 && symbol_value[j - 1] > n; --j)
31914a17663cSThomas Veerman symbol_value[j] = symbol_value[j - 1];
31924a17663cSThomas Veerman symbol_value[j] = n;
31934a17663cSThomas Veerman }
31944a17663cSThomas Veerman }
31954a17663cSThomas Veerman
31964a17663cSThomas Veerman assert(v[1] != 0);
31974a17663cSThomas Veerman
31984a17663cSThomas Veerman if (v[1]->value == UNDEFINED)
31994a17663cSThomas Veerman v[1]->value = 256;
32004a17663cSThomas Veerman
32014a17663cSThomas Veerman j = 0;
32024a17663cSThomas Veerman n = 257;
32034a17663cSThomas Veerman for (i = 2; i < ntokens; ++i)
32044a17663cSThomas Veerman {
32054a17663cSThomas Veerman if (v[i]->value == UNDEFINED)
32064a17663cSThomas Veerman {
32074a17663cSThomas Veerman while (j < k && n == symbol_value[j])
32084a17663cSThomas Veerman {
32094a17663cSThomas Veerman while (++j < k && n == symbol_value[j])
32104a17663cSThomas Veerman continue;
32114a17663cSThomas Veerman ++n;
32124a17663cSThomas Veerman }
32134a17663cSThomas Veerman v[i]->value = n;
32144a17663cSThomas Veerman ++n;
32154a17663cSThomas Veerman }
32164a17663cSThomas Veerman }
32174a17663cSThomas Veerman
32184a17663cSThomas Veerman symbol_name[0] = name_pool + 8;
32194a17663cSThomas Veerman symbol_value[0] = 0;
32204a17663cSThomas Veerman symbol_prec[0] = 0;
32214a17663cSThomas Veerman symbol_assoc[0] = TOKEN;
3222*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
3223*0a6a1f1dSLionel Sambuc symbol_pval[0] = 0;
3224*0a6a1f1dSLionel Sambuc max_tok_pval = 0;
3225*0a6a1f1dSLionel Sambuc #endif
32264a17663cSThomas Veerman for (i = 1; i < ntokens; ++i)
32274a17663cSThomas Veerman {
32284a17663cSThomas Veerman symbol_name[i] = v[i]->name;
32294a17663cSThomas Veerman symbol_value[i] = v[i]->value;
32304a17663cSThomas Veerman symbol_prec[i] = v[i]->prec;
32314a17663cSThomas Veerman symbol_assoc[i] = v[i]->assoc;
3232*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
3233*0a6a1f1dSLionel Sambuc symbol_pval[i] = v[i]->value;
3234*0a6a1f1dSLionel Sambuc if (symbol_pval[i] > max_tok_pval)
3235*0a6a1f1dSLionel Sambuc max_tok_pval = symbol_pval[i];
3236*0a6a1f1dSLionel Sambuc if (destructor)
3237*0a6a1f1dSLionel Sambuc {
3238*0a6a1f1dSLionel Sambuc symbol_destructor[i] = v[i]->destructor;
3239*0a6a1f1dSLionel Sambuc symbol_type_tag[i] = v[i]->tag;
3240*0a6a1f1dSLionel Sambuc }
3241*0a6a1f1dSLionel Sambuc #endif
32424a17663cSThomas Veerman }
32434a17663cSThomas Veerman symbol_name[start_symbol] = name_pool;
32444a17663cSThomas Veerman symbol_value[start_symbol] = -1;
32454a17663cSThomas Veerman symbol_prec[start_symbol] = 0;
32464a17663cSThomas Veerman symbol_assoc[start_symbol] = TOKEN;
3247*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
3248*0a6a1f1dSLionel Sambuc symbol_pval[start_symbol] = (Value_t) (max_tok_pval + 1);
3249*0a6a1f1dSLionel Sambuc #endif
32504a17663cSThomas Veerman for (++i; i < nsyms; ++i)
32514a17663cSThomas Veerman {
32524a17663cSThomas Veerman k = v[i]->index;
32534a17663cSThomas Veerman symbol_name[k] = v[i]->name;
32544a17663cSThomas Veerman symbol_value[k] = v[i]->value;
32554a17663cSThomas Veerman symbol_prec[k] = v[i]->prec;
32564a17663cSThomas Veerman symbol_assoc[k] = v[i]->assoc;
3257*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
3258*0a6a1f1dSLionel Sambuc symbol_pval[k] = (Value_t) ((max_tok_pval + 1) + v[i]->value + 1);
3259*0a6a1f1dSLionel Sambuc if (destructor)
3260*0a6a1f1dSLionel Sambuc {
3261*0a6a1f1dSLionel Sambuc symbol_destructor[k] = v[i]->destructor;
3262*0a6a1f1dSLionel Sambuc symbol_type_tag[k] = v[i]->tag;
3263*0a6a1f1dSLionel Sambuc }
3264*0a6a1f1dSLionel Sambuc #endif
32654a17663cSThomas Veerman }
32664a17663cSThomas Veerman
32674a17663cSThomas Veerman if (gflag)
32684a17663cSThomas Veerman {
326984d9c625SLionel Sambuc symbol_pname = TMALLOC(char *, nsyms);
32704a17663cSThomas Veerman NO_SPACE(symbol_pname);
32714a17663cSThomas Veerman
32724a17663cSThomas Veerman for (i = 0; i < nsyms; ++i)
32734a17663cSThomas Veerman protect_string(symbol_name[i], &(symbol_pname[i]));
32744a17663cSThomas Veerman }
32754a17663cSThomas Veerman
32764a17663cSThomas Veerman FREE(v);
32774a17663cSThomas Veerman }
32784a17663cSThomas Veerman
32794a17663cSThomas Veerman static void
pack_grammar(void)32804a17663cSThomas Veerman pack_grammar(void)
32814a17663cSThomas Veerman {
32824a17663cSThomas Veerman int i;
32834a17663cSThomas Veerman Value_t j;
32844a17663cSThomas Veerman Assoc_t assoc;
32854a17663cSThomas Veerman Value_t prec2;
32864a17663cSThomas Veerman
328784d9c625SLionel Sambuc ritem = TMALLOC(Value_t, nitems);
32884a17663cSThomas Veerman NO_SPACE(ritem);
32894a17663cSThomas Veerman
329084d9c625SLionel Sambuc rlhs = TMALLOC(Value_t, nrules);
32914a17663cSThomas Veerman NO_SPACE(rlhs);
32924a17663cSThomas Veerman
329384d9c625SLionel Sambuc rrhs = TMALLOC(Value_t, nrules + 1);
32944a17663cSThomas Veerman NO_SPACE(rrhs);
32954a17663cSThomas Veerman
329684d9c625SLionel Sambuc rprec = TREALLOC(Value_t, rprec, nrules);
32974a17663cSThomas Veerman NO_SPACE(rprec);
32984a17663cSThomas Veerman
329984d9c625SLionel Sambuc rassoc = TREALLOC(Assoc_t, rassoc, nrules);
33004a17663cSThomas Veerman NO_SPACE(rassoc);
33014a17663cSThomas Veerman
33024a17663cSThomas Veerman ritem[0] = -1;
33034a17663cSThomas Veerman ritem[1] = goal->index;
33044a17663cSThomas Veerman ritem[2] = 0;
33054a17663cSThomas Veerman ritem[3] = -2;
33064a17663cSThomas Veerman rlhs[0] = 0;
33074a17663cSThomas Veerman rlhs[1] = 0;
33084a17663cSThomas Veerman rlhs[2] = start_symbol;
33094a17663cSThomas Veerman rrhs[0] = 0;
33104a17663cSThomas Veerman rrhs[1] = 0;
33114a17663cSThomas Veerman rrhs[2] = 1;
33124a17663cSThomas Veerman
33134a17663cSThomas Veerman j = 4;
33144a17663cSThomas Veerman for (i = 3; i < nrules; ++i)
33154a17663cSThomas Veerman {
3316*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
3317*0a6a1f1dSLionel Sambuc if (plhs[i]->args > 0)
3318*0a6a1f1dSLionel Sambuc {
3319*0a6a1f1dSLionel Sambuc if (plhs[i]->argnames)
3320*0a6a1f1dSLionel Sambuc {
3321*0a6a1f1dSLionel Sambuc FREE(plhs[i]->argnames);
3322*0a6a1f1dSLionel Sambuc plhs[i]->argnames = NULL;
3323*0a6a1f1dSLionel Sambuc }
3324*0a6a1f1dSLionel Sambuc if (plhs[i]->argtags)
3325*0a6a1f1dSLionel Sambuc {
3326*0a6a1f1dSLionel Sambuc FREE(plhs[i]->argtags);
3327*0a6a1f1dSLionel Sambuc plhs[i]->argtags = NULL;
3328*0a6a1f1dSLionel Sambuc }
3329*0a6a1f1dSLionel Sambuc }
3330*0a6a1f1dSLionel Sambuc #endif /* defined(YYBTYACC) */
33314a17663cSThomas Veerman rlhs[i] = plhs[i]->index;
33324a17663cSThomas Veerman rrhs[i] = j;
33334a17663cSThomas Veerman assoc = TOKEN;
33344a17663cSThomas Veerman prec2 = 0;
33354a17663cSThomas Veerman while (pitem[j])
33364a17663cSThomas Veerman {
33374a17663cSThomas Veerman ritem[j] = pitem[j]->index;
33384a17663cSThomas Veerman if (pitem[j]->class == TERM)
33394a17663cSThomas Veerman {
33404a17663cSThomas Veerman prec2 = pitem[j]->prec;
33414a17663cSThomas Veerman assoc = pitem[j]->assoc;
33424a17663cSThomas Veerman }
33434a17663cSThomas Veerman ++j;
33444a17663cSThomas Veerman }
33454a17663cSThomas Veerman ritem[j] = (Value_t) - i;
33464a17663cSThomas Veerman ++j;
33474a17663cSThomas Veerman if (rprec[i] == UNDEFINED)
33484a17663cSThomas Veerman {
33494a17663cSThomas Veerman rprec[i] = prec2;
33504a17663cSThomas Veerman rassoc[i] = assoc;
33514a17663cSThomas Veerman }
33524a17663cSThomas Veerman }
33534a17663cSThomas Veerman rrhs[i] = j;
33544a17663cSThomas Veerman
33554a17663cSThomas Veerman FREE(plhs);
33564a17663cSThomas Veerman FREE(pitem);
3357*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
3358*0a6a1f1dSLionel Sambuc clean_arg_cache();
3359*0a6a1f1dSLionel Sambuc #endif
33604a17663cSThomas Veerman }
33614a17663cSThomas Veerman
33624a17663cSThomas Veerman static void
print_grammar(void)33634a17663cSThomas Veerman print_grammar(void)
33644a17663cSThomas Veerman {
33654a17663cSThomas Veerman int i, k;
33664a17663cSThomas Veerman size_t j, spacing = 0;
33674a17663cSThomas Veerman FILE *f = verbose_file;
33684a17663cSThomas Veerman
33694a17663cSThomas Veerman if (!vflag)
33704a17663cSThomas Veerman return;
33714a17663cSThomas Veerman
33724a17663cSThomas Veerman k = 1;
33734a17663cSThomas Veerman for (i = 2; i < nrules; ++i)
33744a17663cSThomas Veerman {
33754a17663cSThomas Veerman if (rlhs[i] != rlhs[i - 1])
33764a17663cSThomas Veerman {
33774a17663cSThomas Veerman if (i != 2)
33784a17663cSThomas Veerman fprintf(f, "\n");
33794a17663cSThomas Veerman fprintf(f, "%4d %s :", i - 2, symbol_name[rlhs[i]]);
33804a17663cSThomas Veerman spacing = strlen(symbol_name[rlhs[i]]) + 1;
33814a17663cSThomas Veerman }
33824a17663cSThomas Veerman else
33834a17663cSThomas Veerman {
33844a17663cSThomas Veerman fprintf(f, "%4d ", i - 2);
33854a17663cSThomas Veerman j = spacing;
33864a17663cSThomas Veerman while (j-- != 0)
33874a17663cSThomas Veerman putc(' ', f);
33884a17663cSThomas Veerman putc('|', f);
33894a17663cSThomas Veerman }
33904a17663cSThomas Veerman
33914a17663cSThomas Veerman while (ritem[k] >= 0)
33924a17663cSThomas Veerman {
33934a17663cSThomas Veerman fprintf(f, " %s", symbol_name[ritem[k]]);
33944a17663cSThomas Veerman ++k;
33954a17663cSThomas Veerman }
33964a17663cSThomas Veerman ++k;
33974a17663cSThomas Veerman putc('\n', f);
33984a17663cSThomas Veerman }
33994a17663cSThomas Veerman }
34004a17663cSThomas Veerman
3401*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
3402*0a6a1f1dSLionel Sambuc static void
finalize_destructors(void)3403*0a6a1f1dSLionel Sambuc finalize_destructors(void)
3404*0a6a1f1dSLionel Sambuc {
3405*0a6a1f1dSLionel Sambuc int i;
3406*0a6a1f1dSLionel Sambuc bucket *bp;
3407*0a6a1f1dSLionel Sambuc char *tag;
3408*0a6a1f1dSLionel Sambuc
3409*0a6a1f1dSLionel Sambuc for (i = 2; i < nsyms; ++i)
3410*0a6a1f1dSLionel Sambuc {
3411*0a6a1f1dSLionel Sambuc tag = symbol_type_tag[i];
3412*0a6a1f1dSLionel Sambuc if (symbol_destructor[i] == NULL)
3413*0a6a1f1dSLionel Sambuc {
3414*0a6a1f1dSLionel Sambuc if (tag == NULL)
3415*0a6a1f1dSLionel Sambuc { /* use <> destructor, if there is one */
3416*0a6a1f1dSLionel Sambuc if ((bp = default_destructor[UNTYPED_DEFAULT]) != NULL)
3417*0a6a1f1dSLionel Sambuc {
3418*0a6a1f1dSLionel Sambuc symbol_destructor[i] = TMALLOC(char,
3419*0a6a1f1dSLionel Sambuc strlen(bp->destructor) + 1);
3420*0a6a1f1dSLionel Sambuc NO_SPACE(symbol_destructor[i]);
3421*0a6a1f1dSLionel Sambuc strcpy(symbol_destructor[i], bp->destructor);
3422*0a6a1f1dSLionel Sambuc }
3423*0a6a1f1dSLionel Sambuc }
3424*0a6a1f1dSLionel Sambuc else
3425*0a6a1f1dSLionel Sambuc { /* use type destructor for this tag, if there is one */
3426*0a6a1f1dSLionel Sambuc bp = lookup_type_destructor(tag);
3427*0a6a1f1dSLionel Sambuc if (bp->destructor != NULL)
3428*0a6a1f1dSLionel Sambuc {
3429*0a6a1f1dSLionel Sambuc symbol_destructor[i] = TMALLOC(char,
3430*0a6a1f1dSLionel Sambuc strlen(bp->destructor) + 1);
3431*0a6a1f1dSLionel Sambuc NO_SPACE(symbol_destructor[i]);
3432*0a6a1f1dSLionel Sambuc strcpy(symbol_destructor[i], bp->destructor);
3433*0a6a1f1dSLionel Sambuc }
3434*0a6a1f1dSLionel Sambuc else
3435*0a6a1f1dSLionel Sambuc { /* use <*> destructor, if there is one */
3436*0a6a1f1dSLionel Sambuc if ((bp = default_destructor[TYPED_DEFAULT]) != NULL)
3437*0a6a1f1dSLionel Sambuc /* replace "$$" with "(*val).tag" in destructor code */
3438*0a6a1f1dSLionel Sambuc symbol_destructor[i]
3439*0a6a1f1dSLionel Sambuc = process_destructor_XX(bp->destructor, tag);
3440*0a6a1f1dSLionel Sambuc }
3441*0a6a1f1dSLionel Sambuc }
3442*0a6a1f1dSLionel Sambuc }
3443*0a6a1f1dSLionel Sambuc else
3444*0a6a1f1dSLionel Sambuc { /* replace "$$" with "(*val)[.tag]" in destructor code */
3445*0a6a1f1dSLionel Sambuc symbol_destructor[i]
3446*0a6a1f1dSLionel Sambuc = process_destructor_XX(symbol_destructor[i], tag);
3447*0a6a1f1dSLionel Sambuc }
3448*0a6a1f1dSLionel Sambuc }
3449*0a6a1f1dSLionel Sambuc /* 'symbol_type_tag[]' elements are freed by 'free_tags()' */
3450*0a6a1f1dSLionel Sambuc DO_FREE(symbol_type_tag); /* no longer needed */
3451*0a6a1f1dSLionel Sambuc if ((bp = default_destructor[UNTYPED_DEFAULT]) != NULL)
3452*0a6a1f1dSLionel Sambuc {
3453*0a6a1f1dSLionel Sambuc FREE(bp->name);
3454*0a6a1f1dSLionel Sambuc /* 'bp->tag' is a static value, don't free */
3455*0a6a1f1dSLionel Sambuc FREE(bp->destructor);
3456*0a6a1f1dSLionel Sambuc FREE(bp);
3457*0a6a1f1dSLionel Sambuc }
3458*0a6a1f1dSLionel Sambuc if ((bp = default_destructor[TYPED_DEFAULT]) != NULL)
3459*0a6a1f1dSLionel Sambuc {
3460*0a6a1f1dSLionel Sambuc FREE(bp->name);
3461*0a6a1f1dSLionel Sambuc /* 'bp->tag' is a static value, don't free */
3462*0a6a1f1dSLionel Sambuc FREE(bp->destructor);
3463*0a6a1f1dSLionel Sambuc FREE(bp);
3464*0a6a1f1dSLionel Sambuc }
3465*0a6a1f1dSLionel Sambuc if ((bp = default_destructor[TYPE_SPECIFIED]) != NULL)
3466*0a6a1f1dSLionel Sambuc {
3467*0a6a1f1dSLionel Sambuc bucket *p;
3468*0a6a1f1dSLionel Sambuc for (; bp; bp = p)
3469*0a6a1f1dSLionel Sambuc {
3470*0a6a1f1dSLionel Sambuc p = bp->link;
3471*0a6a1f1dSLionel Sambuc FREE(bp->name);
3472*0a6a1f1dSLionel Sambuc /* 'bp->tag' freed by 'free_tags()' */
3473*0a6a1f1dSLionel Sambuc FREE(bp->destructor);
3474*0a6a1f1dSLionel Sambuc FREE(bp);
3475*0a6a1f1dSLionel Sambuc }
3476*0a6a1f1dSLionel Sambuc }
3477*0a6a1f1dSLionel Sambuc }
3478*0a6a1f1dSLionel Sambuc #endif /* defined(YYBTYACC) */
3479*0a6a1f1dSLionel Sambuc
34804a17663cSThomas Veerman void
reader(void)34814a17663cSThomas Veerman reader(void)
34824a17663cSThomas Veerman {
34834a17663cSThomas Veerman write_section(code_file, banner);
34844a17663cSThomas Veerman create_symbol_table();
34854a17663cSThomas Veerman read_declarations();
34864a17663cSThomas Veerman read_grammar();
34874a17663cSThomas Veerman free_symbol_table();
34884a17663cSThomas Veerman pack_names();
34894a17663cSThomas Veerman check_symbols();
34904a17663cSThomas Veerman pack_symbols();
34914a17663cSThomas Veerman pack_grammar();
34924a17663cSThomas Veerman free_symbols();
34934a17663cSThomas Veerman print_grammar();
3494*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
3495*0a6a1f1dSLionel Sambuc if (destructor)
3496*0a6a1f1dSLionel Sambuc finalize_destructors();
3497*0a6a1f1dSLionel Sambuc #endif
3498*0a6a1f1dSLionel Sambuc free_tags();
34994a17663cSThomas Veerman }
35004a17663cSThomas Veerman
35014a17663cSThomas Veerman #ifdef NO_LEAKS
35024a17663cSThomas Veerman static param *
free_declarations(param * list)35034a17663cSThomas Veerman free_declarations(param * list)
35044a17663cSThomas Veerman {
35054a17663cSThomas Veerman while (list != 0)
35064a17663cSThomas Veerman {
35074a17663cSThomas Veerman param *next = list->next;
35084a17663cSThomas Veerman free(list->type);
35094a17663cSThomas Veerman free(list->name);
35104a17663cSThomas Veerman free(list->type2);
35114a17663cSThomas Veerman free(list);
35124a17663cSThomas Veerman list = next;
35134a17663cSThomas Veerman }
35144a17663cSThomas Veerman return list;
35154a17663cSThomas Veerman }
35164a17663cSThomas Veerman
35174a17663cSThomas Veerman void
reader_leaks(void)35184a17663cSThomas Veerman reader_leaks(void)
35194a17663cSThomas Veerman {
35204a17663cSThomas Veerman lex_param = free_declarations(lex_param);
35214a17663cSThomas Veerman parse_param = free_declarations(parse_param);
35224a17663cSThomas Veerman
35234a17663cSThomas Veerman DO_FREE(line);
35244a17663cSThomas Veerman DO_FREE(rrhs);
35254a17663cSThomas Veerman DO_FREE(rlhs);
35264a17663cSThomas Veerman DO_FREE(rprec);
35274a17663cSThomas Veerman DO_FREE(ritem);
35284a17663cSThomas Veerman DO_FREE(rassoc);
35294a17663cSThomas Veerman DO_FREE(cache);
35304a17663cSThomas Veerman DO_FREE(name_pool);
35314a17663cSThomas Veerman DO_FREE(symbol_name);
35324a17663cSThomas Veerman DO_FREE(symbol_prec);
35334a17663cSThomas Veerman DO_FREE(symbol_assoc);
35344a17663cSThomas Veerman DO_FREE(symbol_value);
3535*0a6a1f1dSLionel Sambuc #if defined(YYBTYACC)
3536*0a6a1f1dSLionel Sambuc DO_FREE(symbol_pval);
3537*0a6a1f1dSLionel Sambuc DO_FREE(symbol_destructor);
3538*0a6a1f1dSLionel Sambuc DO_FREE(symbol_type_tag);
3539*0a6a1f1dSLionel Sambuc #endif
35404a17663cSThomas Veerman }
35414a17663cSThomas Veerman #endif
3542