1*822ca327SBaptiste Daroussin /* $Id: reader.c,v 1.104 2023/05/18 21:18:17 tom Exp $ */
298e903e7SBaptiste Daroussin
398e903e7SBaptiste Daroussin #include "defs.h"
498e903e7SBaptiste Daroussin
598e903e7SBaptiste Daroussin /* The line size must be a positive integer. One hundred was chosen */
698e903e7SBaptiste Daroussin /* because few lines in Yacc input grammars exceed 100 characters. */
798e903e7SBaptiste Daroussin /* Note that if a line exceeds LINESIZE characters, the line buffer */
8b53bb29fSJung-uk Kim /* will be expanded to accommodate it. */
998e903e7SBaptiste Daroussin
1098e903e7SBaptiste Daroussin #define LINESIZE 100
1198e903e7SBaptiste Daroussin
1298e903e7SBaptiste Daroussin #define L_CURL '{'
1398e903e7SBaptiste Daroussin #define R_CURL '}'
140c8de5b0SBaptiste Daroussin #define L_PAREN '('
150c8de5b0SBaptiste Daroussin #define R_PAREN ')'
160c8de5b0SBaptiste Daroussin #define L_BRAC '['
170c8de5b0SBaptiste Daroussin #define R_BRAC ']'
180c8de5b0SBaptiste Daroussin
190c8de5b0SBaptiste Daroussin /* the maximum number of arguments (inherited attributes) to a non-terminal */
200c8de5b0SBaptiste Daroussin /* this is a hard limit, but seems more than adequate */
210c8de5b0SBaptiste Daroussin #define MAXARGS 20
2298e903e7SBaptiste Daroussin
23*822ca327SBaptiste Daroussin /* limit the size of optional names for %union */
24*822ca327SBaptiste Daroussin #define NAME_LEN 32
25*822ca327SBaptiste Daroussin
26*822ca327SBaptiste Daroussin #define IS_ALNUM(c) (isalnum(c) || (c) == '_')
27*822ca327SBaptiste Daroussin
288e022d3cSDag-Erling Smørgrav #define begin_case(f,n) fprintf(f, "case %d:\n", (int)(n))
298e022d3cSDag-Erling Smørgrav
308e022d3cSDag-Erling Smørgrav #define end_case(f) \
318e022d3cSDag-Erling Smørgrav fprintf(f, "\n"); \
328e022d3cSDag-Erling Smørgrav fprintf_lineno(f, 1, ""); \
338e022d3cSDag-Erling Smørgrav fprintf(f, "break;\n")
348e022d3cSDag-Erling Smørgrav
35*822ca327SBaptiste Daroussin #define begin_ainfo(data, offset) do { \
36*822ca327SBaptiste Daroussin data.a_lineno = lineno; \
37*822ca327SBaptiste Daroussin data.a_line = dup_line(); \
38*822ca327SBaptiste Daroussin data.a_cptr = data.a_line + (cptr - line - offset); \
39*822ca327SBaptiste Daroussin } while (0)
40*822ca327SBaptiste Daroussin
41*822ca327SBaptiste Daroussin #define end_ainfo(data) do { \
42*822ca327SBaptiste Daroussin FREE(data.a_line); \
43*822ca327SBaptiste Daroussin memset(&data, 0, sizeof(data)); \
44*822ca327SBaptiste Daroussin } while (0)
45*822ca327SBaptiste Daroussin
4698e903e7SBaptiste Daroussin static void start_rule(bucket *bp, int s_lineno);
470c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
482aca18c7SJung-uk Kim static void copy_initial_action(void);
490c8de5b0SBaptiste Daroussin static void copy_destructor(void);
500c8de5b0SBaptiste Daroussin static char *process_destructor_XX(char *code, char *tag);
510c8de5b0SBaptiste Daroussin #endif
5298e903e7SBaptiste Daroussin
530f86d14eSJung-uk Kim #define CACHE_SIZE 256
5498e903e7SBaptiste Daroussin static char *cache;
5598e903e7SBaptiste Daroussin static int cinc, cache_size;
5698e903e7SBaptiste Daroussin
5798e903e7SBaptiste Daroussin int ntags;
580c8de5b0SBaptiste Daroussin static int tagmax, havetags;
5998e903e7SBaptiste Daroussin static char **tag_table;
6098e903e7SBaptiste Daroussin
6198e903e7SBaptiste Daroussin static char saw_eof;
6298e903e7SBaptiste Daroussin char unionized;
63*822ca327SBaptiste Daroussin
64*822ca327SBaptiste Daroussin char *line; /* current input-line */
65*822ca327SBaptiste Daroussin char *cptr; /* position within current input-line */
66*822ca327SBaptiste Daroussin static size_t linesize; /* length of current input-line */
67*822ca327SBaptiste Daroussin
68*822ca327SBaptiste Daroussin typedef struct
69*822ca327SBaptiste Daroussin {
70*822ca327SBaptiste Daroussin char *line_data; /* saved input-line */
71*822ca327SBaptiste Daroussin size_t line_used; /* position within saved input-line */
72*822ca327SBaptiste Daroussin size_t line_size; /* length of saved input-line */
73*822ca327SBaptiste Daroussin fpos_t line_fpos; /* pointer before reading past saved input-line */
74*822ca327SBaptiste Daroussin }
75*822ca327SBaptiste Daroussin SAVE_LINE;
76*822ca327SBaptiste Daroussin
77*822ca327SBaptiste Daroussin static SAVE_LINE save_area;
78*822ca327SBaptiste Daroussin static int must_save; /* request > 0, triggered < 0, inactive 0 */
7998e903e7SBaptiste Daroussin
8098e903e7SBaptiste Daroussin static bucket *goal;
8198e903e7SBaptiste Daroussin static Value_t prec;
8298e903e7SBaptiste Daroussin static int gensym;
8398e903e7SBaptiste Daroussin static char last_was_action;
84c5b5d71aSJung-uk Kim #if defined(YYBTYACC)
85c5b5d71aSJung-uk Kim static int trialaction;
86c5b5d71aSJung-uk Kim #endif
8798e903e7SBaptiste Daroussin
8898e903e7SBaptiste Daroussin static int maxitems;
8998e903e7SBaptiste Daroussin static bucket **pitem;
9098e903e7SBaptiste Daroussin
9198e903e7SBaptiste Daroussin static int maxrules;
9298e903e7SBaptiste Daroussin static bucket **plhs;
9398e903e7SBaptiste Daroussin
9498e903e7SBaptiste Daroussin static size_t name_pool_size;
9598e903e7SBaptiste Daroussin static char *name_pool;
9698e903e7SBaptiste Daroussin
9798e903e7SBaptiste Daroussin char line_format[] = "#line %d \"%s\"\n";
9898e903e7SBaptiste Daroussin
9998e903e7SBaptiste Daroussin param *lex_param;
10098e903e7SBaptiste Daroussin param *parse_param;
10198e903e7SBaptiste Daroussin
102b53bb29fSJung-uk Kim static const char *code_keys[] =
103b53bb29fSJung-uk Kim {
104b53bb29fSJung-uk Kim "", "requires", "provides", "top", "imports",
105b53bb29fSJung-uk Kim };
106b53bb29fSJung-uk Kim
107b53bb29fSJung-uk Kim struct code_lines code_lines[CODE_MAX];
108b53bb29fSJung-uk Kim
1090c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
1100c8de5b0SBaptiste Daroussin int destructor = 0; /* =1 if at least one %destructor */
1110c8de5b0SBaptiste Daroussin
1120c8de5b0SBaptiste Daroussin static bucket *default_destructor[3] =
1130c8de5b0SBaptiste Daroussin {0, 0, 0};
1140c8de5b0SBaptiste Daroussin
1150c8de5b0SBaptiste Daroussin #define UNTYPED_DEFAULT 0
1160c8de5b0SBaptiste Daroussin #define TYPED_DEFAULT 1
1170c8de5b0SBaptiste Daroussin #define TYPE_SPECIFIED 2
1180c8de5b0SBaptiste Daroussin
1190c8de5b0SBaptiste Daroussin static bucket *
lookup_type_destructor(char * tag)1200c8de5b0SBaptiste Daroussin lookup_type_destructor(char *tag)
1210c8de5b0SBaptiste Daroussin {
12211fce282SBaptiste Daroussin const char fmt[] = "%.*s destructor";
1230c8de5b0SBaptiste Daroussin char name[1024] = "\0";
1240c8de5b0SBaptiste Daroussin bucket *bp, **bpp = &default_destructor[TYPE_SPECIFIED];
1250c8de5b0SBaptiste Daroussin
1260c8de5b0SBaptiste Daroussin while ((bp = *bpp) != NULL)
1270c8de5b0SBaptiste Daroussin {
1280c8de5b0SBaptiste Daroussin if (bp->tag == tag)
1290c8de5b0SBaptiste Daroussin return (bp);
1300c8de5b0SBaptiste Daroussin bpp = &bp->link;
1310c8de5b0SBaptiste Daroussin }
1320c8de5b0SBaptiste Daroussin
13311fce282SBaptiste Daroussin sprintf(name, fmt, (int)(sizeof(name) - sizeof(fmt)), tag);
13411fce282SBaptiste Daroussin *bpp = bp = make_bucket(name);
1350c8de5b0SBaptiste Daroussin bp->tag = tag;
1360c8de5b0SBaptiste Daroussin
1370c8de5b0SBaptiste Daroussin return (bp);
1380c8de5b0SBaptiste Daroussin }
1390c8de5b0SBaptiste Daroussin #endif /* defined(YYBTYACC) */
1400c8de5b0SBaptiste Daroussin
14198e903e7SBaptiste Daroussin static void
cachec(int c)14298e903e7SBaptiste Daroussin cachec(int c)
14398e903e7SBaptiste Daroussin {
14498e903e7SBaptiste Daroussin assert(cinc >= 0);
14598e903e7SBaptiste Daroussin if (cinc >= cache_size)
14698e903e7SBaptiste Daroussin {
1470f86d14eSJung-uk Kim cache_size += CACHE_SIZE;
1483e066022SBaptiste Daroussin cache = TREALLOC(char, cache, cache_size);
14998e903e7SBaptiste Daroussin NO_SPACE(cache);
15098e903e7SBaptiste Daroussin }
15198e903e7SBaptiste Daroussin cache[cinc] = (char)c;
15298e903e7SBaptiste Daroussin ++cinc;
15398e903e7SBaptiste Daroussin }
15498e903e7SBaptiste Daroussin
1553e794565SJung-uk Kim typedef enum
1563e794565SJung-uk Kim {
1573e794565SJung-uk Kim ldSPC1,
1583e794565SJung-uk Kim ldSPC2,
1593e794565SJung-uk Kim ldNAME,
1603e794565SJung-uk Kim ldSPC3,
1613e794565SJung-uk Kim ldNUM,
1623e794565SJung-uk Kim ldSPC4,
1633e794565SJung-uk Kim ldFILE,
1643e794565SJung-uk Kim ldOK,
1653e794565SJung-uk Kim ldERR
1663e794565SJung-uk Kim }
1673e794565SJung-uk Kim LINE_DIR;
1683e794565SJung-uk Kim
1693e794565SJung-uk Kim /*
1703e794565SJung-uk Kim * Expect this pattern:
1713e794565SJung-uk Kim * /^[[:space:]]*#[[:space:]]*
1723e794565SJung-uk Kim * line[[:space:]]+
1733e794565SJung-uk Kim * [[:digit:]]+
1743e794565SJung-uk Kim * ([[:space:]]*|[[:space:]]+"[^"]+")/
1753e794565SJung-uk Kim */
1763e794565SJung-uk Kim static int
line_directive(void)1773e794565SJung-uk Kim line_directive(void)
1783e794565SJung-uk Kim {
1793e794565SJung-uk Kim #define UNLESS(what) if (what) { ld = ldERR; break; }
1803e794565SJung-uk Kim int n;
1813e794565SJung-uk Kim int line_1st = -1;
1823e794565SJung-uk Kim int name_1st = -1;
1833e794565SJung-uk Kim int name_end = -1;
1843e794565SJung-uk Kim LINE_DIR ld = ldSPC1;
1853e794565SJung-uk Kim for (n = 0; (ld <= ldOK) && (line[n] != '\0'); ++n)
1863e794565SJung-uk Kim {
1873e794565SJung-uk Kim int ch = UCH(line[n]);
1883e794565SJung-uk Kim switch (ld)
1893e794565SJung-uk Kim {
1903e794565SJung-uk Kim case ldSPC1:
191b53bb29fSJung-uk Kim if (isspace(UCH(ch)))
1923e794565SJung-uk Kim {
1933e794565SJung-uk Kim break;
1943e794565SJung-uk Kim }
1953e794565SJung-uk Kim else
1963e794565SJung-uk Kim UNLESS(ch != '#');
1973e794565SJung-uk Kim ld = ldSPC2;
1983e794565SJung-uk Kim break;
1993e794565SJung-uk Kim case ldSPC2:
200b53bb29fSJung-uk Kim if (isspace(UCH(ch)))
2013e794565SJung-uk Kim {
2023e794565SJung-uk Kim break;
2033e794565SJung-uk Kim }
2043e794565SJung-uk Kim /* FALLTHRU */
2053e794565SJung-uk Kim case ldNAME:
2063e794565SJung-uk Kim UNLESS(strncmp(line + n, "line", 4));
2073e794565SJung-uk Kim n += 4;
2083e794565SJung-uk Kim if (line[n] == '\0')
2093e794565SJung-uk Kim {
2103e794565SJung-uk Kim ld = ldOK;
2113e794565SJung-uk Kim break;
2123e794565SJung-uk Kim }
2133e794565SJung-uk Kim else
2143e794565SJung-uk Kim UNLESS(!isspace(UCH(line[n])));
2153e794565SJung-uk Kim ld = ldSPC3;
2163e794565SJung-uk Kim break;
2173e794565SJung-uk Kim case ldSPC3:
218b53bb29fSJung-uk Kim if (isspace(UCH(ch)))
2193e794565SJung-uk Kim {
2203e794565SJung-uk Kim break;
2213e794565SJung-uk Kim }
2223e794565SJung-uk Kim else
223b53bb29fSJung-uk Kim UNLESS(!isdigit(UCH(ch)));
2243e794565SJung-uk Kim line_1st = n;
2258e022d3cSDag-Erling Smørgrav ld = ldNUM; /* this is needed, but cppcheck says no... */
2263e794565SJung-uk Kim /* FALLTHRU */
2273e794565SJung-uk Kim case ldNUM:
228b53bb29fSJung-uk Kim if (isdigit(UCH(ch)))
2293e794565SJung-uk Kim {
2303e794565SJung-uk Kim break;
2313e794565SJung-uk Kim }
2323e794565SJung-uk Kim else
233b53bb29fSJung-uk Kim UNLESS(!isspace(UCH(ch)));
2343e794565SJung-uk Kim ld = ldSPC4;
2353e794565SJung-uk Kim break;
2363e794565SJung-uk Kim case ldSPC4:
237b53bb29fSJung-uk Kim if (isspace(UCH(ch)))
2383e794565SJung-uk Kim {
2393e794565SJung-uk Kim break;
2403e794565SJung-uk Kim }
2413e794565SJung-uk Kim else
2423e794565SJung-uk Kim UNLESS(ch != '"');
2433e794565SJung-uk Kim UNLESS(line[n + 1] == '"');
2443e794565SJung-uk Kim ld = ldFILE;
2453e794565SJung-uk Kim name_1st = n;
2463e794565SJung-uk Kim break;
2473e794565SJung-uk Kim case ldFILE:
2483e794565SJung-uk Kim if (ch != '"')
2493e794565SJung-uk Kim {
2503e794565SJung-uk Kim break;
2513e794565SJung-uk Kim }
2523e794565SJung-uk Kim ld = ldOK;
2533e794565SJung-uk Kim name_end = n;
2543e794565SJung-uk Kim /* FALLTHRU */
2553e794565SJung-uk Kim case ldERR:
2563e794565SJung-uk Kim case ldOK:
2573e794565SJung-uk Kim break;
2583e794565SJung-uk Kim }
2593e794565SJung-uk Kim }
2603e794565SJung-uk Kim
2613e794565SJung-uk Kim if (ld == ldOK)
2623e794565SJung-uk Kim {
2633e794565SJung-uk Kim size_t need = (size_t)(name_end - name_1st);
264b53bb29fSJung-uk Kim if ((long)need > (long)input_file_name_len)
2653e794565SJung-uk Kim {
266b53bb29fSJung-uk Kim input_file_name_len = ((need + 1) * 3) / 2;
267b53bb29fSJung-uk Kim input_file_name = TREALLOC(char, input_file_name, input_file_name_len);
2683e794565SJung-uk Kim NO_SPACE(input_file_name);
2693e794565SJung-uk Kim }
270b53bb29fSJung-uk Kim if ((long)need > 0)
271b53bb29fSJung-uk Kim {
2723e794565SJung-uk Kim memcpy(input_file_name, line + name_1st + 1, need - 1);
2733e794565SJung-uk Kim input_file_name[need - 1] = '\0';
2743e794565SJung-uk Kim }
275b53bb29fSJung-uk Kim else
276b53bb29fSJung-uk Kim {
277b53bb29fSJung-uk Kim input_file_name[0] = '\0';
278b53bb29fSJung-uk Kim }
279b53bb29fSJung-uk Kim }
2803e794565SJung-uk Kim
2813e794565SJung-uk Kim if (ld >= ldNUM && ld < ldERR)
2823e794565SJung-uk Kim {
283b53bb29fSJung-uk Kim if (line_1st >= 0)
284b53bb29fSJung-uk Kim {
2853e794565SJung-uk Kim lineno = (int)strtol(line + line_1st, NULL, 10) - 1;
2863e794565SJung-uk Kim }
287b53bb29fSJung-uk Kim else
288b53bb29fSJung-uk Kim {
289b53bb29fSJung-uk Kim lineno = 0;
290b53bb29fSJung-uk Kim }
291b53bb29fSJung-uk Kim }
2923e794565SJung-uk Kim
2933e794565SJung-uk Kim return (ld == ldOK);
2943e794565SJung-uk Kim #undef UNLESS
2953e794565SJung-uk Kim }
2963e794565SJung-uk Kim
29798e903e7SBaptiste Daroussin static void
save_line(void)298*822ca327SBaptiste Daroussin save_line(void)
299*822ca327SBaptiste Daroussin {
300*822ca327SBaptiste Daroussin /* remember to save the input-line if we call get_line() */
301*822ca327SBaptiste Daroussin if (!must_save)
302*822ca327SBaptiste Daroussin {
303*822ca327SBaptiste Daroussin must_save = 1;
304*822ca327SBaptiste Daroussin save_area.line_used = (size_t)(cptr - line);
305*822ca327SBaptiste Daroussin }
306*822ca327SBaptiste Daroussin }
307*822ca327SBaptiste Daroussin
308*822ca327SBaptiste Daroussin static void
restore_line(void)309*822ca327SBaptiste Daroussin restore_line(void)
310*822ca327SBaptiste Daroussin {
311*822ca327SBaptiste Daroussin /* if we saved the line, restore it */
312*822ca327SBaptiste Daroussin if (must_save < 0)
313*822ca327SBaptiste Daroussin {
314*822ca327SBaptiste Daroussin free(line);
315*822ca327SBaptiste Daroussin line = save_area.line_data;
316*822ca327SBaptiste Daroussin cptr = save_area.line_used + line;
317*822ca327SBaptiste Daroussin linesize = save_area.line_size;
318*822ca327SBaptiste Daroussin if (fsetpos(input_file, &save_area.line_fpos) != 0)
319*822ca327SBaptiste Daroussin on_error();
320*822ca327SBaptiste Daroussin memset(&save_area, 0, sizeof(save_area));
321*822ca327SBaptiste Daroussin }
322*822ca327SBaptiste Daroussin else if (must_save > 0)
323*822ca327SBaptiste Daroussin {
324*822ca327SBaptiste Daroussin cptr = line + save_area.line_used;
325*822ca327SBaptiste Daroussin }
326*822ca327SBaptiste Daroussin must_save = 0;
327*822ca327SBaptiste Daroussin }
328*822ca327SBaptiste Daroussin
329*822ca327SBaptiste Daroussin static void
get_line(void)33098e903e7SBaptiste Daroussin get_line(void)
33198e903e7SBaptiste Daroussin {
33298e903e7SBaptiste Daroussin FILE *f = input_file;
33398e903e7SBaptiste Daroussin
334*822ca327SBaptiste Daroussin if (must_save > 0)
335*822ca327SBaptiste Daroussin {
336*822ca327SBaptiste Daroussin save_area.line_data = TMALLOC(char, linesize);
337*822ca327SBaptiste Daroussin save_area.line_used = (size_t)(cptr - line);
338*822ca327SBaptiste Daroussin save_area.line_size = linesize;
339*822ca327SBaptiste Daroussin NO_SPACE(save_area.line_data);
340*822ca327SBaptiste Daroussin memcpy(save_area.line_data, line, linesize);
341*822ca327SBaptiste Daroussin if (fgetpos(f, &save_area.line_fpos) != 0)
342*822ca327SBaptiste Daroussin on_error();
343*822ca327SBaptiste Daroussin must_save = -must_save;
344*822ca327SBaptiste Daroussin }
345*822ca327SBaptiste Daroussin
3463e794565SJung-uk Kim do
3473e794565SJung-uk Kim {
3488e022d3cSDag-Erling Smørgrav int c;
349*822ca327SBaptiste Daroussin size_t i;
3508e022d3cSDag-Erling Smørgrav
35198e903e7SBaptiste Daroussin if (saw_eof || (c = getc(f)) == EOF)
35298e903e7SBaptiste Daroussin {
35398e903e7SBaptiste Daroussin if (line)
35498e903e7SBaptiste Daroussin {
35598e903e7SBaptiste Daroussin FREE(line);
35698e903e7SBaptiste Daroussin line = 0;
35798e903e7SBaptiste Daroussin }
35898e903e7SBaptiste Daroussin cptr = 0;
35998e903e7SBaptiste Daroussin saw_eof = 1;
36098e903e7SBaptiste Daroussin return;
36198e903e7SBaptiste Daroussin }
36298e903e7SBaptiste Daroussin
363c5b5d71aSJung-uk Kim if (line == NULL || linesize != (LINESIZE + 1))
36498e903e7SBaptiste Daroussin {
36598e903e7SBaptiste Daroussin if (line)
36698e903e7SBaptiste Daroussin FREE(line);
36798e903e7SBaptiste Daroussin linesize = LINESIZE + 1;
368315e69cbSBaptiste Daroussin line = TMALLOC(char, linesize);
36998e903e7SBaptiste Daroussin NO_SPACE(line);
37098e903e7SBaptiste Daroussin }
37198e903e7SBaptiste Daroussin
37298e903e7SBaptiste Daroussin i = 0;
37398e903e7SBaptiste Daroussin ++lineno;
37498e903e7SBaptiste Daroussin for (;;)
37598e903e7SBaptiste Daroussin {
376315e69cbSBaptiste Daroussin line[i++] = (char)c;
37798e903e7SBaptiste Daroussin if (c == '\n')
3780c8de5b0SBaptiste Daroussin break;
379315e69cbSBaptiste Daroussin if ((i + 3) >= linesize)
38098e903e7SBaptiste Daroussin {
38198e903e7SBaptiste Daroussin linesize += LINESIZE;
3823e066022SBaptiste Daroussin line = TREALLOC(char, line, linesize);
38398e903e7SBaptiste Daroussin NO_SPACE(line);
38498e903e7SBaptiste Daroussin }
38598e903e7SBaptiste Daroussin c = getc(f);
38698e903e7SBaptiste Daroussin if (c == EOF)
38798e903e7SBaptiste Daroussin {
388315e69cbSBaptiste Daroussin line[i++] = '\n';
38998e903e7SBaptiste Daroussin saw_eof = 1;
3900c8de5b0SBaptiste Daroussin break;
3910c8de5b0SBaptiste Daroussin }
3920c8de5b0SBaptiste Daroussin }
393315e69cbSBaptiste Daroussin line[i] = '\0';
3943e794565SJung-uk Kim }
3953e794565SJung-uk Kim while (line_directive());
39698e903e7SBaptiste Daroussin cptr = line;
39798e903e7SBaptiste Daroussin return;
39898e903e7SBaptiste Daroussin }
39998e903e7SBaptiste Daroussin
40098e903e7SBaptiste Daroussin static char *
dup_line(void)40198e903e7SBaptiste Daroussin dup_line(void)
40298e903e7SBaptiste Daroussin {
40398e903e7SBaptiste Daroussin char *p, *s, *t;
40498e903e7SBaptiste Daroussin
405c5b5d71aSJung-uk Kim if (line == NULL)
406c5b5d71aSJung-uk Kim return (NULL);
40798e903e7SBaptiste Daroussin s = line;
40898e903e7SBaptiste Daroussin while (*s != '\n')
40998e903e7SBaptiste Daroussin ++s;
4103e066022SBaptiste Daroussin p = TMALLOC(char, s - line + 1);
41198e903e7SBaptiste Daroussin NO_SPACE(p);
41298e903e7SBaptiste Daroussin
41398e903e7SBaptiste Daroussin s = line;
41498e903e7SBaptiste Daroussin t = p;
41598e903e7SBaptiste Daroussin while ((*t++ = *s++) != '\n')
41698e903e7SBaptiste Daroussin continue;
41798e903e7SBaptiste Daroussin return (p);
41898e903e7SBaptiste Daroussin }
41998e903e7SBaptiste Daroussin
42098e903e7SBaptiste Daroussin static void
skip_comment(void)42198e903e7SBaptiste Daroussin skip_comment(void)
42298e903e7SBaptiste Daroussin {
42398e903e7SBaptiste Daroussin char *s;
4242aca18c7SJung-uk Kim struct ainfo a;
425*822ca327SBaptiste Daroussin
426*822ca327SBaptiste Daroussin begin_ainfo(a, 0);
42798e903e7SBaptiste Daroussin
42898e903e7SBaptiste Daroussin s = cptr + 2;
42998e903e7SBaptiste Daroussin for (;;)
43098e903e7SBaptiste Daroussin {
43198e903e7SBaptiste Daroussin if (*s == '*' && s[1] == '/')
43298e903e7SBaptiste Daroussin {
43398e903e7SBaptiste Daroussin cptr = s + 2;
434*822ca327SBaptiste Daroussin end_ainfo(a);
43598e903e7SBaptiste Daroussin return;
43698e903e7SBaptiste Daroussin }
43798e903e7SBaptiste Daroussin if (*s == '\n')
43898e903e7SBaptiste Daroussin {
43998e903e7SBaptiste Daroussin get_line();
440c5b5d71aSJung-uk Kim if (line == NULL)
4412aca18c7SJung-uk Kim unterminated_comment(&a);
44298e903e7SBaptiste Daroussin s = cptr;
44398e903e7SBaptiste Daroussin }
44498e903e7SBaptiste Daroussin else
44598e903e7SBaptiste Daroussin ++s;
44698e903e7SBaptiste Daroussin }
44798e903e7SBaptiste Daroussin }
44898e903e7SBaptiste Daroussin
44998e903e7SBaptiste Daroussin static int
next_inline(void)45011fce282SBaptiste Daroussin next_inline(void)
45198e903e7SBaptiste Daroussin {
45298e903e7SBaptiste Daroussin char *s;
45398e903e7SBaptiste Daroussin
454c5b5d71aSJung-uk Kim if (line == NULL)
45598e903e7SBaptiste Daroussin {
45698e903e7SBaptiste Daroussin get_line();
457c5b5d71aSJung-uk Kim if (line == NULL)
45898e903e7SBaptiste Daroussin return (EOF);
45998e903e7SBaptiste Daroussin }
46098e903e7SBaptiste Daroussin
46198e903e7SBaptiste Daroussin s = cptr;
46298e903e7SBaptiste Daroussin for (;;)
46398e903e7SBaptiste Daroussin {
46498e903e7SBaptiste Daroussin switch (*s)
46598e903e7SBaptiste Daroussin {
46698e903e7SBaptiste Daroussin case '/':
46798e903e7SBaptiste Daroussin if (s[1] == '*')
46898e903e7SBaptiste Daroussin {
46998e903e7SBaptiste Daroussin cptr = s;
47098e903e7SBaptiste Daroussin skip_comment();
47198e903e7SBaptiste Daroussin s = cptr;
47298e903e7SBaptiste Daroussin break;
47398e903e7SBaptiste Daroussin }
47498e903e7SBaptiste Daroussin else if (s[1] == '/')
47598e903e7SBaptiste Daroussin {
47698e903e7SBaptiste Daroussin get_line();
477c5b5d71aSJung-uk Kim if (line == NULL)
47898e903e7SBaptiste Daroussin return (EOF);
47998e903e7SBaptiste Daroussin s = cptr;
48098e903e7SBaptiste Daroussin break;
48198e903e7SBaptiste Daroussin }
48298e903e7SBaptiste Daroussin /* FALLTHRU */
48398e903e7SBaptiste Daroussin
48498e903e7SBaptiste Daroussin default:
48598e903e7SBaptiste Daroussin cptr = s;
48698e903e7SBaptiste Daroussin return (*s);
48798e903e7SBaptiste Daroussin }
48898e903e7SBaptiste Daroussin }
48998e903e7SBaptiste Daroussin }
49011fce282SBaptiste Daroussin
49111fce282SBaptiste Daroussin static int
nextc(void)49211fce282SBaptiste Daroussin nextc(void)
49311fce282SBaptiste Daroussin {
49411fce282SBaptiste Daroussin int ch;
49511fce282SBaptiste Daroussin int finish = 0;
49611fce282SBaptiste Daroussin
49711fce282SBaptiste Daroussin do
49811fce282SBaptiste Daroussin {
49911fce282SBaptiste Daroussin switch (ch = next_inline())
50011fce282SBaptiste Daroussin {
501*822ca327SBaptiste Daroussin case '\0':
50211fce282SBaptiste Daroussin case '\n':
50311fce282SBaptiste Daroussin get_line();
50411fce282SBaptiste Daroussin break;
50511fce282SBaptiste Daroussin case ' ':
50611fce282SBaptiste Daroussin case '\t':
50711fce282SBaptiste Daroussin case '\f':
50811fce282SBaptiste Daroussin case '\r':
50911fce282SBaptiste Daroussin case '\v':
51011fce282SBaptiste Daroussin case ',':
51111fce282SBaptiste Daroussin case ';':
51211fce282SBaptiste Daroussin ++cptr;
51311fce282SBaptiste Daroussin break;
51411fce282SBaptiste Daroussin case '\\':
51511fce282SBaptiste Daroussin ch = '%';
51611fce282SBaptiste Daroussin /* FALLTHRU */
51711fce282SBaptiste Daroussin default:
51811fce282SBaptiste Daroussin finish = 1;
51911fce282SBaptiste Daroussin break;
52011fce282SBaptiste Daroussin }
52111fce282SBaptiste Daroussin }
52211fce282SBaptiste Daroussin while (!finish);
52311fce282SBaptiste Daroussin
52411fce282SBaptiste Daroussin return ch;
52511fce282SBaptiste Daroussin }
5260c8de5b0SBaptiste Daroussin /* *INDENT-OFF* */
5270c8de5b0SBaptiste Daroussin static struct keyword
5280c8de5b0SBaptiste Daroussin {
529b53bb29fSJung-uk Kim char name[16];
5300c8de5b0SBaptiste Daroussin int token;
5310c8de5b0SBaptiste Daroussin }
5320c8de5b0SBaptiste Daroussin keywords[] = {
5330c8de5b0SBaptiste Daroussin { "binary", NONASSOC },
534b53bb29fSJung-uk Kim { "code", XCODE },
5358e022d3cSDag-Erling Smørgrav { "debug", NONPOSIX_DEBUG },
536*822ca327SBaptiste Daroussin { "define", HACK_DEFINE },
5370c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
5380c8de5b0SBaptiste Daroussin { "destructor", DESTRUCTOR },
5390c8de5b0SBaptiste Daroussin #endif
5402aca18c7SJung-uk Kim { "error-verbose",ERROR_VERBOSE },
5410c8de5b0SBaptiste Daroussin { "expect", EXPECT },
5420c8de5b0SBaptiste Daroussin { "expect-rr", EXPECT_RR },
5430c8de5b0SBaptiste Daroussin { "ident", IDENT },
5442aca18c7SJung-uk Kim #if defined(YYBTYACC)
5452aca18c7SJung-uk Kim { "initial-action", INITIAL_ACTION },
5462aca18c7SJung-uk Kim #endif
5470c8de5b0SBaptiste Daroussin { "left", LEFT },
5480c8de5b0SBaptiste Daroussin { "lex-param", LEX_PARAM },
5490c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
5500c8de5b0SBaptiste Daroussin { "locations", LOCATIONS },
5510c8de5b0SBaptiste Daroussin #endif
5520c8de5b0SBaptiste Daroussin { "nonassoc", NONASSOC },
553*822ca327SBaptiste Daroussin { "nterm", TYPE },
5540c8de5b0SBaptiste Daroussin { "parse-param", PARSE_PARAM },
5550c8de5b0SBaptiste Daroussin { "pure-parser", PURE_PARSER },
5560c8de5b0SBaptiste Daroussin { "right", RIGHT },
5570c8de5b0SBaptiste Daroussin { "start", START },
5580c8de5b0SBaptiste Daroussin { "term", TOKEN },
5590c8de5b0SBaptiste Daroussin { "token", TOKEN },
5600c8de5b0SBaptiste Daroussin { "token-table", TOKEN_TABLE },
5610c8de5b0SBaptiste Daroussin { "type", TYPE },
5620c8de5b0SBaptiste Daroussin { "union", UNION },
5630c8de5b0SBaptiste Daroussin { "yacc", POSIX_YACC },
5640c8de5b0SBaptiste Daroussin };
5650c8de5b0SBaptiste Daroussin /* *INDENT-ON* */
56698e903e7SBaptiste Daroussin
56798e903e7SBaptiste Daroussin static int
compare_keys(const void * a,const void * b)5680c8de5b0SBaptiste Daroussin compare_keys(const void *a, const void *b)
56998e903e7SBaptiste Daroussin {
5700c8de5b0SBaptiste Daroussin const struct keyword *p = (const struct keyword *)a;
5710c8de5b0SBaptiste Daroussin const struct keyword *q = (const struct keyword *)b;
5720c8de5b0SBaptiste Daroussin return strcmp(p->name, q->name);
57398e903e7SBaptiste Daroussin }
57498e903e7SBaptiste Daroussin
57598e903e7SBaptiste Daroussin static int
keyword(void)57698e903e7SBaptiste Daroussin keyword(void)
57798e903e7SBaptiste Daroussin {
57898e903e7SBaptiste Daroussin int c;
57998e903e7SBaptiste Daroussin char *t_cptr = cptr;
58098e903e7SBaptiste Daroussin
58198e903e7SBaptiste Daroussin c = *++cptr;
582b53bb29fSJung-uk Kim if (isalpha(UCH(c)))
58398e903e7SBaptiste Daroussin {
5848e022d3cSDag-Erling Smørgrav struct keyword *key;
5858e022d3cSDag-Erling Smørgrav
58698e903e7SBaptiste Daroussin cinc = 0;
58798e903e7SBaptiste Daroussin for (;;)
58898e903e7SBaptiste Daroussin {
589b53bb29fSJung-uk Kim if (isalpha(UCH(c)))
59098e903e7SBaptiste Daroussin {
591b53bb29fSJung-uk Kim if (isupper(UCH(c)))
59298e903e7SBaptiste Daroussin c = tolower(c);
59398e903e7SBaptiste Daroussin cachec(c);
59498e903e7SBaptiste Daroussin }
595b53bb29fSJung-uk Kim else if (isdigit(UCH(c))
59698e903e7SBaptiste Daroussin || c == '-'
59798e903e7SBaptiste Daroussin || c == '.'
59898e903e7SBaptiste Daroussin || c == '$')
59998e903e7SBaptiste Daroussin {
60098e903e7SBaptiste Daroussin cachec(c);
60198e903e7SBaptiste Daroussin }
6020c8de5b0SBaptiste Daroussin else if (c == '_')
6030c8de5b0SBaptiste Daroussin {
6040c8de5b0SBaptiste Daroussin /* treat keywords spelled with '_' as if it were '-' */
6050c8de5b0SBaptiste Daroussin cachec('-');
6060c8de5b0SBaptiste Daroussin }
60798e903e7SBaptiste Daroussin else
60898e903e7SBaptiste Daroussin {
60998e903e7SBaptiste Daroussin break;
61098e903e7SBaptiste Daroussin }
61198e903e7SBaptiste Daroussin c = *++cptr;
61298e903e7SBaptiste Daroussin }
61398e903e7SBaptiste Daroussin cachec(NUL);
61498e903e7SBaptiste Daroussin
6150c8de5b0SBaptiste Daroussin if ((key = bsearch(cache, keywords,
6160c8de5b0SBaptiste Daroussin sizeof(keywords) / sizeof(*key),
6170c8de5b0SBaptiste Daroussin sizeof(*key), compare_keys)))
6180c8de5b0SBaptiste Daroussin return key->token;
61998e903e7SBaptiste Daroussin }
62098e903e7SBaptiste Daroussin else
62198e903e7SBaptiste Daroussin {
62298e903e7SBaptiste Daroussin ++cptr;
62398e903e7SBaptiste Daroussin if (c == L_CURL)
62498e903e7SBaptiste Daroussin return (TEXT);
62598e903e7SBaptiste Daroussin if (c == '%' || c == '\\')
62698e903e7SBaptiste Daroussin return (MARK);
62798e903e7SBaptiste Daroussin if (c == '<')
62898e903e7SBaptiste Daroussin return (LEFT);
62998e903e7SBaptiste Daroussin if (c == '>')
63098e903e7SBaptiste Daroussin return (RIGHT);
63198e903e7SBaptiste Daroussin if (c == '0')
63298e903e7SBaptiste Daroussin return (TOKEN);
63398e903e7SBaptiste Daroussin if (c == '2')
63498e903e7SBaptiste Daroussin return (NONASSOC);
63598e903e7SBaptiste Daroussin }
63698e903e7SBaptiste Daroussin syntax_error(lineno, line, t_cptr);
637c5b5d71aSJung-uk Kim /*NOTREACHED */
63898e903e7SBaptiste Daroussin }
63998e903e7SBaptiste Daroussin
64098e903e7SBaptiste Daroussin static void
copy_ident(void)64198e903e7SBaptiste Daroussin copy_ident(void)
64298e903e7SBaptiste Daroussin {
64398e903e7SBaptiste Daroussin int c;
64498e903e7SBaptiste Daroussin FILE *f = output_file;
64598e903e7SBaptiste Daroussin
64698e903e7SBaptiste Daroussin c = nextc();
64798e903e7SBaptiste Daroussin if (c == EOF)
64898e903e7SBaptiste Daroussin unexpected_EOF();
64998e903e7SBaptiste Daroussin if (c != '"')
65098e903e7SBaptiste Daroussin syntax_error(lineno, line, cptr);
65198e903e7SBaptiste Daroussin ++outline;
65298e903e7SBaptiste Daroussin fprintf(f, "#ident \"");
65398e903e7SBaptiste Daroussin for (;;)
65498e903e7SBaptiste Daroussin {
65598e903e7SBaptiste Daroussin c = *++cptr;
65698e903e7SBaptiste Daroussin if (c == '\n')
65798e903e7SBaptiste Daroussin {
65898e903e7SBaptiste Daroussin fprintf(f, "\"\n");
65998e903e7SBaptiste Daroussin return;
66098e903e7SBaptiste Daroussin }
66198e903e7SBaptiste Daroussin putc(c, f);
66298e903e7SBaptiste Daroussin if (c == '"')
66398e903e7SBaptiste Daroussin {
66498e903e7SBaptiste Daroussin putc('\n', f);
66598e903e7SBaptiste Daroussin ++cptr;
66698e903e7SBaptiste Daroussin return;
66798e903e7SBaptiste Daroussin }
66898e903e7SBaptiste Daroussin }
66998e903e7SBaptiste Daroussin }
67098e903e7SBaptiste Daroussin
6710c8de5b0SBaptiste Daroussin static char *
copy_string(int quote)6720c8de5b0SBaptiste Daroussin copy_string(int quote)
6730c8de5b0SBaptiste Daroussin {
6740c8de5b0SBaptiste Daroussin struct mstring *temp = msnew();
6752aca18c7SJung-uk Kim struct ainfo a;
676*822ca327SBaptiste Daroussin
677*822ca327SBaptiste Daroussin begin_ainfo(a, 1);
6780c8de5b0SBaptiste Daroussin
6790c8de5b0SBaptiste Daroussin for (;;)
6800c8de5b0SBaptiste Daroussin {
6818e022d3cSDag-Erling Smørgrav int c = *cptr++;
6828e022d3cSDag-Erling Smørgrav
6830c8de5b0SBaptiste Daroussin mputc(temp, c);
6840c8de5b0SBaptiste Daroussin if (c == quote)
6850c8de5b0SBaptiste Daroussin {
686*822ca327SBaptiste Daroussin end_ainfo(a);
6870c8de5b0SBaptiste Daroussin return msdone(temp);
6880c8de5b0SBaptiste Daroussin }
6890c8de5b0SBaptiste Daroussin if (c == '\n')
6902aca18c7SJung-uk Kim unterminated_string(&a);
6910c8de5b0SBaptiste Daroussin if (c == '\\')
6920c8de5b0SBaptiste Daroussin {
6930c8de5b0SBaptiste Daroussin c = *cptr++;
6940c8de5b0SBaptiste Daroussin mputc(temp, c);
6950c8de5b0SBaptiste Daroussin if (c == '\n')
6960c8de5b0SBaptiste Daroussin {
6970c8de5b0SBaptiste Daroussin get_line();
698c5b5d71aSJung-uk Kim if (line == NULL)
6992aca18c7SJung-uk Kim unterminated_string(&a);
7000c8de5b0SBaptiste Daroussin }
7010c8de5b0SBaptiste Daroussin }
7020c8de5b0SBaptiste Daroussin }
7030c8de5b0SBaptiste Daroussin }
7040c8de5b0SBaptiste Daroussin
7050c8de5b0SBaptiste Daroussin static char *
copy_comment(void)7060c8de5b0SBaptiste Daroussin copy_comment(void)
7070c8de5b0SBaptiste Daroussin {
7080c8de5b0SBaptiste Daroussin struct mstring *temp = msnew();
7090c8de5b0SBaptiste Daroussin int c;
7100c8de5b0SBaptiste Daroussin
7110c8de5b0SBaptiste Daroussin c = *cptr;
7120c8de5b0SBaptiste Daroussin if (c == '/')
7130c8de5b0SBaptiste Daroussin {
7140c8de5b0SBaptiste Daroussin mputc(temp, '*');
7150c8de5b0SBaptiste Daroussin while ((c = *++cptr) != '\n')
7160c8de5b0SBaptiste Daroussin {
7170c8de5b0SBaptiste Daroussin mputc(temp, c);
7180c8de5b0SBaptiste Daroussin if (c == '*' && cptr[1] == '/')
7190c8de5b0SBaptiste Daroussin mputc(temp, ' ');
7200c8de5b0SBaptiste Daroussin }
7210c8de5b0SBaptiste Daroussin mputc(temp, '*');
7220c8de5b0SBaptiste Daroussin mputc(temp, '/');
7230c8de5b0SBaptiste Daroussin }
7240c8de5b0SBaptiste Daroussin else if (c == '*')
7250c8de5b0SBaptiste Daroussin {
7262aca18c7SJung-uk Kim struct ainfo a;
727*822ca327SBaptiste Daroussin
728*822ca327SBaptiste Daroussin begin_ainfo(a, 1);
7290c8de5b0SBaptiste Daroussin
7300c8de5b0SBaptiste Daroussin mputc(temp, c);
7310c8de5b0SBaptiste Daroussin ++cptr;
7320c8de5b0SBaptiste Daroussin for (;;)
7330c8de5b0SBaptiste Daroussin {
7340c8de5b0SBaptiste Daroussin c = *cptr++;
7350c8de5b0SBaptiste Daroussin mputc(temp, c);
7360c8de5b0SBaptiste Daroussin if (c == '*' && *cptr == '/')
7370c8de5b0SBaptiste Daroussin {
7380c8de5b0SBaptiste Daroussin mputc(temp, '/');
7390c8de5b0SBaptiste Daroussin ++cptr;
740*822ca327SBaptiste Daroussin end_ainfo(a);
7410c8de5b0SBaptiste Daroussin return msdone(temp);
7420c8de5b0SBaptiste Daroussin }
7430c8de5b0SBaptiste Daroussin if (c == '\n')
7440c8de5b0SBaptiste Daroussin {
7450c8de5b0SBaptiste Daroussin get_line();
746c5b5d71aSJung-uk Kim if (line == NULL)
7472aca18c7SJung-uk Kim unterminated_comment(&a);
7480c8de5b0SBaptiste Daroussin }
7490c8de5b0SBaptiste Daroussin }
7500c8de5b0SBaptiste Daroussin }
7510c8de5b0SBaptiste Daroussin return msdone(temp);
7520c8de5b0SBaptiste Daroussin }
7530c8de5b0SBaptiste Daroussin
754b53bb29fSJung-uk Kim static int
check_key(int pos)755b53bb29fSJung-uk Kim check_key(int pos)
756b53bb29fSJung-uk Kim {
757b53bb29fSJung-uk Kim const char *key = code_keys[pos];
758b53bb29fSJung-uk Kim while (*cptr && *key)
759b53bb29fSJung-uk Kim if (*key++ != *cptr++)
760b53bb29fSJung-uk Kim return 0;
761b53bb29fSJung-uk Kim if (*key || (!isspace(UCH(*cptr)) && *cptr != L_CURL))
762b53bb29fSJung-uk Kim return 0;
763b53bb29fSJung-uk Kim cptr--;
764b53bb29fSJung-uk Kim return 1;
765b53bb29fSJung-uk Kim }
766b53bb29fSJung-uk Kim
767b53bb29fSJung-uk Kim static void
copy_code(void)768b53bb29fSJung-uk Kim copy_code(void)
769b53bb29fSJung-uk Kim {
770b53bb29fSJung-uk Kim int c;
771b53bb29fSJung-uk Kim int curl;
772b53bb29fSJung-uk Kim int cline;
773b53bb29fSJung-uk Kim int on_line = 0;
774b53bb29fSJung-uk Kim int pos = CODE_HEADER;
775b53bb29fSJung-uk Kim struct mstring *code_mstr;
776b53bb29fSJung-uk Kim
777b53bb29fSJung-uk Kim /* read %code <keyword> { */
778b53bb29fSJung-uk Kim for (;;)
779b53bb29fSJung-uk Kim {
780b53bb29fSJung-uk Kim c = *++cptr;
781b53bb29fSJung-uk Kim if (c == EOF)
782b53bb29fSJung-uk Kim unexpected_EOF();
783*822ca327SBaptiste Daroussin if (c == '\0')
784*822ca327SBaptiste Daroussin {
785*822ca327SBaptiste Daroussin get_line();
786*822ca327SBaptiste Daroussin if (line == NULL)
787*822ca327SBaptiste Daroussin {
788*822ca327SBaptiste Daroussin unexpected_EOF();
789*822ca327SBaptiste Daroussin /*NOTREACHED */
790*822ca327SBaptiste Daroussin }
791*822ca327SBaptiste Daroussin c = *cptr;
792*822ca327SBaptiste Daroussin }
793b53bb29fSJung-uk Kim if (isspace(UCH(c)))
794b53bb29fSJung-uk Kim continue;
795b53bb29fSJung-uk Kim
796b53bb29fSJung-uk Kim if (c == L_CURL)
797b53bb29fSJung-uk Kim break;
798b53bb29fSJung-uk Kim
799b53bb29fSJung-uk Kim if (pos == CODE_HEADER)
800b53bb29fSJung-uk Kim {
801b53bb29fSJung-uk Kim switch (UCH(c))
802b53bb29fSJung-uk Kim {
803b53bb29fSJung-uk Kim case 'r':
804b53bb29fSJung-uk Kim pos = CODE_REQUIRES;
805b53bb29fSJung-uk Kim break;
806b53bb29fSJung-uk Kim case 'p':
807b53bb29fSJung-uk Kim pos = CODE_PROVIDES;
808b53bb29fSJung-uk Kim break;
809b53bb29fSJung-uk Kim case 't':
810b53bb29fSJung-uk Kim pos = CODE_TOP;
811b53bb29fSJung-uk Kim break;
812b53bb29fSJung-uk Kim case 'i':
813b53bb29fSJung-uk Kim pos = CODE_IMPORTS;
814b53bb29fSJung-uk Kim break;
815b53bb29fSJung-uk Kim default:
816b53bb29fSJung-uk Kim break;
817b53bb29fSJung-uk Kim }
818b53bb29fSJung-uk Kim
819b53bb29fSJung-uk Kim if (pos == -1 || !check_key(pos))
820b53bb29fSJung-uk Kim {
821b53bb29fSJung-uk Kim syntax_error(lineno, line, cptr);
8228e022d3cSDag-Erling Smørgrav /*NOTREACHED */
823b53bb29fSJung-uk Kim }
824b53bb29fSJung-uk Kim }
825b53bb29fSJung-uk Kim }
826b53bb29fSJung-uk Kim
827b53bb29fSJung-uk Kim cptr++; /* skip initial curl */
828b53bb29fSJung-uk Kim while (*cptr && isspace(UCH(*cptr))) /* skip space */
829b53bb29fSJung-uk Kim cptr++;
830b53bb29fSJung-uk Kim curl = 1; /* nesting count */
831b53bb29fSJung-uk Kim
832b53bb29fSJung-uk Kim /* gather text */
833b53bb29fSJung-uk Kim code_lines[pos].name = code_keys[pos];
834b53bb29fSJung-uk Kim if ((cline = (int)code_lines[pos].num) != 0)
835b53bb29fSJung-uk Kim {
836b53bb29fSJung-uk Kim code_mstr = msrenew(code_lines[pos].lines);
837b53bb29fSJung-uk Kim }
838b53bb29fSJung-uk Kim else
839b53bb29fSJung-uk Kim {
840b53bb29fSJung-uk Kim code_mstr = msnew();
841b53bb29fSJung-uk Kim }
842b53bb29fSJung-uk Kim cline++;
8438e022d3cSDag-Erling Smørgrav if (!lflag)
844b53bb29fSJung-uk Kim msprintf(code_mstr, line_format, lineno, input_file_name);
845b53bb29fSJung-uk Kim for (;;)
846b53bb29fSJung-uk Kim {
847b53bb29fSJung-uk Kim c = *cptr++;
848b53bb29fSJung-uk Kim switch (c)
849b53bb29fSJung-uk Kim {
850b53bb29fSJung-uk Kim case '\0':
851b53bb29fSJung-uk Kim get_line();
852b53bb29fSJung-uk Kim if (line == NULL)
853b53bb29fSJung-uk Kim {
854b53bb29fSJung-uk Kim unexpected_EOF();
8558e022d3cSDag-Erling Smørgrav /*NOTREACHED */
856b53bb29fSJung-uk Kim }
857b53bb29fSJung-uk Kim continue;
858b53bb29fSJung-uk Kim case '\n':
859b53bb29fSJung-uk Kim cline++;
860b53bb29fSJung-uk Kim on_line = 0;
861b53bb29fSJung-uk Kim break;
862b53bb29fSJung-uk Kim case L_CURL:
863b53bb29fSJung-uk Kim curl++;
864b53bb29fSJung-uk Kim break;
865b53bb29fSJung-uk Kim case R_CURL:
866b53bb29fSJung-uk Kim if (--curl == 0)
867b53bb29fSJung-uk Kim {
868b53bb29fSJung-uk Kim if (on_line > 1)
869b53bb29fSJung-uk Kim {
870b53bb29fSJung-uk Kim mputc(code_mstr, '\n');
871b53bb29fSJung-uk Kim cline++;
872b53bb29fSJung-uk Kim }
873b53bb29fSJung-uk Kim code_lines[pos].lines = msdone(code_mstr);
874b53bb29fSJung-uk Kim code_lines[pos].num = (size_t)cline;
875b53bb29fSJung-uk Kim return;
876b53bb29fSJung-uk Kim }
877b53bb29fSJung-uk Kim break;
878b53bb29fSJung-uk Kim default:
879b53bb29fSJung-uk Kim break;
880b53bb29fSJung-uk Kim }
881b53bb29fSJung-uk Kim mputc(code_mstr, c);
882b53bb29fSJung-uk Kim on_line++;
883b53bb29fSJung-uk Kim }
884b53bb29fSJung-uk Kim }
885b53bb29fSJung-uk Kim
88698e903e7SBaptiste Daroussin static void
copy_text(void)88798e903e7SBaptiste Daroussin copy_text(void)
88898e903e7SBaptiste Daroussin {
88998e903e7SBaptiste Daroussin int c;
89098e903e7SBaptiste Daroussin FILE *f = text_file;
89198e903e7SBaptiste Daroussin int need_newline = 0;
8922aca18c7SJung-uk Kim struct ainfo a;
893*822ca327SBaptiste Daroussin
894*822ca327SBaptiste Daroussin begin_ainfo(a, 2);
89598e903e7SBaptiste Daroussin
89698e903e7SBaptiste Daroussin if (*cptr == '\n')
89798e903e7SBaptiste Daroussin {
89898e903e7SBaptiste Daroussin get_line();
899c5b5d71aSJung-uk Kim if (line == NULL)
9002aca18c7SJung-uk Kim unterminated_text(&a);
90198e903e7SBaptiste Daroussin }
9028e022d3cSDag-Erling Smørgrav fprintf_lineno(f, lineno, input_file_name);
90398e903e7SBaptiste Daroussin
90498e903e7SBaptiste Daroussin loop:
90598e903e7SBaptiste Daroussin c = *cptr++;
90698e903e7SBaptiste Daroussin switch (c)
90798e903e7SBaptiste Daroussin {
90898e903e7SBaptiste Daroussin case '\n':
90998e903e7SBaptiste Daroussin putc('\n', f);
91098e903e7SBaptiste Daroussin need_newline = 0;
91198e903e7SBaptiste Daroussin get_line();
91298e903e7SBaptiste Daroussin if (line)
91398e903e7SBaptiste Daroussin goto loop;
9142aca18c7SJung-uk Kim unterminated_text(&a);
91598e903e7SBaptiste Daroussin
91698e903e7SBaptiste Daroussin case '\'':
91798e903e7SBaptiste Daroussin case '"':
91898e903e7SBaptiste Daroussin putc(c, f);
91998e903e7SBaptiste Daroussin {
9200c8de5b0SBaptiste Daroussin char *s = copy_string(c);
9210c8de5b0SBaptiste Daroussin fputs(s, f);
9220c8de5b0SBaptiste Daroussin free(s);
9230c8de5b0SBaptiste Daroussin }
92498e903e7SBaptiste Daroussin need_newline = 1;
92598e903e7SBaptiste Daroussin goto loop;
92698e903e7SBaptiste Daroussin
92798e903e7SBaptiste Daroussin case '/':
92898e903e7SBaptiste Daroussin putc(c, f);
92998e903e7SBaptiste Daroussin {
9300c8de5b0SBaptiste Daroussin char *s = copy_comment();
9310c8de5b0SBaptiste Daroussin fputs(s, f);
9320c8de5b0SBaptiste Daroussin free(s);
93398e903e7SBaptiste Daroussin }
93498e903e7SBaptiste Daroussin need_newline = 1;
93598e903e7SBaptiste Daroussin goto loop;
93698e903e7SBaptiste Daroussin
93798e903e7SBaptiste Daroussin case '%':
93898e903e7SBaptiste Daroussin case '\\':
93998e903e7SBaptiste Daroussin if (*cptr == R_CURL)
94098e903e7SBaptiste Daroussin {
94198e903e7SBaptiste Daroussin if (need_newline)
94298e903e7SBaptiste Daroussin putc('\n', f);
94398e903e7SBaptiste Daroussin ++cptr;
944*822ca327SBaptiste Daroussin end_ainfo(a);
94598e903e7SBaptiste Daroussin return;
94698e903e7SBaptiste Daroussin }
94798e903e7SBaptiste Daroussin /* FALLTHRU */
94898e903e7SBaptiste Daroussin
94998e903e7SBaptiste Daroussin default:
95098e903e7SBaptiste Daroussin putc(c, f);
95198e903e7SBaptiste Daroussin need_newline = 1;
95298e903e7SBaptiste Daroussin goto loop;
95398e903e7SBaptiste Daroussin }
95498e903e7SBaptiste Daroussin }
95598e903e7SBaptiste Daroussin
95698e903e7SBaptiste Daroussin static void
puts_both(const char * s)95798e903e7SBaptiste Daroussin puts_both(const char *s)
95898e903e7SBaptiste Daroussin {
959*822ca327SBaptiste Daroussin if (s && *s)
960*822ca327SBaptiste Daroussin {
96198e903e7SBaptiste Daroussin fputs(s, text_file);
96298e903e7SBaptiste Daroussin if (dflag)
96398e903e7SBaptiste Daroussin fputs(s, union_file);
96498e903e7SBaptiste Daroussin }
965*822ca327SBaptiste Daroussin }
96698e903e7SBaptiste Daroussin
96798e903e7SBaptiste Daroussin static void
putc_both(int c)96898e903e7SBaptiste Daroussin putc_both(int c)
96998e903e7SBaptiste Daroussin {
97098e903e7SBaptiste Daroussin putc(c, text_file);
97198e903e7SBaptiste Daroussin if (dflag)
97298e903e7SBaptiste Daroussin putc(c, union_file);
97398e903e7SBaptiste Daroussin }
97498e903e7SBaptiste Daroussin
97598e903e7SBaptiste Daroussin static void
copy_union(void)97698e903e7SBaptiste Daroussin copy_union(void)
97798e903e7SBaptiste Daroussin {
97898e903e7SBaptiste Daroussin int c;
97998e903e7SBaptiste Daroussin int depth;
9802aca18c7SJung-uk Kim struct ainfo a;
981*822ca327SBaptiste Daroussin char prefix_buf[NAME_LEN + 1];
982*822ca327SBaptiste Daroussin size_t prefix_len = 0;
983*822ca327SBaptiste Daroussin char filler_buf[NAME_LEN + 1];
984*822ca327SBaptiste Daroussin size_t filler_len = 0;
985*822ca327SBaptiste Daroussin int in_prefix = 1;
986*822ca327SBaptiste Daroussin
987*822ca327SBaptiste Daroussin prefix_buf[0] = '\0';
988*822ca327SBaptiste Daroussin filler_buf[0] = '\0';
989*822ca327SBaptiste Daroussin
990*822ca327SBaptiste Daroussin begin_ainfo(a, 6);
99198e903e7SBaptiste Daroussin
99298e903e7SBaptiste Daroussin if (unionized)
99398e903e7SBaptiste Daroussin over_unionized(cptr - 6);
99498e903e7SBaptiste Daroussin unionized = 1;
99598e903e7SBaptiste Daroussin
99698e903e7SBaptiste Daroussin puts_both("#ifdef YYSTYPE\n");
99798e903e7SBaptiste Daroussin puts_both("#undef YYSTYPE_IS_DECLARED\n");
99898e903e7SBaptiste Daroussin puts_both("#define YYSTYPE_IS_DECLARED 1\n");
99998e903e7SBaptiste Daroussin puts_both("#endif\n");
100098e903e7SBaptiste Daroussin puts_both("#ifndef YYSTYPE_IS_DECLARED\n");
100198e903e7SBaptiste Daroussin puts_both("#define YYSTYPE_IS_DECLARED 1\n");
1002c5b5d71aSJung-uk Kim
10038e022d3cSDag-Erling Smørgrav fprintf_lineno(text_file, lineno, input_file_name);
100498e903e7SBaptiste Daroussin
100598e903e7SBaptiste Daroussin depth = 0;
100698e903e7SBaptiste Daroussin loop:
100798e903e7SBaptiste Daroussin c = *cptr++;
1008*822ca327SBaptiste Daroussin if (in_prefix)
1009*822ca327SBaptiste Daroussin {
1010*822ca327SBaptiste Daroussin if (c == L_CURL)
1011*822ca327SBaptiste Daroussin {
1012*822ca327SBaptiste Daroussin in_prefix = 0;
1013*822ca327SBaptiste Daroussin if (prefix_len)
1014*822ca327SBaptiste Daroussin {
1015*822ca327SBaptiste Daroussin puts_both("union ");
1016*822ca327SBaptiste Daroussin puts_both(prefix_buf);
1017*822ca327SBaptiste Daroussin puts_both(filler_buf);
1018*822ca327SBaptiste Daroussin }
1019*822ca327SBaptiste Daroussin else
1020*822ca327SBaptiste Daroussin {
1021*822ca327SBaptiste Daroussin puts_both("typedef union YYSTYPE");
1022*822ca327SBaptiste Daroussin puts_both(filler_buf);
1023*822ca327SBaptiste Daroussin }
1024*822ca327SBaptiste Daroussin }
1025*822ca327SBaptiste Daroussin else if (isspace(c))
1026*822ca327SBaptiste Daroussin {
1027*822ca327SBaptiste Daroussin if (filler_len >= sizeof(filler_buf) - 1)
1028*822ca327SBaptiste Daroussin {
1029*822ca327SBaptiste Daroussin puts_both(filler_buf);
1030*822ca327SBaptiste Daroussin filler_len = 0;
1031*822ca327SBaptiste Daroussin }
1032*822ca327SBaptiste Daroussin filler_buf[filler_len++] = (char)c;
1033*822ca327SBaptiste Daroussin filler_buf[filler_len] = 0;
1034*822ca327SBaptiste Daroussin if (c != '\n')
1035*822ca327SBaptiste Daroussin goto loop;
1036*822ca327SBaptiste Daroussin }
1037*822ca327SBaptiste Daroussin else if (IS_IDENT(c))
1038*822ca327SBaptiste Daroussin {
1039*822ca327SBaptiste Daroussin if (prefix_len < NAME_LEN)
1040*822ca327SBaptiste Daroussin {
1041*822ca327SBaptiste Daroussin prefix_buf[prefix_len++] = (char)c;
1042*822ca327SBaptiste Daroussin prefix_buf[prefix_len] = 0;
1043*822ca327SBaptiste Daroussin }
1044*822ca327SBaptiste Daroussin goto loop;
1045*822ca327SBaptiste Daroussin }
1046*822ca327SBaptiste Daroussin }
1047*822ca327SBaptiste Daroussin if (c != '\n' || !in_prefix)
104898e903e7SBaptiste Daroussin putc_both(c);
104998e903e7SBaptiste Daroussin switch (c)
105098e903e7SBaptiste Daroussin {
105198e903e7SBaptiste Daroussin case '\n':
105298e903e7SBaptiste Daroussin get_line();
1053c5b5d71aSJung-uk Kim if (line == NULL)
10542aca18c7SJung-uk Kim unterminated_union(&a);
105598e903e7SBaptiste Daroussin goto loop;
105698e903e7SBaptiste Daroussin
105798e903e7SBaptiste Daroussin case L_CURL:
105898e903e7SBaptiste Daroussin ++depth;
105998e903e7SBaptiste Daroussin goto loop;
106098e903e7SBaptiste Daroussin
106198e903e7SBaptiste Daroussin case R_CURL:
106298e903e7SBaptiste Daroussin if (--depth == 0)
106398e903e7SBaptiste Daroussin {
1064*822ca327SBaptiste Daroussin puts_both(prefix_len ? "; " : " YYSTYPE;\n");
1065*822ca327SBaptiste Daroussin if (prefix_len)
1066*822ca327SBaptiste Daroussin {
1067*822ca327SBaptiste Daroussin puts_both("typedef union ");
1068*822ca327SBaptiste Daroussin puts_both(prefix_buf);
106998e903e7SBaptiste Daroussin puts_both(" YYSTYPE;\n");
1070*822ca327SBaptiste Daroussin }
107198e903e7SBaptiste Daroussin puts_both("#endif /* !YYSTYPE_IS_DECLARED */\n");
1072*822ca327SBaptiste Daroussin end_ainfo(a);
107398e903e7SBaptiste Daroussin return;
107498e903e7SBaptiste Daroussin }
107598e903e7SBaptiste Daroussin goto loop;
107698e903e7SBaptiste Daroussin
107798e903e7SBaptiste Daroussin case '\'':
107898e903e7SBaptiste Daroussin case '"':
107998e903e7SBaptiste Daroussin {
10800c8de5b0SBaptiste Daroussin char *s = copy_string(c);
10810c8de5b0SBaptiste Daroussin puts_both(s);
10820c8de5b0SBaptiste Daroussin free(s);
10830c8de5b0SBaptiste Daroussin }
108498e903e7SBaptiste Daroussin goto loop;
108598e903e7SBaptiste Daroussin
108698e903e7SBaptiste Daroussin case '/':
108798e903e7SBaptiste Daroussin {
10880c8de5b0SBaptiste Daroussin char *s = copy_comment();
10890c8de5b0SBaptiste Daroussin puts_both(s);
10900c8de5b0SBaptiste Daroussin free(s);
109198e903e7SBaptiste Daroussin }
109298e903e7SBaptiste Daroussin goto loop;
109398e903e7SBaptiste Daroussin
109498e903e7SBaptiste Daroussin default:
109598e903e7SBaptiste Daroussin goto loop;
109698e903e7SBaptiste Daroussin }
109798e903e7SBaptiste Daroussin }
109898e903e7SBaptiste Daroussin
109911fce282SBaptiste Daroussin static char *
after_blanks(char * s)110011fce282SBaptiste Daroussin after_blanks(char *s)
110111fce282SBaptiste Daroussin {
110211fce282SBaptiste Daroussin while (*s != '\0' && isspace(UCH(*s)))
110311fce282SBaptiste Daroussin ++s;
110411fce282SBaptiste Daroussin return s;
110511fce282SBaptiste Daroussin }
110611fce282SBaptiste Daroussin
110798e903e7SBaptiste Daroussin /*
110811fce282SBaptiste Daroussin * Trim leading/trailing blanks, and collapse multiple embedded blanks to a
110911fce282SBaptiste Daroussin * single space. Return index to last character in the buffer.
111098e903e7SBaptiste Daroussin */
111111fce282SBaptiste Daroussin static int
trim_blanks(char * buffer)111211fce282SBaptiste Daroussin trim_blanks(char *buffer)
111311fce282SBaptiste Daroussin {
111411fce282SBaptiste Daroussin if (*buffer != '\0')
111511fce282SBaptiste Daroussin {
111611fce282SBaptiste Daroussin char *d = buffer;
111711fce282SBaptiste Daroussin char *s = after_blanks(d);
111811fce282SBaptiste Daroussin
111911fce282SBaptiste Daroussin while ((*d++ = *s++) != '\0')
112011fce282SBaptiste Daroussin {
112111fce282SBaptiste Daroussin ;
112211fce282SBaptiste Daroussin }
112311fce282SBaptiste Daroussin
112411fce282SBaptiste Daroussin --d;
112511fce282SBaptiste Daroussin while ((--d != buffer) && isspace(UCH(*d)))
112611fce282SBaptiste Daroussin *d = '\0';
112711fce282SBaptiste Daroussin
112811fce282SBaptiste Daroussin for (s = d = buffer; (*d++ = *s++) != '\0';)
112911fce282SBaptiste Daroussin {
113011fce282SBaptiste Daroussin if (isspace(UCH(*s)))
113111fce282SBaptiste Daroussin {
113211fce282SBaptiste Daroussin *s = ' ';
113311fce282SBaptiste Daroussin while (isspace(UCH(*s)))
113411fce282SBaptiste Daroussin {
113511fce282SBaptiste Daroussin *s++ = ' ';
113611fce282SBaptiste Daroussin }
113711fce282SBaptiste Daroussin --s;
113811fce282SBaptiste Daroussin }
113911fce282SBaptiste Daroussin }
114011fce282SBaptiste Daroussin }
114111fce282SBaptiste Daroussin
114211fce282SBaptiste Daroussin return (int)strlen(buffer) - 1;
114311fce282SBaptiste Daroussin }
114411fce282SBaptiste Daroussin
114511fce282SBaptiste Daroussin /*
114611fce282SBaptiste Daroussin * Scan forward in the current line-buffer looking for a right-curly bracket.
114711fce282SBaptiste Daroussin *
114811fce282SBaptiste Daroussin * Parameters begin with a left-curly bracket, and continue until there are no
114911fce282SBaptiste Daroussin * more interesting characters after the last right-curly bracket on the
115011fce282SBaptiste Daroussin * current line. Bison documents parameters as separated like this:
115111fce282SBaptiste Daroussin * {type param1} {type2 param2}
115211fce282SBaptiste Daroussin * but also accepts commas (although some versions of bison mishandle this)
115311fce282SBaptiste Daroussin * {type param1, type2 param2}
115411fce282SBaptiste Daroussin */
115511fce282SBaptiste Daroussin static int
more_curly(void)115611fce282SBaptiste Daroussin more_curly(void)
115711fce282SBaptiste Daroussin {
115811fce282SBaptiste Daroussin int result = 0;
115911fce282SBaptiste Daroussin int finish = 0;
1160*822ca327SBaptiste Daroussin save_line();
116111fce282SBaptiste Daroussin do
116211fce282SBaptiste Daroussin {
116311fce282SBaptiste Daroussin switch (next_inline())
116411fce282SBaptiste Daroussin {
116511fce282SBaptiste Daroussin case 0:
116611fce282SBaptiste Daroussin case '\n':
116711fce282SBaptiste Daroussin finish = 1;
116811fce282SBaptiste Daroussin break;
116911fce282SBaptiste Daroussin case R_CURL:
117011fce282SBaptiste Daroussin finish = 1;
117111fce282SBaptiste Daroussin result = 1;
117211fce282SBaptiste Daroussin break;
117311fce282SBaptiste Daroussin }
117411fce282SBaptiste Daroussin ++cptr;
117511fce282SBaptiste Daroussin }
117611fce282SBaptiste Daroussin while (!finish);
1177*822ca327SBaptiste Daroussin restore_line();
117811fce282SBaptiste Daroussin return result;
117911fce282SBaptiste Daroussin }
118011fce282SBaptiste Daroussin
118198e903e7SBaptiste Daroussin static void
save_param(int k,char * buffer,int name,int type2)118211fce282SBaptiste Daroussin save_param(int k, char *buffer, int name, int type2)
118398e903e7SBaptiste Daroussin {
118498e903e7SBaptiste Daroussin param *head, *p;
118598e903e7SBaptiste Daroussin
11863e066022SBaptiste Daroussin p = TMALLOC(param, 1);
118798e903e7SBaptiste Daroussin NO_SPACE(p);
118898e903e7SBaptiste Daroussin
118911fce282SBaptiste Daroussin p->type2 = strdup(buffer + type2);
119098e903e7SBaptiste Daroussin NO_SPACE(p->type2);
119111fce282SBaptiste Daroussin buffer[type2] = '\0';
119211fce282SBaptiste Daroussin (void)trim_blanks(p->type2);
119398e903e7SBaptiste Daroussin
1194*822ca327SBaptiste Daroussin if (!IS_ALNUM(buffer[name]))
1195*822ca327SBaptiste Daroussin {
1196*822ca327SBaptiste Daroussin int n;
1197*822ca327SBaptiste Daroussin for (n = name - 1; n >= 0; --n)
1198*822ca327SBaptiste Daroussin {
1199*822ca327SBaptiste Daroussin if (!isspace(UCH(buffer[n])))
1200*822ca327SBaptiste Daroussin {
1201*822ca327SBaptiste Daroussin break;
1202*822ca327SBaptiste Daroussin }
1203*822ca327SBaptiste Daroussin }
1204*822ca327SBaptiste Daroussin while (n > 0)
1205*822ca327SBaptiste Daroussin {
1206*822ca327SBaptiste Daroussin if (!IS_ALNUM(UCH(buffer[n - 1])))
1207*822ca327SBaptiste Daroussin break;
1208*822ca327SBaptiste Daroussin --n;
1209*822ca327SBaptiste Daroussin }
1210*822ca327SBaptiste Daroussin name = n;
1211*822ca327SBaptiste Daroussin }
121211fce282SBaptiste Daroussin p->name = strdup(buffer + name);
121398e903e7SBaptiste Daroussin NO_SPACE(p->name);
121411fce282SBaptiste Daroussin buffer[name] = '\0';
121511fce282SBaptiste Daroussin (void)trim_blanks(p->name);
121698e903e7SBaptiste Daroussin
121711fce282SBaptiste Daroussin p->type = strdup(buffer);
121811fce282SBaptiste Daroussin NO_SPACE(p->type);
121911fce282SBaptiste Daroussin (void)trim_blanks(p->type);
122098e903e7SBaptiste Daroussin
122198e903e7SBaptiste Daroussin if (k == LEX_PARAM)
122298e903e7SBaptiste Daroussin head = lex_param;
122398e903e7SBaptiste Daroussin else
122498e903e7SBaptiste Daroussin head = parse_param;
122598e903e7SBaptiste Daroussin
122698e903e7SBaptiste Daroussin if (head != NULL)
122798e903e7SBaptiste Daroussin {
122898e903e7SBaptiste Daroussin while (head->next)
122998e903e7SBaptiste Daroussin head = head->next;
123098e903e7SBaptiste Daroussin head->next = p;
123198e903e7SBaptiste Daroussin }
123298e903e7SBaptiste Daroussin else
123398e903e7SBaptiste Daroussin {
123498e903e7SBaptiste Daroussin if (k == LEX_PARAM)
123598e903e7SBaptiste Daroussin lex_param = p;
123698e903e7SBaptiste Daroussin else
123798e903e7SBaptiste Daroussin parse_param = p;
123898e903e7SBaptiste Daroussin }
123998e903e7SBaptiste Daroussin p->next = NULL;
124011fce282SBaptiste Daroussin }
124111fce282SBaptiste Daroussin
124211fce282SBaptiste Daroussin /*
124311fce282SBaptiste Daroussin * Keep a linked list of parameters. This may be multi-line, if the trailing
124411fce282SBaptiste Daroussin * right-curly bracket is absent.
124511fce282SBaptiste Daroussin */
124611fce282SBaptiste Daroussin static void
copy_param(int k)124711fce282SBaptiste Daroussin copy_param(int k)
124811fce282SBaptiste Daroussin {
124911fce282SBaptiste Daroussin int c;
125011fce282SBaptiste Daroussin int name, type2;
125111fce282SBaptiste Daroussin int curly = 0;
125211fce282SBaptiste Daroussin char *buf = 0;
125311fce282SBaptiste Daroussin int i = -1;
125411fce282SBaptiste Daroussin size_t buf_size = 0;
125511fce282SBaptiste Daroussin int st_lineno = lineno;
125611fce282SBaptiste Daroussin char *comma;
125711fce282SBaptiste Daroussin
125811fce282SBaptiste Daroussin do
125911fce282SBaptiste Daroussin {
126011fce282SBaptiste Daroussin int state = curly;
126111fce282SBaptiste Daroussin c = next_inline();
126211fce282SBaptiste Daroussin switch (c)
126311fce282SBaptiste Daroussin {
126411fce282SBaptiste Daroussin case EOF:
126511fce282SBaptiste Daroussin unexpected_EOF();
126611fce282SBaptiste Daroussin break;
126711fce282SBaptiste Daroussin case L_CURL:
126811fce282SBaptiste Daroussin if (curly == 1)
126911fce282SBaptiste Daroussin {
127011fce282SBaptiste Daroussin goto oops;
127111fce282SBaptiste Daroussin }
127211fce282SBaptiste Daroussin curly = 1;
127311fce282SBaptiste Daroussin st_lineno = lineno;
127411fce282SBaptiste Daroussin break;
127511fce282SBaptiste Daroussin case R_CURL:
127611fce282SBaptiste Daroussin if (curly != 1)
127711fce282SBaptiste Daroussin {
127811fce282SBaptiste Daroussin goto oops;
127911fce282SBaptiste Daroussin }
128011fce282SBaptiste Daroussin curly = 2;
128111fce282SBaptiste Daroussin break;
128211fce282SBaptiste Daroussin case '\n':
128311fce282SBaptiste Daroussin if (curly == 0)
128411fce282SBaptiste Daroussin {
128511fce282SBaptiste Daroussin goto oops;
128611fce282SBaptiste Daroussin }
128711fce282SBaptiste Daroussin break;
128811fce282SBaptiste Daroussin case '%':
128911fce282SBaptiste Daroussin if ((curly == 1) && (cptr == line))
129011fce282SBaptiste Daroussin {
129111fce282SBaptiste Daroussin lineno = st_lineno;
129211fce282SBaptiste Daroussin missing_brace();
129311fce282SBaptiste Daroussin }
129411fce282SBaptiste Daroussin /* FALLTHRU */
129511fce282SBaptiste Daroussin case '"':
129611fce282SBaptiste Daroussin case '\'':
129711fce282SBaptiste Daroussin goto oops;
129811fce282SBaptiste Daroussin default:
129911fce282SBaptiste Daroussin if (curly == 0 && !isspace(UCH(c)))
130011fce282SBaptiste Daroussin {
130111fce282SBaptiste Daroussin goto oops;
130211fce282SBaptiste Daroussin }
130311fce282SBaptiste Daroussin break;
130411fce282SBaptiste Daroussin }
130511fce282SBaptiste Daroussin if (buf == 0)
130611fce282SBaptiste Daroussin {
130711fce282SBaptiste Daroussin buf_size = (size_t)linesize;
130811fce282SBaptiste Daroussin buf = TMALLOC(char, buf_size);
13098e022d3cSDag-Erling Smørgrav NO_SPACE(buf);
131011fce282SBaptiste Daroussin }
131111fce282SBaptiste Daroussin else if (c == '\n')
131211fce282SBaptiste Daroussin {
13138e022d3cSDag-Erling Smørgrav char *tmp;
13148e022d3cSDag-Erling Smørgrav
131511fce282SBaptiste Daroussin get_line();
1316c5b5d71aSJung-uk Kim if (line == NULL)
131711fce282SBaptiste Daroussin unexpected_EOF();
131811fce282SBaptiste Daroussin --cptr;
131911fce282SBaptiste Daroussin buf_size += (size_t)linesize;
13208e022d3cSDag-Erling Smørgrav tmp = TREALLOC(char, buf, buf_size);
13218e022d3cSDag-Erling Smørgrav NO_SPACE(tmp);
13228e022d3cSDag-Erling Smørgrav buf = tmp;
132311fce282SBaptiste Daroussin }
132411fce282SBaptiste Daroussin if (curly)
132511fce282SBaptiste Daroussin {
132611fce282SBaptiste Daroussin if ((state == 2) && (c == L_CURL))
132711fce282SBaptiste Daroussin {
132811fce282SBaptiste Daroussin buf[++i] = ',';
132911fce282SBaptiste Daroussin }
133011fce282SBaptiste Daroussin else if ((state == 2) && isspace(UCH(c)))
133111fce282SBaptiste Daroussin {
133211fce282SBaptiste Daroussin ;
133311fce282SBaptiste Daroussin }
133411fce282SBaptiste Daroussin else if ((c != L_CURL) && (c != R_CURL))
133511fce282SBaptiste Daroussin {
133611fce282SBaptiste Daroussin buf[++i] = (char)c;
133711fce282SBaptiste Daroussin }
133811fce282SBaptiste Daroussin }
133911fce282SBaptiste Daroussin cptr++;
134011fce282SBaptiste Daroussin }
134111fce282SBaptiste Daroussin while (curly < 2 || more_curly());
134211fce282SBaptiste Daroussin
134311fce282SBaptiste Daroussin if (i == 0)
134411fce282SBaptiste Daroussin {
134511fce282SBaptiste Daroussin if (curly == 1)
134611fce282SBaptiste Daroussin {
134711fce282SBaptiste Daroussin lineno = st_lineno;
134811fce282SBaptiste Daroussin missing_brace();
134911fce282SBaptiste Daroussin }
135011fce282SBaptiste Daroussin goto oops;
135111fce282SBaptiste Daroussin }
135211fce282SBaptiste Daroussin
13532aca18c7SJung-uk Kim buf[++i] = '\0';
135420afc491SJung-uk Kim (void)trim_blanks(buf);
135511fce282SBaptiste Daroussin
135611fce282SBaptiste Daroussin comma = buf - 1;
135711fce282SBaptiste Daroussin do
135811fce282SBaptiste Daroussin {
135911fce282SBaptiste Daroussin char *parms = (comma + 1);
136011fce282SBaptiste Daroussin comma = strchr(parms, ',');
136111fce282SBaptiste Daroussin if (comma != 0)
136211fce282SBaptiste Daroussin *comma = '\0';
136311fce282SBaptiste Daroussin
136411fce282SBaptiste Daroussin (void)trim_blanks(parms);
136511fce282SBaptiste Daroussin i = (int)strlen(parms) - 1;
136611fce282SBaptiste Daroussin if (i < 0)
136711fce282SBaptiste Daroussin {
136811fce282SBaptiste Daroussin goto oops;
136911fce282SBaptiste Daroussin }
137011fce282SBaptiste Daroussin
137111fce282SBaptiste Daroussin if (parms[i] == ']')
137211fce282SBaptiste Daroussin {
137311fce282SBaptiste Daroussin int level = 1;
13748e022d3cSDag-Erling Smørgrav while (i >= 0)
137511fce282SBaptiste Daroussin {
13768e022d3cSDag-Erling Smørgrav char ch = parms[i--];
13778e022d3cSDag-Erling Smørgrav if (ch == ']')
13788e022d3cSDag-Erling Smørgrav {
137911fce282SBaptiste Daroussin ++level;
13808e022d3cSDag-Erling Smørgrav }
13818e022d3cSDag-Erling Smørgrav else if (ch == '[')
13828e022d3cSDag-Erling Smørgrav {
13838e022d3cSDag-Erling Smørgrav if (--level <= 1)
13848e022d3cSDag-Erling Smørgrav {
13858e022d3cSDag-Erling Smørgrav ++i;
13868e022d3cSDag-Erling Smørgrav break;
13878e022d3cSDag-Erling Smørgrav }
13888e022d3cSDag-Erling Smørgrav }
138911fce282SBaptiste Daroussin }
139011fce282SBaptiste Daroussin if (i <= 0)
139111fce282SBaptiste Daroussin unexpected_EOF();
139211fce282SBaptiste Daroussin type2 = i--;
139311fce282SBaptiste Daroussin }
139411fce282SBaptiste Daroussin else
139511fce282SBaptiste Daroussin {
139611fce282SBaptiste Daroussin type2 = i + 1;
139711fce282SBaptiste Daroussin }
139811fce282SBaptiste Daroussin
1399*822ca327SBaptiste Daroussin while (i > 0 && IS_ALNUM(UCH(parms[i])))
140011fce282SBaptiste Daroussin i--;
140111fce282SBaptiste Daroussin
140211fce282SBaptiste Daroussin if (!isspace(UCH(parms[i])) && parms[i] != '*')
140311fce282SBaptiste Daroussin goto oops;
140411fce282SBaptiste Daroussin
140511fce282SBaptiste Daroussin name = i + 1;
140611fce282SBaptiste Daroussin
140711fce282SBaptiste Daroussin save_param(k, parms, name, type2);
140811fce282SBaptiste Daroussin }
140911fce282SBaptiste Daroussin while (comma != 0);
141011fce282SBaptiste Daroussin FREE(buf);
141198e903e7SBaptiste Daroussin return;
141298e903e7SBaptiste Daroussin
141311fce282SBaptiste Daroussin oops:
141411fce282SBaptiste Daroussin FREE(buf);
141598e903e7SBaptiste Daroussin syntax_error(lineno, line, cptr);
141698e903e7SBaptiste Daroussin }
141798e903e7SBaptiste Daroussin
141898e903e7SBaptiste Daroussin static int
hexval(int c)141998e903e7SBaptiste Daroussin hexval(int c)
142098e903e7SBaptiste Daroussin {
142198e903e7SBaptiste Daroussin if (c >= '0' && c <= '9')
142298e903e7SBaptiste Daroussin return (c - '0');
142398e903e7SBaptiste Daroussin if (c >= 'A' && c <= 'F')
142498e903e7SBaptiste Daroussin return (c - 'A' + 10);
142598e903e7SBaptiste Daroussin if (c >= 'a' && c <= 'f')
142698e903e7SBaptiste Daroussin return (c - 'a' + 10);
142798e903e7SBaptiste Daroussin return (-1);
142898e903e7SBaptiste Daroussin }
142998e903e7SBaptiste Daroussin
143098e903e7SBaptiste Daroussin static bucket *
get_literal(void)143198e903e7SBaptiste Daroussin get_literal(void)
143298e903e7SBaptiste Daroussin {
143398e903e7SBaptiste Daroussin int c, quote;
143498e903e7SBaptiste Daroussin int i;
143598e903e7SBaptiste Daroussin int n;
143698e903e7SBaptiste Daroussin char *s;
143798e903e7SBaptiste Daroussin bucket *bp;
14382aca18c7SJung-uk Kim struct ainfo a;
1439*822ca327SBaptiste Daroussin
1440*822ca327SBaptiste Daroussin begin_ainfo(a, 0);
144198e903e7SBaptiste Daroussin
144298e903e7SBaptiste Daroussin quote = *cptr++;
144398e903e7SBaptiste Daroussin cinc = 0;
144498e903e7SBaptiste Daroussin for (;;)
144598e903e7SBaptiste Daroussin {
144698e903e7SBaptiste Daroussin c = *cptr++;
144798e903e7SBaptiste Daroussin if (c == quote)
144898e903e7SBaptiste Daroussin break;
144998e903e7SBaptiste Daroussin if (c == '\n')
14502aca18c7SJung-uk Kim unterminated_string(&a);
145198e903e7SBaptiste Daroussin if (c == '\\')
145298e903e7SBaptiste Daroussin {
145398e903e7SBaptiste Daroussin char *c_cptr = cptr - 1;
145498e903e7SBaptiste Daroussin
145598e903e7SBaptiste Daroussin c = *cptr++;
145698e903e7SBaptiste Daroussin switch (c)
145798e903e7SBaptiste Daroussin {
145898e903e7SBaptiste Daroussin case '\n':
145998e903e7SBaptiste Daroussin get_line();
1460c5b5d71aSJung-uk Kim if (line == NULL)
14612aca18c7SJung-uk Kim unterminated_string(&a);
146298e903e7SBaptiste Daroussin continue;
146398e903e7SBaptiste Daroussin
146498e903e7SBaptiste Daroussin case '0':
146598e903e7SBaptiste Daroussin case '1':
146698e903e7SBaptiste Daroussin case '2':
146798e903e7SBaptiste Daroussin case '3':
146898e903e7SBaptiste Daroussin case '4':
146998e903e7SBaptiste Daroussin case '5':
147098e903e7SBaptiste Daroussin case '6':
147198e903e7SBaptiste Daroussin case '7':
147298e903e7SBaptiste Daroussin n = c - '0';
147398e903e7SBaptiste Daroussin c = *cptr;
147498e903e7SBaptiste Daroussin if (IS_OCTAL(c))
147598e903e7SBaptiste Daroussin {
147698e903e7SBaptiste Daroussin n = (n << 3) + (c - '0');
147798e903e7SBaptiste Daroussin c = *++cptr;
147898e903e7SBaptiste Daroussin if (IS_OCTAL(c))
147998e903e7SBaptiste Daroussin {
148098e903e7SBaptiste Daroussin n = (n << 3) + (c - '0');
148198e903e7SBaptiste Daroussin ++cptr;
148298e903e7SBaptiste Daroussin }
148398e903e7SBaptiste Daroussin }
148498e903e7SBaptiste Daroussin if (n > MAXCHAR)
148598e903e7SBaptiste Daroussin illegal_character(c_cptr);
148698e903e7SBaptiste Daroussin c = n;
148798e903e7SBaptiste Daroussin break;
148898e903e7SBaptiste Daroussin
148998e903e7SBaptiste Daroussin case 'x':
149098e903e7SBaptiste Daroussin c = *cptr++;
149198e903e7SBaptiste Daroussin n = hexval(c);
149298e903e7SBaptiste Daroussin if (n < 0 || n >= 16)
149398e903e7SBaptiste Daroussin illegal_character(c_cptr);
149498e903e7SBaptiste Daroussin for (;;)
149598e903e7SBaptiste Daroussin {
149698e903e7SBaptiste Daroussin c = *cptr;
149798e903e7SBaptiste Daroussin i = hexval(c);
149898e903e7SBaptiste Daroussin if (i < 0 || i >= 16)
149998e903e7SBaptiste Daroussin break;
150098e903e7SBaptiste Daroussin ++cptr;
150198e903e7SBaptiste Daroussin n = (n << 4) + i;
150298e903e7SBaptiste Daroussin if (n > MAXCHAR)
150398e903e7SBaptiste Daroussin illegal_character(c_cptr);
150498e903e7SBaptiste Daroussin }
150598e903e7SBaptiste Daroussin c = n;
150698e903e7SBaptiste Daroussin break;
150798e903e7SBaptiste Daroussin
150898e903e7SBaptiste Daroussin case 'a':
150998e903e7SBaptiste Daroussin c = 7;
151098e903e7SBaptiste Daroussin break;
151198e903e7SBaptiste Daroussin case 'b':
151298e903e7SBaptiste Daroussin c = '\b';
151398e903e7SBaptiste Daroussin break;
151498e903e7SBaptiste Daroussin case 'f':
151598e903e7SBaptiste Daroussin c = '\f';
151698e903e7SBaptiste Daroussin break;
151798e903e7SBaptiste Daroussin case 'n':
151898e903e7SBaptiste Daroussin c = '\n';
151998e903e7SBaptiste Daroussin break;
152098e903e7SBaptiste Daroussin case 'r':
152198e903e7SBaptiste Daroussin c = '\r';
152298e903e7SBaptiste Daroussin break;
152398e903e7SBaptiste Daroussin case 't':
152498e903e7SBaptiste Daroussin c = '\t';
152598e903e7SBaptiste Daroussin break;
152698e903e7SBaptiste Daroussin case 'v':
152798e903e7SBaptiste Daroussin c = '\v';
152898e903e7SBaptiste Daroussin break;
152998e903e7SBaptiste Daroussin }
153098e903e7SBaptiste Daroussin }
153198e903e7SBaptiste Daroussin cachec(c);
153298e903e7SBaptiste Daroussin }
1533*822ca327SBaptiste Daroussin end_ainfo(a);
153498e903e7SBaptiste Daroussin
153598e903e7SBaptiste Daroussin n = cinc;
15363e066022SBaptiste Daroussin s = TMALLOC(char, n);
153798e903e7SBaptiste Daroussin NO_SPACE(s);
153898e903e7SBaptiste Daroussin
153998e903e7SBaptiste Daroussin for (i = 0; i < n; ++i)
154098e903e7SBaptiste Daroussin s[i] = cache[i];
154198e903e7SBaptiste Daroussin
154298e903e7SBaptiste Daroussin cinc = 0;
154398e903e7SBaptiste Daroussin if (n == 1)
154498e903e7SBaptiste Daroussin cachec('\'');
154598e903e7SBaptiste Daroussin else
154698e903e7SBaptiste Daroussin cachec('"');
154798e903e7SBaptiste Daroussin
154898e903e7SBaptiste Daroussin for (i = 0; i < n; ++i)
154998e903e7SBaptiste Daroussin {
155098e903e7SBaptiste Daroussin c = UCH(s[i]);
155198e903e7SBaptiste Daroussin if (c == '\\' || c == cache[0])
155298e903e7SBaptiste Daroussin {
155398e903e7SBaptiste Daroussin cachec('\\');
155498e903e7SBaptiste Daroussin cachec(c);
155598e903e7SBaptiste Daroussin }
1556b53bb29fSJung-uk Kim else if (isprint(UCH(c)))
155798e903e7SBaptiste Daroussin cachec(c);
155898e903e7SBaptiste Daroussin else
155998e903e7SBaptiste Daroussin {
156098e903e7SBaptiste Daroussin cachec('\\');
156198e903e7SBaptiste Daroussin switch (c)
156298e903e7SBaptiste Daroussin {
156398e903e7SBaptiste Daroussin case 7:
156498e903e7SBaptiste Daroussin cachec('a');
156598e903e7SBaptiste Daroussin break;
156698e903e7SBaptiste Daroussin case '\b':
156798e903e7SBaptiste Daroussin cachec('b');
156898e903e7SBaptiste Daroussin break;
156998e903e7SBaptiste Daroussin case '\f':
157098e903e7SBaptiste Daroussin cachec('f');
157198e903e7SBaptiste Daroussin break;
157298e903e7SBaptiste Daroussin case '\n':
157398e903e7SBaptiste Daroussin cachec('n');
157498e903e7SBaptiste Daroussin break;
157598e903e7SBaptiste Daroussin case '\r':
157698e903e7SBaptiste Daroussin cachec('r');
157798e903e7SBaptiste Daroussin break;
157898e903e7SBaptiste Daroussin case '\t':
157998e903e7SBaptiste Daroussin cachec('t');
158098e903e7SBaptiste Daroussin break;
158198e903e7SBaptiste Daroussin case '\v':
158298e903e7SBaptiste Daroussin cachec('v');
158398e903e7SBaptiste Daroussin break;
158498e903e7SBaptiste Daroussin default:
158598e903e7SBaptiste Daroussin cachec(((c >> 6) & 7) + '0');
158698e903e7SBaptiste Daroussin cachec(((c >> 3) & 7) + '0');
158798e903e7SBaptiste Daroussin cachec((c & 7) + '0');
158898e903e7SBaptiste Daroussin break;
158998e903e7SBaptiste Daroussin }
159098e903e7SBaptiste Daroussin }
159198e903e7SBaptiste Daroussin }
159298e903e7SBaptiste Daroussin
159398e903e7SBaptiste Daroussin if (n == 1)
159498e903e7SBaptiste Daroussin cachec('\'');
159598e903e7SBaptiste Daroussin else
159698e903e7SBaptiste Daroussin cachec('"');
159798e903e7SBaptiste Daroussin
159898e903e7SBaptiste Daroussin cachec(NUL);
159998e903e7SBaptiste Daroussin bp = lookup(cache);
160098e903e7SBaptiste Daroussin bp->class = TERM;
160198e903e7SBaptiste Daroussin if (n == 1 && bp->value == UNDEFINED)
160298e903e7SBaptiste Daroussin bp->value = UCH(*s);
160398e903e7SBaptiste Daroussin FREE(s);
160498e903e7SBaptiste Daroussin
160598e903e7SBaptiste Daroussin return (bp);
160698e903e7SBaptiste Daroussin }
160798e903e7SBaptiste Daroussin
160898e903e7SBaptiste Daroussin static int
is_reserved(char * name)160998e903e7SBaptiste Daroussin is_reserved(char *name)
161098e903e7SBaptiste Daroussin {
161198e903e7SBaptiste Daroussin if (strcmp(name, ".") == 0 ||
161298e903e7SBaptiste Daroussin strcmp(name, "$accept") == 0 ||
161398e903e7SBaptiste Daroussin strcmp(name, "$end") == 0)
161498e903e7SBaptiste Daroussin return (1);
161598e903e7SBaptiste Daroussin
161698e903e7SBaptiste Daroussin if (name[0] == '$' && name[1] == '$' && isdigit(UCH(name[2])))
161798e903e7SBaptiste Daroussin {
16188e022d3cSDag-Erling Smørgrav char *s = name + 3;
16198e022d3cSDag-Erling Smørgrav
162098e903e7SBaptiste Daroussin while (isdigit(UCH(*s)))
162198e903e7SBaptiste Daroussin ++s;
162298e903e7SBaptiste Daroussin if (*s == NUL)
162398e903e7SBaptiste Daroussin return (1);
162498e903e7SBaptiste Daroussin }
162598e903e7SBaptiste Daroussin
162698e903e7SBaptiste Daroussin return (0);
162798e903e7SBaptiste Daroussin }
162898e903e7SBaptiste Daroussin
162998e903e7SBaptiste Daroussin static bucket *
get_name(void)163098e903e7SBaptiste Daroussin get_name(void)
163198e903e7SBaptiste Daroussin {
163298e903e7SBaptiste Daroussin int c;
163398e903e7SBaptiste Daroussin
163498e903e7SBaptiste Daroussin cinc = 0;
163598e903e7SBaptiste Daroussin for (c = *cptr; IS_IDENT(c); c = *++cptr)
163698e903e7SBaptiste Daroussin cachec(c);
163798e903e7SBaptiste Daroussin cachec(NUL);
163898e903e7SBaptiste Daroussin
163998e903e7SBaptiste Daroussin if (is_reserved(cache))
164098e903e7SBaptiste Daroussin used_reserved(cache);
164198e903e7SBaptiste Daroussin
164298e903e7SBaptiste Daroussin return (lookup(cache));
164398e903e7SBaptiste Daroussin }
164498e903e7SBaptiste Daroussin
164598e903e7SBaptiste Daroussin static Value_t
get_number(void)164698e903e7SBaptiste Daroussin get_number(void)
164798e903e7SBaptiste Daroussin {
164898e903e7SBaptiste Daroussin int c;
1649b53bb29fSJung-uk Kim long n;
1650b53bb29fSJung-uk Kim char *base = cptr;
165198e903e7SBaptiste Daroussin
165298e903e7SBaptiste Daroussin n = 0;
1653b53bb29fSJung-uk Kim for (c = *cptr; isdigit(UCH(c)); c = *++cptr)
1654b53bb29fSJung-uk Kim {
1655b53bb29fSJung-uk Kim n = (10 * n + (c - '0'));
1656b53bb29fSJung-uk Kim if (n > MAXYYINT)
1657b53bb29fSJung-uk Kim {
1658b53bb29fSJung-uk Kim syntax_error(lineno, line, base);
1659b53bb29fSJung-uk Kim /*NOTREACHED */
1660b53bb29fSJung-uk Kim }
1661b53bb29fSJung-uk Kim }
166298e903e7SBaptiste Daroussin
1663b53bb29fSJung-uk Kim return (Value_t)(n);
166498e903e7SBaptiste Daroussin }
166598e903e7SBaptiste Daroussin
166698e903e7SBaptiste Daroussin static char *
cache_tag(char * tag,size_t len)16670c8de5b0SBaptiste Daroussin cache_tag(char *tag, size_t len)
16680c8de5b0SBaptiste Daroussin {
16690c8de5b0SBaptiste Daroussin int i;
16700c8de5b0SBaptiste Daroussin char *s;
16710c8de5b0SBaptiste Daroussin
16720c8de5b0SBaptiste Daroussin for (i = 0; i < ntags; ++i)
16730c8de5b0SBaptiste Daroussin {
16740c8de5b0SBaptiste Daroussin if (strncmp(tag, tag_table[i], len) == 0 &&
16750c8de5b0SBaptiste Daroussin tag_table[i][len] == NUL)
16760c8de5b0SBaptiste Daroussin return (tag_table[i]);
16770c8de5b0SBaptiste Daroussin }
16780c8de5b0SBaptiste Daroussin
16790c8de5b0SBaptiste Daroussin if (ntags >= tagmax)
16800c8de5b0SBaptiste Daroussin {
16810c8de5b0SBaptiste Daroussin tagmax += 16;
16820c8de5b0SBaptiste Daroussin tag_table =
16830c8de5b0SBaptiste Daroussin (tag_table
16840c8de5b0SBaptiste Daroussin ? TREALLOC(char *, tag_table, tagmax)
16850c8de5b0SBaptiste Daroussin : TMALLOC(char *, tagmax));
16860c8de5b0SBaptiste Daroussin NO_SPACE(tag_table);
16870c8de5b0SBaptiste Daroussin }
16880c8de5b0SBaptiste Daroussin
16890c8de5b0SBaptiste Daroussin s = TMALLOC(char, len + 1);
16900c8de5b0SBaptiste Daroussin NO_SPACE(s);
16910c8de5b0SBaptiste Daroussin
16920c8de5b0SBaptiste Daroussin strncpy(s, tag, len);
16930c8de5b0SBaptiste Daroussin s[len] = 0;
16940c8de5b0SBaptiste Daroussin tag_table[ntags++] = s;
16950c8de5b0SBaptiste Daroussin return s;
16960c8de5b0SBaptiste Daroussin }
16970c8de5b0SBaptiste Daroussin
16980c8de5b0SBaptiste Daroussin static char *
get_tag(void)169998e903e7SBaptiste Daroussin get_tag(void)
170098e903e7SBaptiste Daroussin {
170198e903e7SBaptiste Daroussin int c;
170298e903e7SBaptiste Daroussin int t_lineno = lineno;
170398e903e7SBaptiste Daroussin char *t_line = dup_line();
170498e903e7SBaptiste Daroussin char *t_cptr = t_line + (cptr - line);
170598e903e7SBaptiste Daroussin
170698e903e7SBaptiste Daroussin ++cptr;
170798e903e7SBaptiste Daroussin c = nextc();
170898e903e7SBaptiste Daroussin if (c == EOF)
170998e903e7SBaptiste Daroussin unexpected_EOF();
1710b53bb29fSJung-uk Kim if (!IS_NAME1(c))
171198e903e7SBaptiste Daroussin illegal_tag(t_lineno, t_line, t_cptr);
171298e903e7SBaptiste Daroussin
171398e903e7SBaptiste Daroussin cinc = 0;
171498e903e7SBaptiste Daroussin do
171598e903e7SBaptiste Daroussin {
171698e903e7SBaptiste Daroussin cachec(c);
171798e903e7SBaptiste Daroussin c = *++cptr;
171898e903e7SBaptiste Daroussin }
171998e903e7SBaptiste Daroussin while (IS_IDENT(c));
172098e903e7SBaptiste Daroussin cachec(NUL);
172198e903e7SBaptiste Daroussin
172298e903e7SBaptiste Daroussin c = nextc();
172398e903e7SBaptiste Daroussin if (c == EOF)
172498e903e7SBaptiste Daroussin unexpected_EOF();
172598e903e7SBaptiste Daroussin if (c != '>')
172698e903e7SBaptiste Daroussin illegal_tag(t_lineno, t_line, t_cptr);
172798e903e7SBaptiste Daroussin ++cptr;
172898e903e7SBaptiste Daroussin
172998e903e7SBaptiste Daroussin FREE(t_line);
17300c8de5b0SBaptiste Daroussin havetags = 1;
17310c8de5b0SBaptiste Daroussin return cache_tag(cache, (size_t)cinc);
173298e903e7SBaptiste Daroussin }
173398e903e7SBaptiste Daroussin
17340c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
17350c8de5b0SBaptiste Daroussin static char *
scan_id(void)17360c8de5b0SBaptiste Daroussin scan_id(void)
173798e903e7SBaptiste Daroussin {
17380c8de5b0SBaptiste Daroussin char *b = cptr;
173998e903e7SBaptiste Daroussin
1740b53bb29fSJung-uk Kim while (IS_NAME2(UCH(*cptr)))
17410c8de5b0SBaptiste Daroussin cptr++;
17420c8de5b0SBaptiste Daroussin return cache_tag(b, (size_t)(cptr - b));
174398e903e7SBaptiste Daroussin }
17440c8de5b0SBaptiste Daroussin #endif
174598e903e7SBaptiste Daroussin
174698e903e7SBaptiste Daroussin static void
declare_tokens(int assoc)174798e903e7SBaptiste Daroussin declare_tokens(int assoc)
174898e903e7SBaptiste Daroussin {
174998e903e7SBaptiste Daroussin int c;
175098e903e7SBaptiste Daroussin bucket *bp;
175198e903e7SBaptiste Daroussin Value_t value;
175298e903e7SBaptiste Daroussin char *tag = 0;
175398e903e7SBaptiste Daroussin
175498e903e7SBaptiste Daroussin if (assoc != TOKEN)
175598e903e7SBaptiste Daroussin ++prec;
175698e903e7SBaptiste Daroussin
175798e903e7SBaptiste Daroussin c = nextc();
175898e903e7SBaptiste Daroussin if (c == EOF)
175998e903e7SBaptiste Daroussin unexpected_EOF();
176098e903e7SBaptiste Daroussin if (c == '<')
176198e903e7SBaptiste Daroussin {
176298e903e7SBaptiste Daroussin tag = get_tag();
176398e903e7SBaptiste Daroussin c = nextc();
176498e903e7SBaptiste Daroussin if (c == EOF)
176598e903e7SBaptiste Daroussin unexpected_EOF();
176698e903e7SBaptiste Daroussin }
176798e903e7SBaptiste Daroussin
176898e903e7SBaptiste Daroussin for (;;)
176998e903e7SBaptiste Daroussin {
1770b53bb29fSJung-uk Kim if (isalpha(UCH(c)) || c == '_' || c == '.' || c == '$')
177198e903e7SBaptiste Daroussin bp = get_name();
177298e903e7SBaptiste Daroussin else if (c == '\'' || c == '"')
177398e903e7SBaptiste Daroussin bp = get_literal();
177498e903e7SBaptiste Daroussin else
177598e903e7SBaptiste Daroussin return;
177698e903e7SBaptiste Daroussin
177798e903e7SBaptiste Daroussin if (bp == goal)
177898e903e7SBaptiste Daroussin tokenized_start(bp->name);
177998e903e7SBaptiste Daroussin bp->class = TERM;
178098e903e7SBaptiste Daroussin
178198e903e7SBaptiste Daroussin if (tag)
178298e903e7SBaptiste Daroussin {
178398e903e7SBaptiste Daroussin if (bp->tag && tag != bp->tag)
178498e903e7SBaptiste Daroussin retyped_warning(bp->name);
178598e903e7SBaptiste Daroussin bp->tag = tag;
178698e903e7SBaptiste Daroussin }
178798e903e7SBaptiste Daroussin
178898e903e7SBaptiste Daroussin if (assoc != TOKEN)
178998e903e7SBaptiste Daroussin {
179098e903e7SBaptiste Daroussin if (bp->prec && prec != bp->prec)
179198e903e7SBaptiste Daroussin reprec_warning(bp->name);
179298e903e7SBaptiste Daroussin bp->assoc = (Assoc_t)assoc;
179398e903e7SBaptiste Daroussin bp->prec = prec;
179498e903e7SBaptiste Daroussin }
179598e903e7SBaptiste Daroussin
179698e903e7SBaptiste Daroussin c = nextc();
179798e903e7SBaptiste Daroussin if (c == EOF)
179898e903e7SBaptiste Daroussin unexpected_EOF();
179998e903e7SBaptiste Daroussin
1800b53bb29fSJung-uk Kim if (isdigit(UCH(c)))
180198e903e7SBaptiste Daroussin {
180298e903e7SBaptiste Daroussin value = get_number();
180398e903e7SBaptiste Daroussin if (bp->value != UNDEFINED && value != bp->value)
180498e903e7SBaptiste Daroussin revalued_warning(bp->name);
180598e903e7SBaptiste Daroussin bp->value = value;
180698e903e7SBaptiste Daroussin c = nextc();
180798e903e7SBaptiste Daroussin if (c == EOF)
180898e903e7SBaptiste Daroussin unexpected_EOF();
180998e903e7SBaptiste Daroussin }
181098e903e7SBaptiste Daroussin }
181198e903e7SBaptiste Daroussin }
181298e903e7SBaptiste Daroussin
181398e903e7SBaptiste Daroussin /*
181498e903e7SBaptiste Daroussin * %expect requires special handling
181598e903e7SBaptiste Daroussin * as it really isn't part of the yacc
181698e903e7SBaptiste Daroussin * grammar only a flag for yacc proper.
181798e903e7SBaptiste Daroussin */
181898e903e7SBaptiste Daroussin static void
declare_expect(int assoc)181998e903e7SBaptiste Daroussin declare_expect(int assoc)
182098e903e7SBaptiste Daroussin {
182198e903e7SBaptiste Daroussin int c;
182298e903e7SBaptiste Daroussin
182398e903e7SBaptiste Daroussin if (assoc != EXPECT && assoc != EXPECT_RR)
182498e903e7SBaptiste Daroussin ++prec;
182598e903e7SBaptiste Daroussin
182698e903e7SBaptiste Daroussin /*
182798e903e7SBaptiste Daroussin * Stay away from nextc - doesn't
182898e903e7SBaptiste Daroussin * detect EOL and will read to EOF.
182998e903e7SBaptiste Daroussin */
183098e903e7SBaptiste Daroussin c = *++cptr;
183198e903e7SBaptiste Daroussin if (c == EOF)
183298e903e7SBaptiste Daroussin unexpected_EOF();
183398e903e7SBaptiste Daroussin
183498e903e7SBaptiste Daroussin for (;;)
183598e903e7SBaptiste Daroussin {
1836b53bb29fSJung-uk Kim if (isdigit(UCH(c)))
183798e903e7SBaptiste Daroussin {
183898e903e7SBaptiste Daroussin if (assoc == EXPECT)
183998e903e7SBaptiste Daroussin SRexpect = get_number();
184098e903e7SBaptiste Daroussin else
184198e903e7SBaptiste Daroussin RRexpect = get_number();
184298e903e7SBaptiste Daroussin break;
184398e903e7SBaptiste Daroussin }
184498e903e7SBaptiste Daroussin /*
184598e903e7SBaptiste Daroussin * Looking for number before EOL.
184698e903e7SBaptiste Daroussin * Spaces, tabs, and numbers are ok,
184798e903e7SBaptiste Daroussin * words, punc., etc. are syntax errors.
184898e903e7SBaptiste Daroussin */
1849b53bb29fSJung-uk Kim else if (c == '\n' || isalpha(UCH(c)) || !isspace(UCH(c)))
185098e903e7SBaptiste Daroussin {
185198e903e7SBaptiste Daroussin syntax_error(lineno, line, cptr);
185298e903e7SBaptiste Daroussin }
185398e903e7SBaptiste Daroussin else
185498e903e7SBaptiste Daroussin {
185598e903e7SBaptiste Daroussin c = *++cptr;
185698e903e7SBaptiste Daroussin if (c == EOF)
185798e903e7SBaptiste Daroussin unexpected_EOF();
185898e903e7SBaptiste Daroussin }
185998e903e7SBaptiste Daroussin }
186098e903e7SBaptiste Daroussin }
186198e903e7SBaptiste Daroussin
18620c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
186398e903e7SBaptiste Daroussin static void
declare_argtypes(bucket * bp)18640c8de5b0SBaptiste Daroussin declare_argtypes(bucket *bp)
186598e903e7SBaptiste Daroussin {
18660c8de5b0SBaptiste Daroussin char *tags[MAXARGS];
18678e022d3cSDag-Erling Smørgrav int args = 0;
186898e903e7SBaptiste Daroussin
18690c8de5b0SBaptiste Daroussin if (bp->args >= 0)
18700c8de5b0SBaptiste Daroussin retyped_warning(bp->name);
18710c8de5b0SBaptiste Daroussin cptr++; /* skip open paren */
18720c8de5b0SBaptiste Daroussin for (;;)
18730c8de5b0SBaptiste Daroussin {
18748e022d3cSDag-Erling Smørgrav int c = nextc();
187598e903e7SBaptiste Daroussin if (c == EOF)
187698e903e7SBaptiste Daroussin unexpected_EOF();
187798e903e7SBaptiste Daroussin if (c != '<')
187898e903e7SBaptiste Daroussin syntax_error(lineno, line, cptr);
18790c8de5b0SBaptiste Daroussin tags[args++] = get_tag();
18800c8de5b0SBaptiste Daroussin c = nextc();
18810c8de5b0SBaptiste Daroussin if (c == R_PAREN)
18820c8de5b0SBaptiste Daroussin break;
18830c8de5b0SBaptiste Daroussin if (c == EOF)
18840c8de5b0SBaptiste Daroussin unexpected_EOF();
18850c8de5b0SBaptiste Daroussin }
18860c8de5b0SBaptiste Daroussin cptr++; /* skip close paren */
18870c8de5b0SBaptiste Daroussin bp->args = args;
18880c8de5b0SBaptiste Daroussin bp->argnames = TMALLOC(char *, args);
18890c8de5b0SBaptiste Daroussin NO_SPACE(bp->argnames);
18900c8de5b0SBaptiste Daroussin bp->argtags = CALLOC(sizeof(char *), args + 1);
18910c8de5b0SBaptiste Daroussin NO_SPACE(bp->argtags);
18920c8de5b0SBaptiste Daroussin while (--args >= 0)
18930c8de5b0SBaptiste Daroussin {
18940c8de5b0SBaptiste Daroussin bp->argtags[args] = tags[args];
18950c8de5b0SBaptiste Daroussin bp->argnames[args] = NULL;
18960c8de5b0SBaptiste Daroussin }
18970c8de5b0SBaptiste Daroussin }
18980c8de5b0SBaptiste Daroussin #endif
18990c8de5b0SBaptiste Daroussin
1900*822ca327SBaptiste Daroussin static int
scan_blanks(void)1901*822ca327SBaptiste Daroussin scan_blanks(void)
1902*822ca327SBaptiste Daroussin {
1903*822ca327SBaptiste Daroussin int c;
1904*822ca327SBaptiste Daroussin
1905*822ca327SBaptiste Daroussin do
1906*822ca327SBaptiste Daroussin {
1907*822ca327SBaptiste Daroussin c = next_inline();
1908*822ca327SBaptiste Daroussin if (c == '\n')
1909*822ca327SBaptiste Daroussin {
1910*822ca327SBaptiste Daroussin ++cptr;
1911*822ca327SBaptiste Daroussin return 0;
1912*822ca327SBaptiste Daroussin }
1913*822ca327SBaptiste Daroussin else if (c == ' ' || c == '\t')
1914*822ca327SBaptiste Daroussin ++cptr;
1915*822ca327SBaptiste Daroussin else
1916*822ca327SBaptiste Daroussin break;
1917*822ca327SBaptiste Daroussin }
1918*822ca327SBaptiste Daroussin while (c == ' ' || c == '\t');
1919*822ca327SBaptiste Daroussin
1920*822ca327SBaptiste Daroussin return 1;
1921*822ca327SBaptiste Daroussin }
1922*822ca327SBaptiste Daroussin
1923*822ca327SBaptiste Daroussin static int
scan_ident(void)1924*822ca327SBaptiste Daroussin scan_ident(void)
1925*822ca327SBaptiste Daroussin {
1926*822ca327SBaptiste Daroussin int c;
1927*822ca327SBaptiste Daroussin
1928*822ca327SBaptiste Daroussin cinc = 0;
1929*822ca327SBaptiste Daroussin for (c = *cptr; IS_IDENT(c); c = *++cptr)
1930*822ca327SBaptiste Daroussin cachec(c);
1931*822ca327SBaptiste Daroussin cachec(NUL);
1932*822ca327SBaptiste Daroussin
1933*822ca327SBaptiste Daroussin return cinc;
1934*822ca327SBaptiste Daroussin }
1935*822ca327SBaptiste Daroussin
1936*822ca327SBaptiste Daroussin static void
hack_defines(void)1937*822ca327SBaptiste Daroussin hack_defines(void)
1938*822ca327SBaptiste Daroussin {
1939*822ca327SBaptiste Daroussin struct ainfo a;
1940*822ca327SBaptiste Daroussin
1941*822ca327SBaptiste Daroussin if (!scan_blanks())
1942*822ca327SBaptiste Daroussin return;
1943*822ca327SBaptiste Daroussin
1944*822ca327SBaptiste Daroussin begin_ainfo(a, 0);
1945*822ca327SBaptiste Daroussin if (!scan_ident())
1946*822ca327SBaptiste Daroussin {
1947*822ca327SBaptiste Daroussin end_ainfo(a);
1948*822ca327SBaptiste Daroussin }
1949*822ca327SBaptiste Daroussin
1950*822ca327SBaptiste Daroussin if (!strcmp(cache, "api.pure"))
1951*822ca327SBaptiste Daroussin {
1952*822ca327SBaptiste Daroussin end_ainfo(a);
1953*822ca327SBaptiste Daroussin scan_blanks();
1954*822ca327SBaptiste Daroussin begin_ainfo(a, 0);
1955*822ca327SBaptiste Daroussin scan_ident();
1956*822ca327SBaptiste Daroussin
1957*822ca327SBaptiste Daroussin if (!strcmp(cache, "false"))
1958*822ca327SBaptiste Daroussin pure_parser = 0;
1959*822ca327SBaptiste Daroussin else if (!strcmp(cache, "true")
1960*822ca327SBaptiste Daroussin || !strcmp(cache, "full")
1961*822ca327SBaptiste Daroussin || *cache == 0)
1962*822ca327SBaptiste Daroussin pure_parser = 1;
1963*822ca327SBaptiste Daroussin else
1964*822ca327SBaptiste Daroussin unexpected_value(&a);
1965*822ca327SBaptiste Daroussin end_ainfo(a);
1966*822ca327SBaptiste Daroussin }
1967*822ca327SBaptiste Daroussin else
1968*822ca327SBaptiste Daroussin {
1969*822ca327SBaptiste Daroussin unexpected_value(&a);
1970*822ca327SBaptiste Daroussin }
1971*822ca327SBaptiste Daroussin
1972*822ca327SBaptiste Daroussin while (next_inline() != '\n')
1973*822ca327SBaptiste Daroussin ++cptr;
1974*822ca327SBaptiste Daroussin }
1975*822ca327SBaptiste Daroussin
19760c8de5b0SBaptiste Daroussin static void
declare_types(void)19770c8de5b0SBaptiste Daroussin declare_types(void)
19780c8de5b0SBaptiste Daroussin {
19790c8de5b0SBaptiste Daroussin int c;
1980c5b5d71aSJung-uk Kim bucket *bp = NULL;
19810c8de5b0SBaptiste Daroussin char *tag = NULL;
19820c8de5b0SBaptiste Daroussin
19830c8de5b0SBaptiste Daroussin c = nextc();
19840c8de5b0SBaptiste Daroussin if (c == EOF)
19850c8de5b0SBaptiste Daroussin unexpected_EOF();
19860c8de5b0SBaptiste Daroussin if (c == '<')
198798e903e7SBaptiste Daroussin tag = get_tag();
198898e903e7SBaptiste Daroussin
198998e903e7SBaptiste Daroussin for (;;)
199098e903e7SBaptiste Daroussin {
199198e903e7SBaptiste Daroussin c = nextc();
19920c8de5b0SBaptiste Daroussin if (c == EOF)
19930c8de5b0SBaptiste Daroussin unexpected_EOF();
1994b53bb29fSJung-uk Kim if (isalpha(UCH(c)) || c == '_' || c == '.' || c == '$')
19950c8de5b0SBaptiste Daroussin {
199698e903e7SBaptiste Daroussin bp = get_name();
19970c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
19980c8de5b0SBaptiste Daroussin if (nextc() == L_PAREN)
19990c8de5b0SBaptiste Daroussin declare_argtypes(bp);
20000c8de5b0SBaptiste Daroussin else
20010c8de5b0SBaptiste Daroussin bp->args = 0;
20020c8de5b0SBaptiste Daroussin #endif
20030c8de5b0SBaptiste Daroussin }
200498e903e7SBaptiste Daroussin else if (c == '\'' || c == '"')
20050c8de5b0SBaptiste Daroussin {
200698e903e7SBaptiste Daroussin bp = get_literal();
20070c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
20080c8de5b0SBaptiste Daroussin bp->args = 0;
20090c8de5b0SBaptiste Daroussin #endif
20100c8de5b0SBaptiste Daroussin }
201198e903e7SBaptiste Daroussin else
201298e903e7SBaptiste Daroussin return;
201398e903e7SBaptiste Daroussin
20140c8de5b0SBaptiste Daroussin if (tag)
20150c8de5b0SBaptiste Daroussin {
201698e903e7SBaptiste Daroussin if (bp->tag && tag != bp->tag)
201798e903e7SBaptiste Daroussin retyped_warning(bp->name);
201898e903e7SBaptiste Daroussin bp->tag = tag;
201998e903e7SBaptiste Daroussin }
202098e903e7SBaptiste Daroussin }
20210c8de5b0SBaptiste Daroussin }
202298e903e7SBaptiste Daroussin
202398e903e7SBaptiste Daroussin static void
declare_start(void)202498e903e7SBaptiste Daroussin declare_start(void)
202598e903e7SBaptiste Daroussin {
202698e903e7SBaptiste Daroussin int c;
202798e903e7SBaptiste Daroussin bucket *bp;
202898e903e7SBaptiste Daroussin
202998e903e7SBaptiste Daroussin c = nextc();
203098e903e7SBaptiste Daroussin if (c == EOF)
203198e903e7SBaptiste Daroussin unexpected_EOF();
2032b53bb29fSJung-uk Kim if (!isalpha(UCH(c)) && c != '_' && c != '.' && c != '$')
203398e903e7SBaptiste Daroussin syntax_error(lineno, line, cptr);
203498e903e7SBaptiste Daroussin bp = get_name();
203598e903e7SBaptiste Daroussin if (bp->class == TERM)
203698e903e7SBaptiste Daroussin terminal_start(bp->name);
203798e903e7SBaptiste Daroussin if (goal && goal != bp)
203898e903e7SBaptiste Daroussin restarted_warning();
203998e903e7SBaptiste Daroussin goal = bp;
204098e903e7SBaptiste Daroussin }
204198e903e7SBaptiste Daroussin
204298e903e7SBaptiste Daroussin static void
read_declarations(void)204398e903e7SBaptiste Daroussin read_declarations(void)
204498e903e7SBaptiste Daroussin {
20450f86d14eSJung-uk Kim cache_size = CACHE_SIZE;
20463e066022SBaptiste Daroussin cache = TMALLOC(char, cache_size);
204798e903e7SBaptiste Daroussin NO_SPACE(cache);
204898e903e7SBaptiste Daroussin
204998e903e7SBaptiste Daroussin for (;;)
205098e903e7SBaptiste Daroussin {
20518e022d3cSDag-Erling Smørgrav int k;
20528e022d3cSDag-Erling Smørgrav int c = nextc();
20538e022d3cSDag-Erling Smørgrav
205498e903e7SBaptiste Daroussin if (c == EOF)
205598e903e7SBaptiste Daroussin unexpected_EOF();
205698e903e7SBaptiste Daroussin if (c != '%')
205798e903e7SBaptiste Daroussin syntax_error(lineno, line, cptr);
205898e903e7SBaptiste Daroussin switch (k = keyword())
205998e903e7SBaptiste Daroussin {
206098e903e7SBaptiste Daroussin case MARK:
206198e903e7SBaptiste Daroussin return;
206298e903e7SBaptiste Daroussin
206398e903e7SBaptiste Daroussin case IDENT:
206498e903e7SBaptiste Daroussin copy_ident();
206598e903e7SBaptiste Daroussin break;
206698e903e7SBaptiste Daroussin
2067b53bb29fSJung-uk Kim case XCODE:
2068b53bb29fSJung-uk Kim copy_code();
2069b53bb29fSJung-uk Kim break;
2070b53bb29fSJung-uk Kim
207198e903e7SBaptiste Daroussin case TEXT:
207298e903e7SBaptiste Daroussin copy_text();
207398e903e7SBaptiste Daroussin break;
207498e903e7SBaptiste Daroussin
207598e903e7SBaptiste Daroussin case UNION:
207698e903e7SBaptiste Daroussin copy_union();
207798e903e7SBaptiste Daroussin break;
207898e903e7SBaptiste Daroussin
207998e903e7SBaptiste Daroussin case TOKEN:
208098e903e7SBaptiste Daroussin case LEFT:
208198e903e7SBaptiste Daroussin case RIGHT:
208298e903e7SBaptiste Daroussin case NONASSOC:
208398e903e7SBaptiste Daroussin declare_tokens(k);
208498e903e7SBaptiste Daroussin break;
208598e903e7SBaptiste Daroussin
208698e903e7SBaptiste Daroussin case EXPECT:
208798e903e7SBaptiste Daroussin case EXPECT_RR:
208898e903e7SBaptiste Daroussin declare_expect(k);
208998e903e7SBaptiste Daroussin break;
209098e903e7SBaptiste Daroussin
209198e903e7SBaptiste Daroussin case TYPE:
209298e903e7SBaptiste Daroussin declare_types();
209398e903e7SBaptiste Daroussin break;
209498e903e7SBaptiste Daroussin
209598e903e7SBaptiste Daroussin case START:
209698e903e7SBaptiste Daroussin declare_start();
209798e903e7SBaptiste Daroussin break;
209898e903e7SBaptiste Daroussin
209998e903e7SBaptiste Daroussin case PURE_PARSER:
210098e903e7SBaptiste Daroussin pure_parser = 1;
210198e903e7SBaptiste Daroussin break;
210298e903e7SBaptiste Daroussin
210398e903e7SBaptiste Daroussin case PARSE_PARAM:
210498e903e7SBaptiste Daroussin case LEX_PARAM:
210598e903e7SBaptiste Daroussin copy_param(k);
210698e903e7SBaptiste Daroussin break;
210798e903e7SBaptiste Daroussin
21084b4a8fcaSBaptiste Daroussin case TOKEN_TABLE:
21094b4a8fcaSBaptiste Daroussin token_table = 1;
21104b4a8fcaSBaptiste Daroussin break;
21114b4a8fcaSBaptiste Daroussin
21122aca18c7SJung-uk Kim case ERROR_VERBOSE:
21132aca18c7SJung-uk Kim error_verbose = 1;
21142aca18c7SJung-uk Kim break;
21152aca18c7SJung-uk Kim
21160c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
21170c8de5b0SBaptiste Daroussin case LOCATIONS:
21180c8de5b0SBaptiste Daroussin locations = 1;
21190c8de5b0SBaptiste Daroussin break;
21200c8de5b0SBaptiste Daroussin
21210c8de5b0SBaptiste Daroussin case DESTRUCTOR:
21220c8de5b0SBaptiste Daroussin destructor = 1;
21230c8de5b0SBaptiste Daroussin copy_destructor();
21240c8de5b0SBaptiste Daroussin break;
21252aca18c7SJung-uk Kim case INITIAL_ACTION:
21262aca18c7SJung-uk Kim copy_initial_action();
21272aca18c7SJung-uk Kim break;
21280c8de5b0SBaptiste Daroussin #endif
21290c8de5b0SBaptiste Daroussin
21308e022d3cSDag-Erling Smørgrav case NONPOSIX_DEBUG:
21318e022d3cSDag-Erling Smørgrav tflag = 1;
21322aca18c7SJung-uk Kim break;
21332aca18c7SJung-uk Kim
2134*822ca327SBaptiste Daroussin case HACK_DEFINE:
2135*822ca327SBaptiste Daroussin hack_defines();
2136*822ca327SBaptiste Daroussin break;
2137*822ca327SBaptiste Daroussin
213898e903e7SBaptiste Daroussin case POSIX_YACC:
213998e903e7SBaptiste Daroussin /* noop for bison compatibility. byacc is already designed to be posix
214098e903e7SBaptiste Daroussin * yacc compatible. */
214198e903e7SBaptiste Daroussin break;
214298e903e7SBaptiste Daroussin }
214398e903e7SBaptiste Daroussin }
214498e903e7SBaptiste Daroussin }
214598e903e7SBaptiste Daroussin
214698e903e7SBaptiste Daroussin static void
initialize_grammar(void)214798e903e7SBaptiste Daroussin initialize_grammar(void)
214898e903e7SBaptiste Daroussin {
214998e903e7SBaptiste Daroussin nitems = 4;
215098e903e7SBaptiste Daroussin maxitems = 300;
215198e903e7SBaptiste Daroussin
21523e066022SBaptiste Daroussin pitem = TMALLOC(bucket *, maxitems);
215398e903e7SBaptiste Daroussin NO_SPACE(pitem);
215498e903e7SBaptiste Daroussin
215598e903e7SBaptiste Daroussin pitem[0] = 0;
215698e903e7SBaptiste Daroussin pitem[1] = 0;
215798e903e7SBaptiste Daroussin pitem[2] = 0;
215898e903e7SBaptiste Daroussin pitem[3] = 0;
215998e903e7SBaptiste Daroussin
216098e903e7SBaptiste Daroussin nrules = 3;
216198e903e7SBaptiste Daroussin maxrules = 100;
216298e903e7SBaptiste Daroussin
21633e066022SBaptiste Daroussin plhs = TMALLOC(bucket *, maxrules);
216498e903e7SBaptiste Daroussin NO_SPACE(plhs);
216598e903e7SBaptiste Daroussin
216698e903e7SBaptiste Daroussin plhs[0] = 0;
216798e903e7SBaptiste Daroussin plhs[1] = 0;
216898e903e7SBaptiste Daroussin plhs[2] = 0;
216998e903e7SBaptiste Daroussin
21703e066022SBaptiste Daroussin rprec = TMALLOC(Value_t, maxrules);
217198e903e7SBaptiste Daroussin NO_SPACE(rprec);
217298e903e7SBaptiste Daroussin
217398e903e7SBaptiste Daroussin rprec[0] = 0;
217498e903e7SBaptiste Daroussin rprec[1] = 0;
217598e903e7SBaptiste Daroussin rprec[2] = 0;
217698e903e7SBaptiste Daroussin
21773e066022SBaptiste Daroussin rassoc = TMALLOC(Assoc_t, maxrules);
217898e903e7SBaptiste Daroussin NO_SPACE(rassoc);
217998e903e7SBaptiste Daroussin
218098e903e7SBaptiste Daroussin rassoc[0] = TOKEN;
218198e903e7SBaptiste Daroussin rassoc[1] = TOKEN;
218298e903e7SBaptiste Daroussin rassoc[2] = TOKEN;
218398e903e7SBaptiste Daroussin }
218498e903e7SBaptiste Daroussin
218598e903e7SBaptiste Daroussin static void
expand_items(void)218698e903e7SBaptiste Daroussin expand_items(void)
218798e903e7SBaptiste Daroussin {
218898e903e7SBaptiste Daroussin maxitems += 300;
21893e066022SBaptiste Daroussin pitem = TREALLOC(bucket *, pitem, maxitems);
219098e903e7SBaptiste Daroussin NO_SPACE(pitem);
219198e903e7SBaptiste Daroussin }
219298e903e7SBaptiste Daroussin
219398e903e7SBaptiste Daroussin static void
expand_rules(void)219498e903e7SBaptiste Daroussin expand_rules(void)
219598e903e7SBaptiste Daroussin {
219698e903e7SBaptiste Daroussin maxrules += 100;
219798e903e7SBaptiste Daroussin
21983e066022SBaptiste Daroussin plhs = TREALLOC(bucket *, plhs, maxrules);
219998e903e7SBaptiste Daroussin NO_SPACE(plhs);
220098e903e7SBaptiste Daroussin
22013e066022SBaptiste Daroussin rprec = TREALLOC(Value_t, rprec, maxrules);
220298e903e7SBaptiste Daroussin NO_SPACE(rprec);
220398e903e7SBaptiste Daroussin
22043e066022SBaptiste Daroussin rassoc = TREALLOC(Assoc_t, rassoc, maxrules);
220598e903e7SBaptiste Daroussin NO_SPACE(rassoc);
220698e903e7SBaptiste Daroussin }
220798e903e7SBaptiste Daroussin
22080c8de5b0SBaptiste Daroussin /* set immediately prior to where copy_args() could be called, and incremented by
22090c8de5b0SBaptiste Daroussin the various routines that will rescan the argument list as appropriate */
22100c8de5b0SBaptiste Daroussin static int rescan_lineno;
22110c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
22120c8de5b0SBaptiste Daroussin
22130c8de5b0SBaptiste Daroussin static char *
copy_args(int * alen)22140c8de5b0SBaptiste Daroussin copy_args(int *alen)
22150c8de5b0SBaptiste Daroussin {
22160c8de5b0SBaptiste Daroussin struct mstring *s = msnew();
22170c8de5b0SBaptiste Daroussin int depth = 0, len = 1;
22180c8de5b0SBaptiste Daroussin char c, quote = 0;
22192aca18c7SJung-uk Kim struct ainfo a;
22202aca18c7SJung-uk Kim
2221*822ca327SBaptiste Daroussin begin_ainfo(a, 1);
22220c8de5b0SBaptiste Daroussin
22230c8de5b0SBaptiste Daroussin while ((c = *cptr++) != R_PAREN || depth || quote)
22240c8de5b0SBaptiste Daroussin {
22250c8de5b0SBaptiste Daroussin if (c == ',' && !quote && !depth)
22260c8de5b0SBaptiste Daroussin {
22270c8de5b0SBaptiste Daroussin len++;
22280c8de5b0SBaptiste Daroussin mputc(s, 0);
22290c8de5b0SBaptiste Daroussin continue;
22300c8de5b0SBaptiste Daroussin }
22310c8de5b0SBaptiste Daroussin mputc(s, c);
22320c8de5b0SBaptiste Daroussin if (c == '\n')
22330c8de5b0SBaptiste Daroussin {
22340c8de5b0SBaptiste Daroussin get_line();
22350c8de5b0SBaptiste Daroussin if (!line)
22360c8de5b0SBaptiste Daroussin {
22370c8de5b0SBaptiste Daroussin if (quote)
22382aca18c7SJung-uk Kim unterminated_string(&a);
22390c8de5b0SBaptiste Daroussin else
22402aca18c7SJung-uk Kim unterminated_arglist(&a);
22410c8de5b0SBaptiste Daroussin }
22420c8de5b0SBaptiste Daroussin }
22430c8de5b0SBaptiste Daroussin else if (quote)
22440c8de5b0SBaptiste Daroussin {
22450c8de5b0SBaptiste Daroussin if (c == quote)
22460c8de5b0SBaptiste Daroussin quote = 0;
22470c8de5b0SBaptiste Daroussin else if (c == '\\')
22480c8de5b0SBaptiste Daroussin {
22490c8de5b0SBaptiste Daroussin if (*cptr != '\n')
22500c8de5b0SBaptiste Daroussin mputc(s, *cptr++);
22510c8de5b0SBaptiste Daroussin }
22520c8de5b0SBaptiste Daroussin }
22530c8de5b0SBaptiste Daroussin else
22540c8de5b0SBaptiste Daroussin {
22550c8de5b0SBaptiste Daroussin if (c == L_PAREN)
22560c8de5b0SBaptiste Daroussin depth++;
22570c8de5b0SBaptiste Daroussin else if (c == R_PAREN)
22580c8de5b0SBaptiste Daroussin depth--;
22590c8de5b0SBaptiste Daroussin else if (c == '\"' || c == '\'')
22600c8de5b0SBaptiste Daroussin quote = c;
22610c8de5b0SBaptiste Daroussin }
22620c8de5b0SBaptiste Daroussin }
22630c8de5b0SBaptiste Daroussin if (alen)
22640c8de5b0SBaptiste Daroussin *alen = len;
2265*822ca327SBaptiste Daroussin end_ainfo(a);
22660c8de5b0SBaptiste Daroussin return msdone(s);
22670c8de5b0SBaptiste Daroussin }
22680c8de5b0SBaptiste Daroussin
22690c8de5b0SBaptiste Daroussin static char *
parse_id(char * p,char ** save)22700c8de5b0SBaptiste Daroussin parse_id(char *p, char **save)
22710c8de5b0SBaptiste Daroussin {
22720c8de5b0SBaptiste Daroussin char *b;
22730c8de5b0SBaptiste Daroussin
22742aca18c7SJung-uk Kim while (isspace(UCH(*p)))
22750c8de5b0SBaptiste Daroussin if (*p++ == '\n')
22760c8de5b0SBaptiste Daroussin rescan_lineno++;
22772aca18c7SJung-uk Kim if (!isalpha(UCH(*p)) && *p != '_')
22780c8de5b0SBaptiste Daroussin return NULL;
22790c8de5b0SBaptiste Daroussin b = p;
2280b53bb29fSJung-uk Kim while (IS_NAME2(UCH(*p)))
22810c8de5b0SBaptiste Daroussin p++;
22820c8de5b0SBaptiste Daroussin if (save)
22830c8de5b0SBaptiste Daroussin {
22840c8de5b0SBaptiste Daroussin *save = cache_tag(b, (size_t)(p - b));
22850c8de5b0SBaptiste Daroussin }
22860c8de5b0SBaptiste Daroussin return p;
22870c8de5b0SBaptiste Daroussin }
22880c8de5b0SBaptiste Daroussin
22890c8de5b0SBaptiste Daroussin static char *
parse_int(char * p,int * save)22900c8de5b0SBaptiste Daroussin parse_int(char *p, int *save)
22910c8de5b0SBaptiste Daroussin {
22920c8de5b0SBaptiste Daroussin int neg = 0, val = 0;
22930c8de5b0SBaptiste Daroussin
22942aca18c7SJung-uk Kim while (isspace(UCH(*p)))
22950c8de5b0SBaptiste Daroussin if (*p++ == '\n')
22960c8de5b0SBaptiste Daroussin rescan_lineno++;
22970c8de5b0SBaptiste Daroussin if (*p == '-')
22980c8de5b0SBaptiste Daroussin {
22990c8de5b0SBaptiste Daroussin neg = 1;
23000c8de5b0SBaptiste Daroussin p++;
23010c8de5b0SBaptiste Daroussin }
23022aca18c7SJung-uk Kim if (!isdigit(UCH(*p)))
23030c8de5b0SBaptiste Daroussin return NULL;
23042aca18c7SJung-uk Kim while (isdigit(UCH(*p)))
23050c8de5b0SBaptiste Daroussin val = val * 10 + *p++ - '0';
23060c8de5b0SBaptiste Daroussin if (neg)
23070c8de5b0SBaptiste Daroussin val = -val;
23080c8de5b0SBaptiste Daroussin if (save)
23090c8de5b0SBaptiste Daroussin *save = val;
23100c8de5b0SBaptiste Daroussin return p;
23110c8de5b0SBaptiste Daroussin }
23120c8de5b0SBaptiste Daroussin
23130c8de5b0SBaptiste Daroussin static void
parse_arginfo(bucket * a,char * args,int argslen)23140c8de5b0SBaptiste Daroussin parse_arginfo(bucket *a, char *args, int argslen)
23150c8de5b0SBaptiste Daroussin {
23160c8de5b0SBaptiste Daroussin char *p = args, *tmp;
23170c8de5b0SBaptiste Daroussin int i, redec = 0;
23180c8de5b0SBaptiste Daroussin
2319c5b5d71aSJung-uk Kim if (a->args >= 0)
23200c8de5b0SBaptiste Daroussin {
23210c8de5b0SBaptiste Daroussin if (a->args != argslen)
23220c8de5b0SBaptiste Daroussin arg_number_disagree_warning(rescan_lineno, a->name);
23230c8de5b0SBaptiste Daroussin redec = 1;
23240c8de5b0SBaptiste Daroussin }
23250c8de5b0SBaptiste Daroussin else
23260c8de5b0SBaptiste Daroussin {
23270c8de5b0SBaptiste Daroussin if ((a->args = argslen) == 0)
23280c8de5b0SBaptiste Daroussin return;
23290c8de5b0SBaptiste Daroussin a->argnames = TMALLOC(char *, argslen);
23300c8de5b0SBaptiste Daroussin NO_SPACE(a->argnames);
23310c8de5b0SBaptiste Daroussin a->argtags = TMALLOC(char *, argslen);
23320c8de5b0SBaptiste Daroussin NO_SPACE(a->argtags);
23330c8de5b0SBaptiste Daroussin }
23340c8de5b0SBaptiste Daroussin if (!args)
23350c8de5b0SBaptiste Daroussin return;
23360c8de5b0SBaptiste Daroussin for (i = 0; i < argslen; i++)
23370c8de5b0SBaptiste Daroussin {
23382aca18c7SJung-uk Kim while (isspace(UCH(*p)))
23390c8de5b0SBaptiste Daroussin if (*p++ == '\n')
23400c8de5b0SBaptiste Daroussin rescan_lineno++;
23410c8de5b0SBaptiste Daroussin if (*p++ != '$')
23420c8de5b0SBaptiste Daroussin bad_formals();
23432aca18c7SJung-uk Kim while (isspace(UCH(*p)))
23440c8de5b0SBaptiste Daroussin if (*p++ == '\n')
23450c8de5b0SBaptiste Daroussin rescan_lineno++;
23460c8de5b0SBaptiste Daroussin if (*p == '<')
23470c8de5b0SBaptiste Daroussin {
23480c8de5b0SBaptiste Daroussin havetags = 1;
23490c8de5b0SBaptiste Daroussin if (!(p = parse_id(p + 1, &tmp)))
23500c8de5b0SBaptiste Daroussin bad_formals();
23512aca18c7SJung-uk Kim while (isspace(UCH(*p)))
23520c8de5b0SBaptiste Daroussin if (*p++ == '\n')
23530c8de5b0SBaptiste Daroussin rescan_lineno++;
23540c8de5b0SBaptiste Daroussin if (*p++ != '>')
23550c8de5b0SBaptiste Daroussin bad_formals();
23560c8de5b0SBaptiste Daroussin if (redec)
23570c8de5b0SBaptiste Daroussin {
23580c8de5b0SBaptiste Daroussin if (a->argtags[i] != tmp)
23590c8de5b0SBaptiste Daroussin arg_type_disagree_warning(rescan_lineno, i + 1, a->name);
23600c8de5b0SBaptiste Daroussin }
23610c8de5b0SBaptiste Daroussin else
23620c8de5b0SBaptiste Daroussin a->argtags[i] = tmp;
23630c8de5b0SBaptiste Daroussin }
23640c8de5b0SBaptiste Daroussin else if (!redec)
23650c8de5b0SBaptiste Daroussin a->argtags[i] = NULL;
23660c8de5b0SBaptiste Daroussin if (!(p = parse_id(p, &a->argnames[i])))
23670c8de5b0SBaptiste Daroussin bad_formals();
23682aca18c7SJung-uk Kim while (isspace(UCH(*p)))
23690c8de5b0SBaptiste Daroussin if (*p++ == '\n')
23700c8de5b0SBaptiste Daroussin rescan_lineno++;
23710c8de5b0SBaptiste Daroussin if (*p++)
23720c8de5b0SBaptiste Daroussin bad_formals();
23730c8de5b0SBaptiste Daroussin }
23740c8de5b0SBaptiste Daroussin free(args);
23750c8de5b0SBaptiste Daroussin }
23760c8de5b0SBaptiste Daroussin
23770c8de5b0SBaptiste Daroussin static char *
compile_arg(char ** theptr,char * yyvaltag)23780c8de5b0SBaptiste Daroussin compile_arg(char **theptr, char *yyvaltag)
23790c8de5b0SBaptiste Daroussin {
23800c8de5b0SBaptiste Daroussin char *p = *theptr;
23810c8de5b0SBaptiste Daroussin struct mstring *c = msnew();
23828e022d3cSDag-Erling Smørgrav int i, n;
23830c8de5b0SBaptiste Daroussin Value_t *offsets = NULL, maxoffset;
23840c8de5b0SBaptiste Daroussin bucket **rhs;
23850c8de5b0SBaptiste Daroussin
23860c8de5b0SBaptiste Daroussin maxoffset = 0;
23870c8de5b0SBaptiste Daroussin n = 0;
23880c8de5b0SBaptiste Daroussin for (i = nitems - 1; pitem[i]; --i)
23890c8de5b0SBaptiste Daroussin {
23900c8de5b0SBaptiste Daroussin n++;
23910c8de5b0SBaptiste Daroussin if (pitem[i]->class != ARGUMENT)
23920c8de5b0SBaptiste Daroussin maxoffset++;
23930c8de5b0SBaptiste Daroussin }
23940c8de5b0SBaptiste Daroussin if (maxoffset > 0)
23950c8de5b0SBaptiste Daroussin {
23968e022d3cSDag-Erling Smørgrav int j;
23978e022d3cSDag-Erling Smørgrav
23988e022d3cSDag-Erling Smørgrav offsets = TCMALLOC(Value_t, maxoffset + 1);
23990c8de5b0SBaptiste Daroussin NO_SPACE(offsets);
240011fce282SBaptiste Daroussin
24010c8de5b0SBaptiste Daroussin for (j = 0, i++; i < nitems; i++)
24020c8de5b0SBaptiste Daroussin if (pitem[i]->class != ARGUMENT)
24030c8de5b0SBaptiste Daroussin offsets[++j] = (Value_t)(i - nitems + 1);
240411fce282SBaptiste Daroussin }
24050c8de5b0SBaptiste Daroussin rhs = pitem + nitems - 1;
24060c8de5b0SBaptiste Daroussin
24070c8de5b0SBaptiste Daroussin if (yyvaltag)
24080c8de5b0SBaptiste Daroussin msprintf(c, "yyval.%s = ", yyvaltag);
24090c8de5b0SBaptiste Daroussin else
24100c8de5b0SBaptiste Daroussin msprintf(c, "yyval = ");
24110c8de5b0SBaptiste Daroussin while (*p)
24120c8de5b0SBaptiste Daroussin {
24130c8de5b0SBaptiste Daroussin if (*p == '$')
24140c8de5b0SBaptiste Daroussin {
24150c8de5b0SBaptiste Daroussin char *tag = NULL;
24160c8de5b0SBaptiste Daroussin if (*++p == '<')
24170c8de5b0SBaptiste Daroussin if (!(p = parse_id(++p, &tag)) || *p++ != '>')
24180c8de5b0SBaptiste Daroussin illegal_tag(rescan_lineno, NULL, NULL);
24192aca18c7SJung-uk Kim if (isdigit(UCH(*p)) || *p == '-')
24200c8de5b0SBaptiste Daroussin {
24210c8de5b0SBaptiste Daroussin int val;
24220c8de5b0SBaptiste Daroussin if (!(p = parse_int(p, &val)))
24230c8de5b0SBaptiste Daroussin dollar_error(rescan_lineno, NULL, NULL);
24240c8de5b0SBaptiste Daroussin if (val <= 0)
24250c8de5b0SBaptiste Daroussin i = val - n;
24260c8de5b0SBaptiste Daroussin else if (val > maxoffset)
24270c8de5b0SBaptiste Daroussin {
24280c8de5b0SBaptiste Daroussin dollar_warning(rescan_lineno, val);
24290c8de5b0SBaptiste Daroussin i = val - maxoffset;
24300c8de5b0SBaptiste Daroussin }
243111fce282SBaptiste Daroussin else if (maxoffset > 0)
24320c8de5b0SBaptiste Daroussin {
24330c8de5b0SBaptiste Daroussin i = offsets[val];
24340c8de5b0SBaptiste Daroussin if (!tag && !(tag = rhs[i]->tag) && havetags)
24350c8de5b0SBaptiste Daroussin untyped_rhs(val, rhs[i]->name);
24360c8de5b0SBaptiste Daroussin }
24370c8de5b0SBaptiste Daroussin msprintf(c, "yystack.l_mark[%d]", i);
24380c8de5b0SBaptiste Daroussin if (tag)
24390c8de5b0SBaptiste Daroussin msprintf(c, ".%s", tag);
24400c8de5b0SBaptiste Daroussin else if (havetags)
24410c8de5b0SBaptiste Daroussin unknown_rhs(val);
24420c8de5b0SBaptiste Daroussin }
24432aca18c7SJung-uk Kim else if (isalpha(UCH(*p)) || *p == '_')
24440c8de5b0SBaptiste Daroussin {
24450c8de5b0SBaptiste Daroussin char *arg;
24460c8de5b0SBaptiste Daroussin if (!(p = parse_id(p, &arg)))
24470c8de5b0SBaptiste Daroussin dollar_error(rescan_lineno, NULL, NULL);
24480c8de5b0SBaptiste Daroussin for (i = plhs[nrules]->args - 1; i >= 0; i--)
24490c8de5b0SBaptiste Daroussin if (arg == plhs[nrules]->argnames[i])
24500c8de5b0SBaptiste Daroussin break;
24510c8de5b0SBaptiste Daroussin if (i < 0)
24520c8de5b0SBaptiste Daroussin unknown_arg_warning(rescan_lineno, "$", arg, NULL, NULL);
24530c8de5b0SBaptiste Daroussin else if (!tag)
24540c8de5b0SBaptiste Daroussin tag = plhs[nrules]->argtags[i];
2455c5b5d71aSJung-uk Kim msprintf(c, "yystack.l_mark[%d]",
2456c5b5d71aSJung-uk Kim i - plhs[nrules]->args + 1 - n);
24570c8de5b0SBaptiste Daroussin if (tag)
24580c8de5b0SBaptiste Daroussin msprintf(c, ".%s", tag);
24590c8de5b0SBaptiste Daroussin else if (havetags)
24600c8de5b0SBaptiste Daroussin untyped_arg_warning(rescan_lineno, "$", arg);
24610c8de5b0SBaptiste Daroussin }
24620c8de5b0SBaptiste Daroussin else
24630c8de5b0SBaptiste Daroussin dollar_error(rescan_lineno, NULL, NULL);
24640c8de5b0SBaptiste Daroussin }
24650c8de5b0SBaptiste Daroussin else if (*p == '@')
24660c8de5b0SBaptiste Daroussin {
24670c8de5b0SBaptiste Daroussin at_error(rescan_lineno, NULL, NULL);
24680c8de5b0SBaptiste Daroussin }
24690c8de5b0SBaptiste Daroussin else
24700c8de5b0SBaptiste Daroussin {
24710c8de5b0SBaptiste Daroussin if (*p == '\n')
24720c8de5b0SBaptiste Daroussin rescan_lineno++;
24730c8de5b0SBaptiste Daroussin mputc(c, *p++);
24740c8de5b0SBaptiste Daroussin }
24750c8de5b0SBaptiste Daroussin }
24760c8de5b0SBaptiste Daroussin *theptr = p;
24770c8de5b0SBaptiste Daroussin if (maxoffset > 0)
24780c8de5b0SBaptiste Daroussin FREE(offsets);
24790c8de5b0SBaptiste Daroussin return msdone(c);
24800c8de5b0SBaptiste Daroussin }
24810c8de5b0SBaptiste Daroussin
2482c5b5d71aSJung-uk Kim static int
can_elide_arg(char ** theptr,char * yyvaltag)2483c5b5d71aSJung-uk Kim can_elide_arg(char **theptr, char *yyvaltag)
2484c5b5d71aSJung-uk Kim {
2485c5b5d71aSJung-uk Kim char *p = *theptr;
2486c5b5d71aSJung-uk Kim int rv = 0;
24878e022d3cSDag-Erling Smørgrav int i, n = 0;
2488c5b5d71aSJung-uk Kim Value_t *offsets = NULL, maxoffset = 0;
2489c5b5d71aSJung-uk Kim bucket **rhs;
2490c5b5d71aSJung-uk Kim char *tag = 0;
2491c5b5d71aSJung-uk Kim
2492c5b5d71aSJung-uk Kim if (*p++ != '$')
2493c5b5d71aSJung-uk Kim return 0;
2494c5b5d71aSJung-uk Kim if (*p == '<')
2495c5b5d71aSJung-uk Kim {
2496c5b5d71aSJung-uk Kim if (!(p = parse_id(++p, &tag)) || *p++ != '>')
2497c5b5d71aSJung-uk Kim return 0;
2498c5b5d71aSJung-uk Kim }
2499c5b5d71aSJung-uk Kim for (i = nitems - 1; pitem[i]; --i)
2500c5b5d71aSJung-uk Kim {
2501c5b5d71aSJung-uk Kim n++;
2502c5b5d71aSJung-uk Kim if (pitem[i]->class != ARGUMENT)
2503c5b5d71aSJung-uk Kim maxoffset++;
2504c5b5d71aSJung-uk Kim }
2505c5b5d71aSJung-uk Kim if (maxoffset > 0)
2506c5b5d71aSJung-uk Kim {
25078e022d3cSDag-Erling Smørgrav int j;
25088e022d3cSDag-Erling Smørgrav
25098e022d3cSDag-Erling Smørgrav offsets = TCMALLOC(Value_t, maxoffset + 1);
2510c5b5d71aSJung-uk Kim NO_SPACE(offsets);
2511c5b5d71aSJung-uk Kim
2512c5b5d71aSJung-uk Kim for (j = 0, i++; i < nitems; i++)
2513c5b5d71aSJung-uk Kim if (pitem[i]->class != ARGUMENT)
2514c5b5d71aSJung-uk Kim offsets[++j] = (Value_t)(i - nitems + 1);
2515c5b5d71aSJung-uk Kim }
2516c5b5d71aSJung-uk Kim rhs = pitem + nitems - 1;
2517c5b5d71aSJung-uk Kim
25182aca18c7SJung-uk Kim if (isdigit(UCH(*p)) || *p == '-')
2519c5b5d71aSJung-uk Kim {
2520c5b5d71aSJung-uk Kim int val;
2521c5b5d71aSJung-uk Kim if (!(p = parse_int(p, &val)))
2522c5b5d71aSJung-uk Kim rv = 0;
2523c5b5d71aSJung-uk Kim else
2524c5b5d71aSJung-uk Kim {
2525c5b5d71aSJung-uk Kim if (val <= 0)
2526c5b5d71aSJung-uk Kim rv = 1 - val + n;
2527c5b5d71aSJung-uk Kim else if (val > maxoffset)
2528c5b5d71aSJung-uk Kim rv = 0;
2529c5b5d71aSJung-uk Kim else
2530c5b5d71aSJung-uk Kim {
2531c5b5d71aSJung-uk Kim i = offsets[val];
2532c5b5d71aSJung-uk Kim rv = 1 - i;
2533c5b5d71aSJung-uk Kim if (!tag)
2534c5b5d71aSJung-uk Kim tag = rhs[i]->tag;
2535c5b5d71aSJung-uk Kim }
2536c5b5d71aSJung-uk Kim }
2537c5b5d71aSJung-uk Kim }
25382aca18c7SJung-uk Kim else if (isalpha(UCH(*p)) || *p == '_')
2539c5b5d71aSJung-uk Kim {
2540c5b5d71aSJung-uk Kim char *arg;
2541c5b5d71aSJung-uk Kim if (!(p = parse_id(p, &arg)))
2542b53bb29fSJung-uk Kim {
2543b53bb29fSJung-uk Kim FREE(offsets);
2544c5b5d71aSJung-uk Kim return 0;
2545b53bb29fSJung-uk Kim }
2546c5b5d71aSJung-uk Kim for (i = plhs[nrules]->args - 1; i >= 0; i--)
2547c5b5d71aSJung-uk Kim if (arg == plhs[nrules]->argnames[i])
2548c5b5d71aSJung-uk Kim break;
2549c5b5d71aSJung-uk Kim if (i >= 0)
2550c5b5d71aSJung-uk Kim {
2551c5b5d71aSJung-uk Kim if (!tag)
2552c5b5d71aSJung-uk Kim tag = plhs[nrules]->argtags[i];
2553c5b5d71aSJung-uk Kim rv = plhs[nrules]->args + n - i;
2554c5b5d71aSJung-uk Kim }
2555c5b5d71aSJung-uk Kim }
2556c5b5d71aSJung-uk Kim if (tag && yyvaltag)
2557c5b5d71aSJung-uk Kim {
2558c5b5d71aSJung-uk Kim if (strcmp(tag, yyvaltag))
2559c5b5d71aSJung-uk Kim rv = 0;
2560c5b5d71aSJung-uk Kim }
2561c5b5d71aSJung-uk Kim else if (tag || yyvaltag)
2562c5b5d71aSJung-uk Kim rv = 0;
2563c5b5d71aSJung-uk Kim if (maxoffset > 0)
2564c5b5d71aSJung-uk Kim FREE(offsets);
2565b53bb29fSJung-uk Kim if (p == 0 || *p || rv <= 0)
2566c5b5d71aSJung-uk Kim return 0;
2567c5b5d71aSJung-uk Kim *theptr = p + 1;
2568c5b5d71aSJung-uk Kim return rv;
2569c5b5d71aSJung-uk Kim }
2570c5b5d71aSJung-uk Kim
25710c8de5b0SBaptiste Daroussin #define ARG_CACHE_SIZE 1024
25720c8de5b0SBaptiste Daroussin static struct arg_cache
25730c8de5b0SBaptiste Daroussin {
25740c8de5b0SBaptiste Daroussin struct arg_cache *next;
25750c8de5b0SBaptiste Daroussin char *code;
25760c8de5b0SBaptiste Daroussin int rule;
25770c8de5b0SBaptiste Daroussin }
25780c8de5b0SBaptiste Daroussin *arg_cache[ARG_CACHE_SIZE];
25790c8de5b0SBaptiste Daroussin
25800c8de5b0SBaptiste Daroussin static int
lookup_arg_cache(char * code)25810c8de5b0SBaptiste Daroussin lookup_arg_cache(char *code)
25820c8de5b0SBaptiste Daroussin {
25830c8de5b0SBaptiste Daroussin struct arg_cache *entry;
25840c8de5b0SBaptiste Daroussin
25850c8de5b0SBaptiste Daroussin entry = arg_cache[strnshash(code) % ARG_CACHE_SIZE];
25860c8de5b0SBaptiste Daroussin while (entry)
25870c8de5b0SBaptiste Daroussin {
25880c8de5b0SBaptiste Daroussin if (!strnscmp(entry->code, code))
25890c8de5b0SBaptiste Daroussin return entry->rule;
25900c8de5b0SBaptiste Daroussin entry = entry->next;
25910c8de5b0SBaptiste Daroussin }
25920c8de5b0SBaptiste Daroussin return -1;
25930c8de5b0SBaptiste Daroussin }
25940c8de5b0SBaptiste Daroussin
25950c8de5b0SBaptiste Daroussin static void
insert_arg_cache(char * code,int rule)25960c8de5b0SBaptiste Daroussin insert_arg_cache(char *code, int rule)
25970c8de5b0SBaptiste Daroussin {
25980c8de5b0SBaptiste Daroussin struct arg_cache *entry = NEW(struct arg_cache);
25990c8de5b0SBaptiste Daroussin int i;
26000c8de5b0SBaptiste Daroussin
26010c8de5b0SBaptiste Daroussin NO_SPACE(entry);
26020c8de5b0SBaptiste Daroussin i = strnshash(code) % ARG_CACHE_SIZE;
26030c8de5b0SBaptiste Daroussin entry->code = code;
26040c8de5b0SBaptiste Daroussin entry->rule = rule;
26050c8de5b0SBaptiste Daroussin entry->next = arg_cache[i];
26060c8de5b0SBaptiste Daroussin arg_cache[i] = entry;
26070c8de5b0SBaptiste Daroussin }
26080c8de5b0SBaptiste Daroussin
26090c8de5b0SBaptiste Daroussin static void
clean_arg_cache(void)26100c8de5b0SBaptiste Daroussin clean_arg_cache(void)
26110c8de5b0SBaptiste Daroussin {
26120c8de5b0SBaptiste Daroussin struct arg_cache *e, *t;
26130c8de5b0SBaptiste Daroussin int i;
26140c8de5b0SBaptiste Daroussin
26150c8de5b0SBaptiste Daroussin for (i = 0; i < ARG_CACHE_SIZE; i++)
26160c8de5b0SBaptiste Daroussin {
26170c8de5b0SBaptiste Daroussin for (e = arg_cache[i]; (t = e); e = e->next, FREE(t))
26180c8de5b0SBaptiste Daroussin free(e->code);
26190c8de5b0SBaptiste Daroussin arg_cache[i] = NULL;
26200c8de5b0SBaptiste Daroussin }
26210c8de5b0SBaptiste Daroussin }
2622c5b5d71aSJung-uk Kim #endif /* defined(YYBTYACC) */
26230c8de5b0SBaptiste Daroussin
262498e903e7SBaptiste Daroussin static void
advance_to_start(void)262598e903e7SBaptiste Daroussin advance_to_start(void)
262698e903e7SBaptiste Daroussin {
262798e903e7SBaptiste Daroussin int c;
262898e903e7SBaptiste Daroussin bucket *bp;
262998e903e7SBaptiste Daroussin int s_lineno;
26300c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
26310c8de5b0SBaptiste Daroussin char *args = NULL;
26320c8de5b0SBaptiste Daroussin int argslen = 0;
26330c8de5b0SBaptiste Daroussin #endif
263498e903e7SBaptiste Daroussin
263598e903e7SBaptiste Daroussin for (;;)
263698e903e7SBaptiste Daroussin {
26378e022d3cSDag-Erling Smørgrav char *s_cptr;
26388e022d3cSDag-Erling Smørgrav
263998e903e7SBaptiste Daroussin c = nextc();
264098e903e7SBaptiste Daroussin if (c != '%')
264198e903e7SBaptiste Daroussin break;
264298e903e7SBaptiste Daroussin s_cptr = cptr;
264398e903e7SBaptiste Daroussin switch (keyword())
264498e903e7SBaptiste Daroussin {
2645b53bb29fSJung-uk Kim case XCODE:
2646b53bb29fSJung-uk Kim copy_code();
2647b53bb29fSJung-uk Kim break;
2648b53bb29fSJung-uk Kim
264998e903e7SBaptiste Daroussin case MARK:
265098e903e7SBaptiste Daroussin no_grammar();
265198e903e7SBaptiste Daroussin
265298e903e7SBaptiste Daroussin case TEXT:
265398e903e7SBaptiste Daroussin copy_text();
265498e903e7SBaptiste Daroussin break;
265598e903e7SBaptiste Daroussin
265698e903e7SBaptiste Daroussin case START:
265798e903e7SBaptiste Daroussin declare_start();
265898e903e7SBaptiste Daroussin break;
265998e903e7SBaptiste Daroussin
266098e903e7SBaptiste Daroussin default:
266198e903e7SBaptiste Daroussin syntax_error(lineno, line, s_cptr);
266298e903e7SBaptiste Daroussin }
266398e903e7SBaptiste Daroussin }
266498e903e7SBaptiste Daroussin
266598e903e7SBaptiste Daroussin c = nextc();
2666b53bb29fSJung-uk Kim if (!isalpha(UCH(c)) && c != '_' && c != '.' && c != '_')
266798e903e7SBaptiste Daroussin syntax_error(lineno, line, cptr);
266898e903e7SBaptiste Daroussin bp = get_name();
266998e903e7SBaptiste Daroussin if (goal == 0)
267098e903e7SBaptiste Daroussin {
267198e903e7SBaptiste Daroussin if (bp->class == TERM)
267298e903e7SBaptiste Daroussin terminal_start(bp->name);
267398e903e7SBaptiste Daroussin goal = bp;
267498e903e7SBaptiste Daroussin }
267598e903e7SBaptiste Daroussin
267698e903e7SBaptiste Daroussin s_lineno = lineno;
267798e903e7SBaptiste Daroussin c = nextc();
267898e903e7SBaptiste Daroussin if (c == EOF)
267998e903e7SBaptiste Daroussin unexpected_EOF();
26800c8de5b0SBaptiste Daroussin rescan_lineno = lineno; /* line# for possible inherited args rescan */
26810c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
26820c8de5b0SBaptiste Daroussin if (c == L_PAREN)
26830c8de5b0SBaptiste Daroussin {
26840c8de5b0SBaptiste Daroussin ++cptr;
26850c8de5b0SBaptiste Daroussin args = copy_args(&argslen);
26860c8de5b0SBaptiste Daroussin NO_SPACE(args);
26870c8de5b0SBaptiste Daroussin c = nextc();
26880c8de5b0SBaptiste Daroussin }
26890c8de5b0SBaptiste Daroussin #endif
269098e903e7SBaptiste Daroussin if (c != ':')
269198e903e7SBaptiste Daroussin syntax_error(lineno, line, cptr);
269298e903e7SBaptiste Daroussin start_rule(bp, s_lineno);
26930c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
26940c8de5b0SBaptiste Daroussin parse_arginfo(bp, args, argslen);
26950c8de5b0SBaptiste Daroussin #endif
269698e903e7SBaptiste Daroussin ++cptr;
269798e903e7SBaptiste Daroussin }
269898e903e7SBaptiste Daroussin
269998e903e7SBaptiste Daroussin static void
start_rule(bucket * bp,int s_lineno)270098e903e7SBaptiste Daroussin start_rule(bucket *bp, int s_lineno)
270198e903e7SBaptiste Daroussin {
270298e903e7SBaptiste Daroussin if (bp->class == TERM)
270398e903e7SBaptiste Daroussin terminal_lhs(s_lineno);
270498e903e7SBaptiste Daroussin bp->class = NONTERM;
27050c8de5b0SBaptiste Daroussin if (!bp->index)
27060c8de5b0SBaptiste Daroussin bp->index = nrules;
270798e903e7SBaptiste Daroussin if (nrules >= maxrules)
270898e903e7SBaptiste Daroussin expand_rules();
270998e903e7SBaptiste Daroussin plhs[nrules] = bp;
271098e903e7SBaptiste Daroussin rprec[nrules] = UNDEFINED;
271198e903e7SBaptiste Daroussin rassoc[nrules] = TOKEN;
271298e903e7SBaptiste Daroussin }
271398e903e7SBaptiste Daroussin
271498e903e7SBaptiste Daroussin static void
end_rule(void)271598e903e7SBaptiste Daroussin end_rule(void)
271698e903e7SBaptiste Daroussin {
271798e903e7SBaptiste Daroussin if (!last_was_action && plhs[nrules]->tag)
271898e903e7SBaptiste Daroussin {
271998e903e7SBaptiste Daroussin if (pitem[nitems - 1])
272098e903e7SBaptiste Daroussin {
27218e022d3cSDag-Erling Smørgrav int i;
27228e022d3cSDag-Erling Smørgrav
272398e903e7SBaptiste Daroussin for (i = nitems - 1; (i > 0) && pitem[i]; --i)
272498e903e7SBaptiste Daroussin continue;
272598e903e7SBaptiste Daroussin if (pitem[i + 1] == 0 || pitem[i + 1]->tag != plhs[nrules]->tag)
2726c5b5d71aSJung-uk Kim default_action_warning(plhs[nrules]->name);
272798e903e7SBaptiste Daroussin }
272898e903e7SBaptiste Daroussin else
2729c5b5d71aSJung-uk Kim default_action_warning(plhs[nrules]->name);
273098e903e7SBaptiste Daroussin }
273198e903e7SBaptiste Daroussin
273298e903e7SBaptiste Daroussin last_was_action = 0;
273398e903e7SBaptiste Daroussin if (nitems >= maxitems)
273498e903e7SBaptiste Daroussin expand_items();
273598e903e7SBaptiste Daroussin pitem[nitems] = 0;
273698e903e7SBaptiste Daroussin ++nitems;
273798e903e7SBaptiste Daroussin ++nrules;
273898e903e7SBaptiste Daroussin }
273998e903e7SBaptiste Daroussin
274098e903e7SBaptiste Daroussin static void
insert_empty_rule(void)274198e903e7SBaptiste Daroussin insert_empty_rule(void)
274298e903e7SBaptiste Daroussin {
274398e903e7SBaptiste Daroussin bucket *bp, **bpp;
274498e903e7SBaptiste Daroussin
274598e903e7SBaptiste Daroussin assert(cache);
27460f86d14eSJung-uk Kim assert(cache_size >= CACHE_SIZE);
274798e903e7SBaptiste Daroussin sprintf(cache, "$$%d", ++gensym);
274898e903e7SBaptiste Daroussin bp = make_bucket(cache);
274998e903e7SBaptiste Daroussin last_symbol->next = bp;
275098e903e7SBaptiste Daroussin last_symbol = bp;
275198e903e7SBaptiste Daroussin bp->tag = plhs[nrules]->tag;
27520c8de5b0SBaptiste Daroussin bp->class = ACTION;
27530c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
27540c8de5b0SBaptiste Daroussin bp->args = 0;
27550c8de5b0SBaptiste Daroussin #endif
275698e903e7SBaptiste Daroussin
27570c8de5b0SBaptiste Daroussin nitems = (Value_t)(nitems + 2);
27580c8de5b0SBaptiste Daroussin if (nitems > maxitems)
275998e903e7SBaptiste Daroussin expand_items();
276098e903e7SBaptiste Daroussin bpp = pitem + nitems - 1;
276198e903e7SBaptiste Daroussin *bpp-- = bp;
276298e903e7SBaptiste Daroussin while ((bpp[0] = bpp[-1]) != 0)
276398e903e7SBaptiste Daroussin --bpp;
276498e903e7SBaptiste Daroussin
276598e903e7SBaptiste Daroussin if (++nrules >= maxrules)
276698e903e7SBaptiste Daroussin expand_rules();
276798e903e7SBaptiste Daroussin plhs[nrules] = plhs[nrules - 1];
276898e903e7SBaptiste Daroussin plhs[nrules - 1] = bp;
276998e903e7SBaptiste Daroussin rprec[nrules] = rprec[nrules - 1];
277098e903e7SBaptiste Daroussin rprec[nrules - 1] = 0;
277198e903e7SBaptiste Daroussin rassoc[nrules] = rassoc[nrules - 1];
277298e903e7SBaptiste Daroussin rassoc[nrules - 1] = TOKEN;
277398e903e7SBaptiste Daroussin }
277498e903e7SBaptiste Daroussin
27750c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
27760c8de5b0SBaptiste Daroussin static char *
insert_arg_rule(char * arg,char * tag)27770c8de5b0SBaptiste Daroussin insert_arg_rule(char *arg, char *tag)
27780c8de5b0SBaptiste Daroussin {
27790c8de5b0SBaptiste Daroussin int line_number = rescan_lineno;
27800c8de5b0SBaptiste Daroussin char *code = compile_arg(&arg, tag);
27810c8de5b0SBaptiste Daroussin int rule = lookup_arg_cache(code);
27820c8de5b0SBaptiste Daroussin FILE *f = action_file;
27830c8de5b0SBaptiste Daroussin
27840c8de5b0SBaptiste Daroussin if (rule < 0)
27850c8de5b0SBaptiste Daroussin {
27860c8de5b0SBaptiste Daroussin rule = nrules;
27870c8de5b0SBaptiste Daroussin insert_arg_cache(code, rule);
2788c5b5d71aSJung-uk Kim trialaction = 1; /* arg rules always run in trial mode */
27898e022d3cSDag-Erling Smørgrav begin_case(f, rule - 2);
27908e022d3cSDag-Erling Smørgrav fprintf_lineno(f, line_number, input_file_name);
27918e022d3cSDag-Erling Smørgrav fprintf(f, "%s;", code);
27928e022d3cSDag-Erling Smørgrav end_case(f);
27930c8de5b0SBaptiste Daroussin insert_empty_rule();
2794c5b5d71aSJung-uk Kim plhs[rule]->tag = cache_tag(tag, strlen(tag));
27950c8de5b0SBaptiste Daroussin plhs[rule]->class = ARGUMENT;
27960c8de5b0SBaptiste Daroussin }
27970c8de5b0SBaptiste Daroussin else
27980c8de5b0SBaptiste Daroussin {
27990c8de5b0SBaptiste Daroussin if (++nitems > maxitems)
28000c8de5b0SBaptiste Daroussin expand_items();
28010c8de5b0SBaptiste Daroussin pitem[nitems - 1] = plhs[rule];
28020c8de5b0SBaptiste Daroussin free(code);
28030c8de5b0SBaptiste Daroussin }
28040c8de5b0SBaptiste Daroussin return arg + 1;
28050c8de5b0SBaptiste Daroussin }
28060c8de5b0SBaptiste Daroussin #endif
28070c8de5b0SBaptiste Daroussin
280898e903e7SBaptiste Daroussin static void
add_symbol(void)280998e903e7SBaptiste Daroussin add_symbol(void)
281098e903e7SBaptiste Daroussin {
281198e903e7SBaptiste Daroussin int c;
281298e903e7SBaptiste Daroussin bucket *bp;
281398e903e7SBaptiste Daroussin int s_lineno = lineno;
28140c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
28150c8de5b0SBaptiste Daroussin char *args = NULL;
28160c8de5b0SBaptiste Daroussin int argslen = 0;
28170c8de5b0SBaptiste Daroussin #endif
281898e903e7SBaptiste Daroussin
281998e903e7SBaptiste Daroussin c = *cptr;
282098e903e7SBaptiste Daroussin if (c == '\'' || c == '"')
282198e903e7SBaptiste Daroussin bp = get_literal();
282298e903e7SBaptiste Daroussin else
282398e903e7SBaptiste Daroussin bp = get_name();
282498e903e7SBaptiste Daroussin
282598e903e7SBaptiste Daroussin c = nextc();
28260c8de5b0SBaptiste Daroussin rescan_lineno = lineno; /* line# for possible inherited args rescan */
28270c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
28280c8de5b0SBaptiste Daroussin if (c == L_PAREN)
28290c8de5b0SBaptiste Daroussin {
28300c8de5b0SBaptiste Daroussin ++cptr;
28310c8de5b0SBaptiste Daroussin args = copy_args(&argslen);
28320c8de5b0SBaptiste Daroussin NO_SPACE(args);
28330c8de5b0SBaptiste Daroussin c = nextc();
28340c8de5b0SBaptiste Daroussin }
28350c8de5b0SBaptiste Daroussin #endif
283698e903e7SBaptiste Daroussin if (c == ':')
283798e903e7SBaptiste Daroussin {
283898e903e7SBaptiste Daroussin end_rule();
283998e903e7SBaptiste Daroussin start_rule(bp, s_lineno);
28400c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
28410c8de5b0SBaptiste Daroussin parse_arginfo(bp, args, argslen);
28420c8de5b0SBaptiste Daroussin #endif
284398e903e7SBaptiste Daroussin ++cptr;
284498e903e7SBaptiste Daroussin return;
284598e903e7SBaptiste Daroussin }
284698e903e7SBaptiste Daroussin
284798e903e7SBaptiste Daroussin if (last_was_action)
284898e903e7SBaptiste Daroussin insert_empty_rule();
284998e903e7SBaptiste Daroussin last_was_action = 0;
285098e903e7SBaptiste Daroussin
28510c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
28520c8de5b0SBaptiste Daroussin if (bp->args < 0)
28530c8de5b0SBaptiste Daroussin bp->args = argslen;
28540c8de5b0SBaptiste Daroussin if (argslen == 0 && bp->args > 0 && pitem[nitems - 1] == NULL)
28550c8de5b0SBaptiste Daroussin {
28560c8de5b0SBaptiste Daroussin int i;
28570c8de5b0SBaptiste Daroussin if (plhs[nrules]->args != bp->args)
28580c8de5b0SBaptiste Daroussin wrong_number_args_warning("default ", bp->name);
28590c8de5b0SBaptiste Daroussin for (i = bp->args - 1; i >= 0; i--)
28600c8de5b0SBaptiste Daroussin if (plhs[nrules]->argtags[i] != bp->argtags[i])
28610c8de5b0SBaptiste Daroussin wrong_type_for_arg_warning(i + 1, bp->name);
28620c8de5b0SBaptiste Daroussin }
28630c8de5b0SBaptiste Daroussin else if (bp->args != argslen)
28640c8de5b0SBaptiste Daroussin wrong_number_args_warning("", bp->name);
2865c5b5d71aSJung-uk Kim if (args != 0)
28660c8de5b0SBaptiste Daroussin {
2867c5b5d71aSJung-uk Kim char *ap = args;
2868c5b5d71aSJung-uk Kim int i = 0;
2869c5b5d71aSJung-uk Kim int elide_cnt = can_elide_arg(&ap, bp->argtags[0]);
2870c5b5d71aSJung-uk Kim
2871c5b5d71aSJung-uk Kim if (elide_cnt > argslen)
2872c5b5d71aSJung-uk Kim elide_cnt = 0;
2873c5b5d71aSJung-uk Kim if (elide_cnt)
2874c5b5d71aSJung-uk Kim {
2875c5b5d71aSJung-uk Kim for (i = 1; i < elide_cnt; i++)
2876c5b5d71aSJung-uk Kim if (can_elide_arg(&ap, bp->argtags[i]) != elide_cnt - i)
2877c5b5d71aSJung-uk Kim {
2878c5b5d71aSJung-uk Kim elide_cnt = 0;
2879c5b5d71aSJung-uk Kim break;
2880c5b5d71aSJung-uk Kim }
2881c5b5d71aSJung-uk Kim }
2882c5b5d71aSJung-uk Kim if (elide_cnt)
2883c5b5d71aSJung-uk Kim {
2884c5b5d71aSJung-uk Kim assert(i == elide_cnt);
2885c5b5d71aSJung-uk Kim }
2886c5b5d71aSJung-uk Kim else
2887c5b5d71aSJung-uk Kim {
2888c5b5d71aSJung-uk Kim ap = args;
2889c5b5d71aSJung-uk Kim i = 0;
2890c5b5d71aSJung-uk Kim }
2891c5b5d71aSJung-uk Kim for (; i < argslen; i++)
28920c8de5b0SBaptiste Daroussin ap = insert_arg_rule(ap, bp->argtags[i]);
28930c8de5b0SBaptiste Daroussin free(args);
28940c8de5b0SBaptiste Daroussin }
28950c8de5b0SBaptiste Daroussin #endif /* defined(YYBTYACC) */
28960c8de5b0SBaptiste Daroussin
289798e903e7SBaptiste Daroussin if (++nitems > maxitems)
289898e903e7SBaptiste Daroussin expand_items();
289998e903e7SBaptiste Daroussin pitem[nitems - 1] = bp;
290098e903e7SBaptiste Daroussin }
290198e903e7SBaptiste Daroussin
290298e903e7SBaptiste Daroussin static void
copy_action(void)290398e903e7SBaptiste Daroussin copy_action(void)
290498e903e7SBaptiste Daroussin {
290598e903e7SBaptiste Daroussin int c;
29060c8de5b0SBaptiste Daroussin int i, j, n;
290798e903e7SBaptiste Daroussin int depth;
29080c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
29090c8de5b0SBaptiste Daroussin int haveyyval = 0;
29100c8de5b0SBaptiste Daroussin #endif
291198e903e7SBaptiste Daroussin char *tag;
291298e903e7SBaptiste Daroussin FILE *f = action_file;
29132aca18c7SJung-uk Kim struct ainfo a;
29140c8de5b0SBaptiste Daroussin Value_t *offsets = NULL, maxoffset;
29150c8de5b0SBaptiste Daroussin bucket **rhs;
291698e903e7SBaptiste Daroussin
2917*822ca327SBaptiste Daroussin begin_ainfo(a, 0);
29182aca18c7SJung-uk Kim
291998e903e7SBaptiste Daroussin if (last_was_action)
292098e903e7SBaptiste Daroussin insert_empty_rule();
292198e903e7SBaptiste Daroussin last_was_action = 1;
2922c5b5d71aSJung-uk Kim #if defined(YYBTYACC)
2923c5b5d71aSJung-uk Kim trialaction = (*cptr == L_BRAC);
2924c5b5d71aSJung-uk Kim #endif
292598e903e7SBaptiste Daroussin
29268e022d3cSDag-Erling Smørgrav begin_case(f, nrules - 2);
29270c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
29280c8de5b0SBaptiste Daroussin if (backtrack)
29290c8de5b0SBaptiste Daroussin {
2930c5b5d71aSJung-uk Kim if (!trialaction)
29310c8de5b0SBaptiste Daroussin fprintf(f, " if (!yytrial)\n");
29320c8de5b0SBaptiste Daroussin }
29330c8de5b0SBaptiste Daroussin #endif
29348e022d3cSDag-Erling Smørgrav fprintf_lineno(f, lineno, input_file_name);
293598e903e7SBaptiste Daroussin if (*cptr == '=')
293698e903e7SBaptiste Daroussin ++cptr;
293798e903e7SBaptiste Daroussin
293898e903e7SBaptiste Daroussin /* avoid putting curly-braces in first column, to ease editing */
293998e903e7SBaptiste Daroussin if (*after_blanks(cptr) == L_CURL)
294098e903e7SBaptiste Daroussin {
294198e903e7SBaptiste Daroussin putc('\t', f);
294298e903e7SBaptiste Daroussin cptr = after_blanks(cptr);
294398e903e7SBaptiste Daroussin }
294498e903e7SBaptiste Daroussin
29450c8de5b0SBaptiste Daroussin maxoffset = 0;
294698e903e7SBaptiste Daroussin n = 0;
294798e903e7SBaptiste Daroussin for (i = nitems - 1; pitem[i]; --i)
29480c8de5b0SBaptiste Daroussin {
294998e903e7SBaptiste Daroussin ++n;
29500c8de5b0SBaptiste Daroussin if (pitem[i]->class != ARGUMENT)
29510c8de5b0SBaptiste Daroussin maxoffset++;
29520c8de5b0SBaptiste Daroussin }
29530c8de5b0SBaptiste Daroussin if (maxoffset > 0)
29540c8de5b0SBaptiste Daroussin {
29550c8de5b0SBaptiste Daroussin offsets = TMALLOC(Value_t, maxoffset + 1);
29560c8de5b0SBaptiste Daroussin NO_SPACE(offsets);
295711fce282SBaptiste Daroussin
29580c8de5b0SBaptiste Daroussin for (j = 0, i++; i < nitems; i++)
29590c8de5b0SBaptiste Daroussin {
29600c8de5b0SBaptiste Daroussin if (pitem[i]->class != ARGUMENT)
29610c8de5b0SBaptiste Daroussin {
29620c8de5b0SBaptiste Daroussin offsets[++j] = (Value_t)(i - nitems + 1);
29630c8de5b0SBaptiste Daroussin }
29640c8de5b0SBaptiste Daroussin }
296511fce282SBaptiste Daroussin }
29660c8de5b0SBaptiste Daroussin rhs = pitem + nitems - 1;
296798e903e7SBaptiste Daroussin
296898e903e7SBaptiste Daroussin depth = 0;
296998e903e7SBaptiste Daroussin loop:
297098e903e7SBaptiste Daroussin c = *cptr;
297198e903e7SBaptiste Daroussin if (c == '$')
297298e903e7SBaptiste Daroussin {
297398e903e7SBaptiste Daroussin if (cptr[1] == '<')
297498e903e7SBaptiste Daroussin {
297598e903e7SBaptiste Daroussin int d_lineno = lineno;
297698e903e7SBaptiste Daroussin char *d_line = dup_line();
297798e903e7SBaptiste Daroussin char *d_cptr = d_line + (cptr - line);
297898e903e7SBaptiste Daroussin
297998e903e7SBaptiste Daroussin ++cptr;
298098e903e7SBaptiste Daroussin tag = get_tag();
298198e903e7SBaptiste Daroussin c = *cptr;
298298e903e7SBaptiste Daroussin if (c == '$')
298398e903e7SBaptiste Daroussin {
298498e903e7SBaptiste Daroussin fprintf(f, "yyval.%s", tag);
298598e903e7SBaptiste Daroussin ++cptr;
298698e903e7SBaptiste Daroussin FREE(d_line);
298798e903e7SBaptiste Daroussin goto loop;
298898e903e7SBaptiste Daroussin }
2989b53bb29fSJung-uk Kim else if (isdigit(UCH(c)))
299098e903e7SBaptiste Daroussin {
299198e903e7SBaptiste Daroussin i = get_number();
29920c8de5b0SBaptiste Daroussin if (i == 0)
29930c8de5b0SBaptiste Daroussin fprintf(f, "yystack.l_mark[%d].%s", -n, tag);
29940c8de5b0SBaptiste Daroussin else if (i > maxoffset)
29950c8de5b0SBaptiste Daroussin {
299698e903e7SBaptiste Daroussin dollar_warning(d_lineno, i);
29978e022d3cSDag-Erling Smørgrav fprintf(f, "yystack.l_mark[%ld].%s",
29988e022d3cSDag-Erling Smørgrav (long)(i - maxoffset), tag);
29990c8de5b0SBaptiste Daroussin }
30000c8de5b0SBaptiste Daroussin else if (offsets)
30018e022d3cSDag-Erling Smørgrav fprintf(f, "yystack.l_mark[%ld].%s",
30028e022d3cSDag-Erling Smørgrav (long)offsets[i], tag);
300398e903e7SBaptiste Daroussin FREE(d_line);
300498e903e7SBaptiste Daroussin goto loop;
300598e903e7SBaptiste Daroussin }
300698e903e7SBaptiste Daroussin else if (c == '-' && isdigit(UCH(cptr[1])))
300798e903e7SBaptiste Daroussin {
300898e903e7SBaptiste Daroussin ++cptr;
300998e903e7SBaptiste Daroussin i = -get_number() - n;
301098e903e7SBaptiste Daroussin fprintf(f, "yystack.l_mark[%d].%s", i, tag);
301198e903e7SBaptiste Daroussin FREE(d_line);
301298e903e7SBaptiste Daroussin goto loop;
301398e903e7SBaptiste Daroussin }
30140c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
3015b53bb29fSJung-uk Kim else if (isalpha(UCH(c)) || c == '_')
30160c8de5b0SBaptiste Daroussin {
30170c8de5b0SBaptiste Daroussin char *arg = scan_id();
30180c8de5b0SBaptiste Daroussin for (i = plhs[nrules]->args - 1; i >= 0; i--)
30190c8de5b0SBaptiste Daroussin if (arg == plhs[nrules]->argnames[i])
30200c8de5b0SBaptiste Daroussin break;
30210c8de5b0SBaptiste Daroussin if (i < 0)
30220c8de5b0SBaptiste Daroussin unknown_arg_warning(d_lineno, "$", arg, d_line, d_cptr);
3023c5b5d71aSJung-uk Kim fprintf(f, "yystack.l_mark[%d].%s",
3024c5b5d71aSJung-uk Kim i - plhs[nrules]->args + 1 - n, tag);
30250c8de5b0SBaptiste Daroussin FREE(d_line);
30260c8de5b0SBaptiste Daroussin goto loop;
30270c8de5b0SBaptiste Daroussin }
30280c8de5b0SBaptiste Daroussin #endif
302998e903e7SBaptiste Daroussin else
303098e903e7SBaptiste Daroussin dollar_error(d_lineno, d_line, d_cptr);
303198e903e7SBaptiste Daroussin }
303298e903e7SBaptiste Daroussin else if (cptr[1] == '$')
303398e903e7SBaptiste Daroussin {
30340c8de5b0SBaptiste Daroussin if (havetags)
303598e903e7SBaptiste Daroussin {
303698e903e7SBaptiste Daroussin tag = plhs[nrules]->tag;
303798e903e7SBaptiste Daroussin if (tag == 0)
303898e903e7SBaptiste Daroussin untyped_lhs();
303998e903e7SBaptiste Daroussin fprintf(f, "yyval.%s", tag);
304098e903e7SBaptiste Daroussin }
304198e903e7SBaptiste Daroussin else
304298e903e7SBaptiste Daroussin fprintf(f, "yyval");
304398e903e7SBaptiste Daroussin cptr += 2;
30440c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
30450c8de5b0SBaptiste Daroussin haveyyval = 1;
30460c8de5b0SBaptiste Daroussin #endif
304798e903e7SBaptiste Daroussin goto loop;
304898e903e7SBaptiste Daroussin }
304998e903e7SBaptiste Daroussin else if (isdigit(UCH(cptr[1])))
305098e903e7SBaptiste Daroussin {
305198e903e7SBaptiste Daroussin ++cptr;
305298e903e7SBaptiste Daroussin i = get_number();
305311fce282SBaptiste Daroussin if (havetags && offsets)
305498e903e7SBaptiste Daroussin {
30550c8de5b0SBaptiste Daroussin if (i <= 0 || i > maxoffset)
305698e903e7SBaptiste Daroussin unknown_rhs(i);
30570c8de5b0SBaptiste Daroussin tag = rhs[offsets[i]]->tag;
305898e903e7SBaptiste Daroussin if (tag == 0)
30590c8de5b0SBaptiste Daroussin untyped_rhs(i, rhs[offsets[i]]->name);
30608e022d3cSDag-Erling Smørgrav fprintf(f, "yystack.l_mark[%ld].%s", (long)offsets[i], tag);
306198e903e7SBaptiste Daroussin }
306298e903e7SBaptiste Daroussin else
306398e903e7SBaptiste Daroussin {
30640c8de5b0SBaptiste Daroussin if (i == 0)
30650c8de5b0SBaptiste Daroussin fprintf(f, "yystack.l_mark[%d]", -n);
30660c8de5b0SBaptiste Daroussin else if (i > maxoffset)
30670c8de5b0SBaptiste Daroussin {
306898e903e7SBaptiste Daroussin dollar_warning(lineno, i);
30698e022d3cSDag-Erling Smørgrav fprintf(f, "yystack.l_mark[%ld]", (long)(i - maxoffset));
30700c8de5b0SBaptiste Daroussin }
30710c8de5b0SBaptiste Daroussin else if (offsets)
30728e022d3cSDag-Erling Smørgrav fprintf(f, "yystack.l_mark[%ld]", (long)offsets[i]);
307398e903e7SBaptiste Daroussin }
307498e903e7SBaptiste Daroussin goto loop;
307598e903e7SBaptiste Daroussin }
307698e903e7SBaptiste Daroussin else if (cptr[1] == '-')
307798e903e7SBaptiste Daroussin {
307898e903e7SBaptiste Daroussin cptr += 2;
307998e903e7SBaptiste Daroussin i = get_number();
30800c8de5b0SBaptiste Daroussin if (havetags)
308198e903e7SBaptiste Daroussin unknown_rhs(-i);
308298e903e7SBaptiste Daroussin fprintf(f, "yystack.l_mark[%d]", -i - n);
308398e903e7SBaptiste Daroussin goto loop;
308498e903e7SBaptiste Daroussin }
30850c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
30862aca18c7SJung-uk Kim else if (isalpha(UCH(cptr[1])) || cptr[1] == '_')
30870c8de5b0SBaptiste Daroussin {
30880c8de5b0SBaptiste Daroussin char *arg;
30890c8de5b0SBaptiste Daroussin ++cptr;
30900c8de5b0SBaptiste Daroussin arg = scan_id();
30910c8de5b0SBaptiste Daroussin for (i = plhs[nrules]->args - 1; i >= 0; i--)
30920c8de5b0SBaptiste Daroussin if (arg == plhs[nrules]->argnames[i])
30930c8de5b0SBaptiste Daroussin break;
30940c8de5b0SBaptiste Daroussin if (i < 0)
30950c8de5b0SBaptiste Daroussin unknown_arg_warning(lineno, "$", arg, line, cptr);
30960c8de5b0SBaptiste Daroussin tag = (i < 0 ? NULL : plhs[nrules]->argtags[i]);
30970c8de5b0SBaptiste Daroussin fprintf(f, "yystack.l_mark[%d]", i - plhs[nrules]->args + 1 - n);
30980c8de5b0SBaptiste Daroussin if (tag)
30990c8de5b0SBaptiste Daroussin fprintf(f, ".%s", tag);
31000c8de5b0SBaptiste Daroussin else if (havetags)
31010c8de5b0SBaptiste Daroussin untyped_arg_warning(lineno, "$", arg);
31020c8de5b0SBaptiste Daroussin goto loop;
310398e903e7SBaptiste Daroussin }
31040c8de5b0SBaptiste Daroussin #endif
31050c8de5b0SBaptiste Daroussin }
31060c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
31070c8de5b0SBaptiste Daroussin if (c == '@')
31080c8de5b0SBaptiste Daroussin {
31090c8de5b0SBaptiste Daroussin if (!locations)
31100c8de5b0SBaptiste Daroussin {
3111*822ca327SBaptiste Daroussin dislocations_warning();
3112*822ca327SBaptiste Daroussin locations = 1;
31130c8de5b0SBaptiste Daroussin }
31140c8de5b0SBaptiste Daroussin if (cptr[1] == '$')
31150c8de5b0SBaptiste Daroussin {
31160c8de5b0SBaptiste Daroussin fprintf(f, "yyloc");
31170c8de5b0SBaptiste Daroussin cptr += 2;
31180c8de5b0SBaptiste Daroussin goto loop;
31190c8de5b0SBaptiste Daroussin }
31200c8de5b0SBaptiste Daroussin else if (isdigit(UCH(cptr[1])))
31210c8de5b0SBaptiste Daroussin {
31220c8de5b0SBaptiste Daroussin ++cptr;
31230c8de5b0SBaptiste Daroussin i = get_number();
31240c8de5b0SBaptiste Daroussin if (i == 0)
31250c8de5b0SBaptiste Daroussin fprintf(f, "yystack.p_mark[%d]", -n);
31260c8de5b0SBaptiste Daroussin else if (i > maxoffset)
31270c8de5b0SBaptiste Daroussin {
31280c8de5b0SBaptiste Daroussin at_warning(lineno, i);
31290c8de5b0SBaptiste Daroussin fprintf(f, "yystack.p_mark[%d]", i - maxoffset);
31300c8de5b0SBaptiste Daroussin }
31310c8de5b0SBaptiste Daroussin else if (offsets)
31320c8de5b0SBaptiste Daroussin fprintf(f, "yystack.p_mark[%d]", offsets[i]);
31330c8de5b0SBaptiste Daroussin goto loop;
31340c8de5b0SBaptiste Daroussin }
3135c5b5d71aSJung-uk Kim else if (cptr[1] == '-')
3136c5b5d71aSJung-uk Kim {
3137c5b5d71aSJung-uk Kim cptr += 2;
3138c5b5d71aSJung-uk Kim i = get_number();
3139c5b5d71aSJung-uk Kim fprintf(f, "yystack.p_mark[%d]", -i - n);
3140c5b5d71aSJung-uk Kim goto loop;
3141c5b5d71aSJung-uk Kim }
31420c8de5b0SBaptiste Daroussin }
31430c8de5b0SBaptiste Daroussin #endif
3144b53bb29fSJung-uk Kim if (IS_NAME1(c))
314598e903e7SBaptiste Daroussin {
314698e903e7SBaptiste Daroussin do
314798e903e7SBaptiste Daroussin {
314898e903e7SBaptiste Daroussin putc(c, f);
314998e903e7SBaptiste Daroussin c = *++cptr;
315098e903e7SBaptiste Daroussin }
3151b53bb29fSJung-uk Kim while (IS_NAME2(c));
315298e903e7SBaptiste Daroussin goto loop;
315398e903e7SBaptiste Daroussin }
315498e903e7SBaptiste Daroussin ++cptr;
31550c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
31560c8de5b0SBaptiste Daroussin if (backtrack)
31570c8de5b0SBaptiste Daroussin {
31580c8de5b0SBaptiste Daroussin if (trialaction && c == L_BRAC && depth == 0)
31590c8de5b0SBaptiste Daroussin {
31600c8de5b0SBaptiste Daroussin ++depth;
31610c8de5b0SBaptiste Daroussin putc(L_CURL, f);
31620c8de5b0SBaptiste Daroussin goto loop;
31630c8de5b0SBaptiste Daroussin }
31640c8de5b0SBaptiste Daroussin if (trialaction && c == R_BRAC && depth == 1)
31650c8de5b0SBaptiste Daroussin {
31660c8de5b0SBaptiste Daroussin --depth;
31670c8de5b0SBaptiste Daroussin putc(R_CURL, f);
31680c8de5b0SBaptiste Daroussin c = nextc();
31690c8de5b0SBaptiste Daroussin if (c == L_BRAC && !haveyyval)
31700c8de5b0SBaptiste Daroussin {
31710c8de5b0SBaptiste Daroussin goto loop;
31720c8de5b0SBaptiste Daroussin }
31730c8de5b0SBaptiste Daroussin if (c == L_CURL && !haveyyval)
31740c8de5b0SBaptiste Daroussin {
31750c8de5b0SBaptiste Daroussin fprintf(f, " if (!yytrial)\n");
31768e022d3cSDag-Erling Smørgrav fprintf_lineno(f, lineno, input_file_name);
31770c8de5b0SBaptiste Daroussin trialaction = 0;
31780c8de5b0SBaptiste Daroussin goto loop;
31790c8de5b0SBaptiste Daroussin }
31808e022d3cSDag-Erling Smørgrav end_case(f);
3181*822ca327SBaptiste Daroussin end_ainfo(a);
31820c8de5b0SBaptiste Daroussin if (maxoffset > 0)
31830c8de5b0SBaptiste Daroussin FREE(offsets);
31840c8de5b0SBaptiste Daroussin return;
31850c8de5b0SBaptiste Daroussin }
31860c8de5b0SBaptiste Daroussin }
31870c8de5b0SBaptiste Daroussin #endif
31880c8de5b0SBaptiste Daroussin putc(c, f);
318998e903e7SBaptiste Daroussin switch (c)
319098e903e7SBaptiste Daroussin {
319198e903e7SBaptiste Daroussin case '\n':
319298e903e7SBaptiste Daroussin get_line();
319398e903e7SBaptiste Daroussin if (line)
319498e903e7SBaptiste Daroussin goto loop;
31952aca18c7SJung-uk Kim unterminated_action(&a);
319698e903e7SBaptiste Daroussin
319798e903e7SBaptiste Daroussin case ';':
319898e903e7SBaptiste Daroussin if (depth > 0)
319998e903e7SBaptiste Daroussin goto loop;
32008e022d3cSDag-Erling Smørgrav end_case(f);
3201*822ca327SBaptiste Daroussin end_ainfo(a);
32020c8de5b0SBaptiste Daroussin if (maxoffset > 0)
32030c8de5b0SBaptiste Daroussin FREE(offsets);
320498e903e7SBaptiste Daroussin return;
320598e903e7SBaptiste Daroussin
32060c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
32070c8de5b0SBaptiste Daroussin case L_BRAC:
32080c8de5b0SBaptiste Daroussin if (backtrack)
32090c8de5b0SBaptiste Daroussin ++depth;
32100c8de5b0SBaptiste Daroussin goto loop;
32110c8de5b0SBaptiste Daroussin
32120c8de5b0SBaptiste Daroussin case R_BRAC:
32130c8de5b0SBaptiste Daroussin if (backtrack)
32140c8de5b0SBaptiste Daroussin --depth;
32150c8de5b0SBaptiste Daroussin goto loop;
32160c8de5b0SBaptiste Daroussin #endif
32170c8de5b0SBaptiste Daroussin
321898e903e7SBaptiste Daroussin case L_CURL:
321998e903e7SBaptiste Daroussin ++depth;
322098e903e7SBaptiste Daroussin goto loop;
322198e903e7SBaptiste Daroussin
322298e903e7SBaptiste Daroussin case R_CURL:
322398e903e7SBaptiste Daroussin if (--depth > 0)
322498e903e7SBaptiste Daroussin goto loop;
32250c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
32260c8de5b0SBaptiste Daroussin if (backtrack)
32270c8de5b0SBaptiste Daroussin {
32280c8de5b0SBaptiste Daroussin c = nextc();
32290c8de5b0SBaptiste Daroussin if (c == L_BRAC && !haveyyval)
32300c8de5b0SBaptiste Daroussin {
32310c8de5b0SBaptiste Daroussin trialaction = 1;
32320c8de5b0SBaptiste Daroussin goto loop;
32330c8de5b0SBaptiste Daroussin }
32340c8de5b0SBaptiste Daroussin if (c == L_CURL && !haveyyval)
32350c8de5b0SBaptiste Daroussin {
32360c8de5b0SBaptiste Daroussin fprintf(f, " if (!yytrial)\n");
32378e022d3cSDag-Erling Smørgrav fprintf_lineno(f, lineno, input_file_name);
32380c8de5b0SBaptiste Daroussin goto loop;
32390c8de5b0SBaptiste Daroussin }
32400c8de5b0SBaptiste Daroussin }
32410c8de5b0SBaptiste Daroussin #endif
32428e022d3cSDag-Erling Smørgrav end_case(f);
3243*822ca327SBaptiste Daroussin end_ainfo(a);
32440c8de5b0SBaptiste Daroussin if (maxoffset > 0)
32450c8de5b0SBaptiste Daroussin FREE(offsets);
324698e903e7SBaptiste Daroussin return;
324798e903e7SBaptiste Daroussin
324898e903e7SBaptiste Daroussin case '\'':
324998e903e7SBaptiste Daroussin case '"':
325098e903e7SBaptiste Daroussin {
32510c8de5b0SBaptiste Daroussin char *s = copy_string(c);
32520c8de5b0SBaptiste Daroussin fputs(s, f);
32530c8de5b0SBaptiste Daroussin free(s);
32540c8de5b0SBaptiste Daroussin }
32550c8de5b0SBaptiste Daroussin goto loop;
325698e903e7SBaptiste Daroussin
32570c8de5b0SBaptiste Daroussin case '/':
32580c8de5b0SBaptiste Daroussin {
32590c8de5b0SBaptiste Daroussin char *s = copy_comment();
32600c8de5b0SBaptiste Daroussin fputs(s, f);
32610c8de5b0SBaptiste Daroussin free(s);
32620c8de5b0SBaptiste Daroussin }
32630c8de5b0SBaptiste Daroussin goto loop;
32640c8de5b0SBaptiste Daroussin
32650c8de5b0SBaptiste Daroussin default:
32660c8de5b0SBaptiste Daroussin goto loop;
32670c8de5b0SBaptiste Daroussin }
32680c8de5b0SBaptiste Daroussin }
32690c8de5b0SBaptiste Daroussin
32700c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
32712aca18c7SJung-uk Kim static char *
get_code(struct ainfo * a,const char * loc)32722aca18c7SJung-uk Kim get_code(struct ainfo *a, const char *loc)
32730c8de5b0SBaptiste Daroussin {
32740c8de5b0SBaptiste Daroussin int c;
32750c8de5b0SBaptiste Daroussin int depth;
32760c8de5b0SBaptiste Daroussin char *tag;
32772aca18c7SJung-uk Kim struct mstring *code_mstr = msnew();
32780c8de5b0SBaptiste Daroussin
32790c8de5b0SBaptiste Daroussin if (!lflag)
32802aca18c7SJung-uk Kim msprintf(code_mstr, line_format, lineno, input_file_name);
32810c8de5b0SBaptiste Daroussin
32820c8de5b0SBaptiste Daroussin cptr = after_blanks(cptr);
32830c8de5b0SBaptiste Daroussin if (*cptr == L_CURL)
32840c8de5b0SBaptiste Daroussin /* avoid putting curly-braces in first column, to ease editing */
32852aca18c7SJung-uk Kim mputc(code_mstr, '\t');
32860c8de5b0SBaptiste Daroussin else
32870c8de5b0SBaptiste Daroussin syntax_error(lineno, line, cptr);
32880c8de5b0SBaptiste Daroussin
3289*822ca327SBaptiste Daroussin begin_ainfo((*a), 0);
32900c8de5b0SBaptiste Daroussin
32910c8de5b0SBaptiste Daroussin depth = 0;
32920c8de5b0SBaptiste Daroussin loop:
32930c8de5b0SBaptiste Daroussin c = *cptr;
32940c8de5b0SBaptiste Daroussin if (c == '$')
32950c8de5b0SBaptiste Daroussin {
32960c8de5b0SBaptiste Daroussin if (cptr[1] == '<')
32970c8de5b0SBaptiste Daroussin {
32980c8de5b0SBaptiste Daroussin int d_lineno = lineno;
32990c8de5b0SBaptiste Daroussin char *d_line = dup_line();
33000c8de5b0SBaptiste Daroussin char *d_cptr = d_line + (cptr - line);
33010c8de5b0SBaptiste Daroussin
33020c8de5b0SBaptiste Daroussin ++cptr;
33030c8de5b0SBaptiste Daroussin tag = get_tag();
33040c8de5b0SBaptiste Daroussin c = *cptr;
33050c8de5b0SBaptiste Daroussin if (c == '$')
33060c8de5b0SBaptiste Daroussin {
33072aca18c7SJung-uk Kim msprintf(code_mstr, "(*val).%s", tag);
33080c8de5b0SBaptiste Daroussin ++cptr;
33090c8de5b0SBaptiste Daroussin FREE(d_line);
33100c8de5b0SBaptiste Daroussin goto loop;
33110c8de5b0SBaptiste Daroussin }
33120c8de5b0SBaptiste Daroussin else
33130c8de5b0SBaptiste Daroussin dollar_error(d_lineno, d_line, d_cptr);
33140c8de5b0SBaptiste Daroussin }
33150c8de5b0SBaptiste Daroussin else if (cptr[1] == '$')
33160c8de5b0SBaptiste Daroussin {
33170c8de5b0SBaptiste Daroussin /* process '$$' later; replacement is context dependent */
33182aca18c7SJung-uk Kim msprintf(code_mstr, "$$");
33190c8de5b0SBaptiste Daroussin cptr += 2;
33200c8de5b0SBaptiste Daroussin goto loop;
33210c8de5b0SBaptiste Daroussin }
33220c8de5b0SBaptiste Daroussin }
33230c8de5b0SBaptiste Daroussin if (c == '@' && cptr[1] == '$')
33240c8de5b0SBaptiste Daroussin {
33250c8de5b0SBaptiste Daroussin if (!locations)
33260c8de5b0SBaptiste Daroussin {
3327*822ca327SBaptiste Daroussin dislocations_warning();
3328*822ca327SBaptiste Daroussin locations = 1;
33290c8de5b0SBaptiste Daroussin }
33302aca18c7SJung-uk Kim msprintf(code_mstr, "%s", loc);
33310c8de5b0SBaptiste Daroussin cptr += 2;
33320c8de5b0SBaptiste Daroussin goto loop;
33330c8de5b0SBaptiste Daroussin }
3334b53bb29fSJung-uk Kim if (IS_NAME1(c))
33350c8de5b0SBaptiste Daroussin {
33360c8de5b0SBaptiste Daroussin do
33370c8de5b0SBaptiste Daroussin {
33382aca18c7SJung-uk Kim mputc(code_mstr, c);
33390c8de5b0SBaptiste Daroussin c = *++cptr;
33400c8de5b0SBaptiste Daroussin }
3341b53bb29fSJung-uk Kim while (IS_NAME2(c));
33420c8de5b0SBaptiste Daroussin goto loop;
33430c8de5b0SBaptiste Daroussin }
33440c8de5b0SBaptiste Daroussin ++cptr;
33452aca18c7SJung-uk Kim mputc(code_mstr, c);
33460c8de5b0SBaptiste Daroussin switch (c)
33470c8de5b0SBaptiste Daroussin {
33480c8de5b0SBaptiste Daroussin case '\n':
33490c8de5b0SBaptiste Daroussin get_line();
33500c8de5b0SBaptiste Daroussin if (line)
33510c8de5b0SBaptiste Daroussin goto loop;
33522aca18c7SJung-uk Kim unterminated_action(a);
33530c8de5b0SBaptiste Daroussin
33540c8de5b0SBaptiste Daroussin case L_CURL:
33550c8de5b0SBaptiste Daroussin ++depth;
33560c8de5b0SBaptiste Daroussin goto loop;
33570c8de5b0SBaptiste Daroussin
33580c8de5b0SBaptiste Daroussin case R_CURL:
33590c8de5b0SBaptiste Daroussin if (--depth > 0)
33600c8de5b0SBaptiste Daroussin goto loop;
33612aca18c7SJung-uk Kim goto out;
33620c8de5b0SBaptiste Daroussin
33630c8de5b0SBaptiste Daroussin case '\'':
33640c8de5b0SBaptiste Daroussin case '"':
33650c8de5b0SBaptiste Daroussin {
33660c8de5b0SBaptiste Daroussin char *s = copy_string(c);
33672aca18c7SJung-uk Kim msprintf(code_mstr, "%s", s);
33680c8de5b0SBaptiste Daroussin free(s);
33690c8de5b0SBaptiste Daroussin }
33700c8de5b0SBaptiste Daroussin goto loop;
33710c8de5b0SBaptiste Daroussin
33720c8de5b0SBaptiste Daroussin case '/':
33730c8de5b0SBaptiste Daroussin {
33740c8de5b0SBaptiste Daroussin char *s = copy_comment();
33752aca18c7SJung-uk Kim msprintf(code_mstr, "%s", s);
33760c8de5b0SBaptiste Daroussin free(s);
33770c8de5b0SBaptiste Daroussin }
33780c8de5b0SBaptiste Daroussin goto loop;
33790c8de5b0SBaptiste Daroussin
33800c8de5b0SBaptiste Daroussin default:
33810c8de5b0SBaptiste Daroussin goto loop;
33820c8de5b0SBaptiste Daroussin }
33832aca18c7SJung-uk Kim out:
33842aca18c7SJung-uk Kim return msdone(code_mstr);
33852aca18c7SJung-uk Kim }
33862aca18c7SJung-uk Kim
33872aca18c7SJung-uk Kim static void
copy_initial_action(void)33882aca18c7SJung-uk Kim copy_initial_action(void)
33892aca18c7SJung-uk Kim {
33902aca18c7SJung-uk Kim struct ainfo a;
33912aca18c7SJung-uk Kim
33922aca18c7SJung-uk Kim initial_action = get_code(&a, "yyloc");
3393*822ca327SBaptiste Daroussin end_ainfo(a);
33942aca18c7SJung-uk Kim }
33952aca18c7SJung-uk Kim
33962aca18c7SJung-uk Kim static void
copy_destructor(void)33972aca18c7SJung-uk Kim copy_destructor(void)
33982aca18c7SJung-uk Kim {
33992aca18c7SJung-uk Kim char *code_text;
34002aca18c7SJung-uk Kim struct ainfo a;
34012aca18c7SJung-uk Kim bucket *bp;
34022aca18c7SJung-uk Kim
34032aca18c7SJung-uk Kim code_text = get_code(&a, "(*loc)");
34042aca18c7SJung-uk Kim
34050c8de5b0SBaptiste Daroussin for (;;)
34060c8de5b0SBaptiste Daroussin {
34078e022d3cSDag-Erling Smørgrav int c = nextc();
34080c8de5b0SBaptiste Daroussin if (c == EOF)
34090c8de5b0SBaptiste Daroussin unexpected_EOF();
34100c8de5b0SBaptiste Daroussin if (c == '<')
34110c8de5b0SBaptiste Daroussin {
34120c8de5b0SBaptiste Daroussin if (cptr[1] == '>')
34130c8de5b0SBaptiste Daroussin { /* "no semantic type" default destructor */
34140c8de5b0SBaptiste Daroussin cptr += 2;
34150c8de5b0SBaptiste Daroussin if ((bp = default_destructor[UNTYPED_DEFAULT]) == NULL)
34160c8de5b0SBaptiste Daroussin {
34170c8de5b0SBaptiste Daroussin static char untyped_default[] = "<>";
34180c8de5b0SBaptiste Daroussin bp = make_bucket("untyped default");
34190c8de5b0SBaptiste Daroussin bp->tag = untyped_default;
34200c8de5b0SBaptiste Daroussin default_destructor[UNTYPED_DEFAULT] = bp;
34210c8de5b0SBaptiste Daroussin }
34220c8de5b0SBaptiste Daroussin if (bp->destructor != NULL)
34232aca18c7SJung-uk Kim destructor_redeclared_warning(&a);
34240c8de5b0SBaptiste Daroussin else
34250c8de5b0SBaptiste Daroussin /* replace "$$" with "(*val)" in destructor code */
34260c8de5b0SBaptiste Daroussin bp->destructor = process_destructor_XX(code_text, NULL);
34270c8de5b0SBaptiste Daroussin }
34280c8de5b0SBaptiste Daroussin else if (cptr[1] == '*' && cptr[2] == '>')
34290c8de5b0SBaptiste Daroussin { /* "no per-symbol or per-type" default destructor */
34300c8de5b0SBaptiste Daroussin cptr += 3;
34310c8de5b0SBaptiste Daroussin if ((bp = default_destructor[TYPED_DEFAULT]) == NULL)
34320c8de5b0SBaptiste Daroussin {
34330c8de5b0SBaptiste Daroussin static char typed_default[] = "<*>";
34340c8de5b0SBaptiste Daroussin bp = make_bucket("typed default");
34350c8de5b0SBaptiste Daroussin bp->tag = typed_default;
34360c8de5b0SBaptiste Daroussin default_destructor[TYPED_DEFAULT] = bp;
34370c8de5b0SBaptiste Daroussin }
34380c8de5b0SBaptiste Daroussin if (bp->destructor != NULL)
34392aca18c7SJung-uk Kim destructor_redeclared_warning(&a);
34400c8de5b0SBaptiste Daroussin else
34410c8de5b0SBaptiste Daroussin {
34420c8de5b0SBaptiste Daroussin /* postpone re-processing destructor $$s until end of grammar spec */
34430c8de5b0SBaptiste Daroussin bp->destructor = TMALLOC(char, strlen(code_text) + 1);
34440c8de5b0SBaptiste Daroussin NO_SPACE(bp->destructor);
34450c8de5b0SBaptiste Daroussin strcpy(bp->destructor, code_text);
34460c8de5b0SBaptiste Daroussin }
34470c8de5b0SBaptiste Daroussin }
34480c8de5b0SBaptiste Daroussin else
34490c8de5b0SBaptiste Daroussin { /* "semantic type" default destructor */
34502aca18c7SJung-uk Kim char *tag = get_tag();
34510c8de5b0SBaptiste Daroussin bp = lookup_type_destructor(tag);
34520c8de5b0SBaptiste Daroussin if (bp->destructor != NULL)
34532aca18c7SJung-uk Kim destructor_redeclared_warning(&a);
34540c8de5b0SBaptiste Daroussin else
34550c8de5b0SBaptiste Daroussin /* replace "$$" with "(*val).tag" in destructor code */
34560c8de5b0SBaptiste Daroussin bp->destructor = process_destructor_XX(code_text, tag);
34570c8de5b0SBaptiste Daroussin }
34580c8de5b0SBaptiste Daroussin }
3459b53bb29fSJung-uk Kim else if (isalpha(UCH(c)) || c == '_' || c == '.' || c == '$')
34600c8de5b0SBaptiste Daroussin { /* "symbol" destructor */
34610c8de5b0SBaptiste Daroussin bp = get_name();
34620c8de5b0SBaptiste Daroussin if (bp->destructor != NULL)
34632aca18c7SJung-uk Kim destructor_redeclared_warning(&a);
34640c8de5b0SBaptiste Daroussin else
34650c8de5b0SBaptiste Daroussin {
34660c8de5b0SBaptiste Daroussin /* postpone re-processing destructor $$s until end of grammar spec */
34670c8de5b0SBaptiste Daroussin bp->destructor = TMALLOC(char, strlen(code_text) + 1);
34680c8de5b0SBaptiste Daroussin NO_SPACE(bp->destructor);
34690c8de5b0SBaptiste Daroussin strcpy(bp->destructor, code_text);
34700c8de5b0SBaptiste Daroussin }
34710c8de5b0SBaptiste Daroussin }
34720c8de5b0SBaptiste Daroussin else
34730c8de5b0SBaptiste Daroussin break;
34740c8de5b0SBaptiste Daroussin }
3475*822ca327SBaptiste Daroussin end_ainfo(a);
34760c8de5b0SBaptiste Daroussin free(code_text);
34770c8de5b0SBaptiste Daroussin }
34780c8de5b0SBaptiste Daroussin
34790c8de5b0SBaptiste Daroussin static char *
process_destructor_XX(char * code,char * tag)34800c8de5b0SBaptiste Daroussin process_destructor_XX(char *code, char *tag)
34810c8de5b0SBaptiste Daroussin {
34820c8de5b0SBaptiste Daroussin int c;
34830c8de5b0SBaptiste Daroussin int quote;
34840c8de5b0SBaptiste Daroussin int depth;
34850c8de5b0SBaptiste Daroussin struct mstring *new_code = msnew();
34860c8de5b0SBaptiste Daroussin char *codeptr = code;
34870c8de5b0SBaptiste Daroussin
34880c8de5b0SBaptiste Daroussin depth = 0;
34890c8de5b0SBaptiste Daroussin loop: /* step thru code */
34900c8de5b0SBaptiste Daroussin c = *codeptr;
34910c8de5b0SBaptiste Daroussin if (c == '$' && codeptr[1] == '$')
34920c8de5b0SBaptiste Daroussin {
34930c8de5b0SBaptiste Daroussin codeptr += 2;
34940c8de5b0SBaptiste Daroussin if (tag == NULL)
34950c8de5b0SBaptiste Daroussin msprintf(new_code, "(*val)");
34960c8de5b0SBaptiste Daroussin else
34970c8de5b0SBaptiste Daroussin msprintf(new_code, "(*val).%s", tag);
34980c8de5b0SBaptiste Daroussin goto loop;
34990c8de5b0SBaptiste Daroussin }
3500b53bb29fSJung-uk Kim if (IS_NAME1(c))
35010c8de5b0SBaptiste Daroussin {
35020c8de5b0SBaptiste Daroussin do
35030c8de5b0SBaptiste Daroussin {
35040c8de5b0SBaptiste Daroussin mputc(new_code, c);
35050c8de5b0SBaptiste Daroussin c = *++codeptr;
35060c8de5b0SBaptiste Daroussin }
3507b53bb29fSJung-uk Kim while (IS_NAME2(c));
35080c8de5b0SBaptiste Daroussin goto loop;
35090c8de5b0SBaptiste Daroussin }
35100c8de5b0SBaptiste Daroussin ++codeptr;
35110c8de5b0SBaptiste Daroussin mputc(new_code, c);
35120c8de5b0SBaptiste Daroussin switch (c)
35130c8de5b0SBaptiste Daroussin {
35140c8de5b0SBaptiste Daroussin case L_CURL:
35150c8de5b0SBaptiste Daroussin ++depth;
35160c8de5b0SBaptiste Daroussin goto loop;
35170c8de5b0SBaptiste Daroussin
35180c8de5b0SBaptiste Daroussin case R_CURL:
35190c8de5b0SBaptiste Daroussin if (--depth > 0)
35200c8de5b0SBaptiste Daroussin goto loop;
35210c8de5b0SBaptiste Daroussin return msdone(new_code);
35220c8de5b0SBaptiste Daroussin
35230c8de5b0SBaptiste Daroussin case '\'':
35240c8de5b0SBaptiste Daroussin case '"':
352598e903e7SBaptiste Daroussin quote = c;
352698e903e7SBaptiste Daroussin for (;;)
352798e903e7SBaptiste Daroussin {
35280c8de5b0SBaptiste Daroussin c = *codeptr++;
35290c8de5b0SBaptiste Daroussin mputc(new_code, c);
353098e903e7SBaptiste Daroussin if (c == quote)
353198e903e7SBaptiste Daroussin goto loop;
353298e903e7SBaptiste Daroussin if (c == '\\')
353398e903e7SBaptiste Daroussin {
35340c8de5b0SBaptiste Daroussin c = *codeptr++;
35350c8de5b0SBaptiste Daroussin mputc(new_code, c);
353698e903e7SBaptiste Daroussin }
353798e903e7SBaptiste Daroussin }
353898e903e7SBaptiste Daroussin
353998e903e7SBaptiste Daroussin case '/':
35400c8de5b0SBaptiste Daroussin c = *codeptr;
354198e903e7SBaptiste Daroussin if (c == '*')
354298e903e7SBaptiste Daroussin {
35430c8de5b0SBaptiste Daroussin mputc(new_code, c);
35440c8de5b0SBaptiste Daroussin ++codeptr;
354598e903e7SBaptiste Daroussin for (;;)
354698e903e7SBaptiste Daroussin {
35470c8de5b0SBaptiste Daroussin c = *codeptr++;
35480c8de5b0SBaptiste Daroussin mputc(new_code, c);
35490c8de5b0SBaptiste Daroussin if (c == '*' && *codeptr == '/')
355098e903e7SBaptiste Daroussin {
35510c8de5b0SBaptiste Daroussin mputc(new_code, '/');
35520c8de5b0SBaptiste Daroussin ++codeptr;
355398e903e7SBaptiste Daroussin goto loop;
355498e903e7SBaptiste Daroussin }
355598e903e7SBaptiste Daroussin }
355698e903e7SBaptiste Daroussin }
355798e903e7SBaptiste Daroussin goto loop;
355898e903e7SBaptiste Daroussin
355998e903e7SBaptiste Daroussin default:
356098e903e7SBaptiste Daroussin goto loop;
356198e903e7SBaptiste Daroussin }
356298e903e7SBaptiste Daroussin }
35630c8de5b0SBaptiste Daroussin #endif /* defined(YYBTYACC) */
356498e903e7SBaptiste Daroussin
356598e903e7SBaptiste Daroussin static int
mark_symbol(void)356698e903e7SBaptiste Daroussin mark_symbol(void)
356798e903e7SBaptiste Daroussin {
356898e903e7SBaptiste Daroussin int c;
35693e066022SBaptiste Daroussin bucket *bp = NULL;
357098e903e7SBaptiste Daroussin
357198e903e7SBaptiste Daroussin c = cptr[1];
357298e903e7SBaptiste Daroussin if (c == '%' || c == '\\')
357398e903e7SBaptiste Daroussin {
357498e903e7SBaptiste Daroussin cptr += 2;
357598e903e7SBaptiste Daroussin return (1);
357698e903e7SBaptiste Daroussin }
357798e903e7SBaptiste Daroussin
357898e903e7SBaptiste Daroussin if (c == '=')
357998e903e7SBaptiste Daroussin cptr += 2;
358098e903e7SBaptiste Daroussin else if ((c == 'p' || c == 'P') &&
358198e903e7SBaptiste Daroussin ((c = cptr[2]) == 'r' || c == 'R') &&
358298e903e7SBaptiste Daroussin ((c = cptr[3]) == 'e' || c == 'E') &&
358398e903e7SBaptiste Daroussin ((c = cptr[4]) == 'c' || c == 'C') &&
358498e903e7SBaptiste Daroussin ((c = cptr[5], !IS_IDENT(c))))
358598e903e7SBaptiste Daroussin cptr += 5;
35868e022d3cSDag-Erling Smørgrav else if ((c == 'e' || c == 'E') &&
35878e022d3cSDag-Erling Smørgrav ((c = cptr[2]) == 'm' || c == 'M') &&
35888e022d3cSDag-Erling Smørgrav ((c = cptr[3]) == 'p' || c == 'P') &&
35898e022d3cSDag-Erling Smørgrav ((c = cptr[4]) == 't' || c == 'T') &&
35908e022d3cSDag-Erling Smørgrav ((c = cptr[5]) == 'y' || c == 'Y') &&
35918e022d3cSDag-Erling Smørgrav ((c = cptr[6], !IS_IDENT(c))))
35928e022d3cSDag-Erling Smørgrav {
35938e022d3cSDag-Erling Smørgrav cptr += 6;
35948e022d3cSDag-Erling Smørgrav return (1);
35958e022d3cSDag-Erling Smørgrav }
359698e903e7SBaptiste Daroussin else
359798e903e7SBaptiste Daroussin syntax_error(lineno, line, cptr);
359898e903e7SBaptiste Daroussin
359998e903e7SBaptiste Daroussin c = nextc();
3600b53bb29fSJung-uk Kim if (isalpha(UCH(c)) || c == '_' || c == '.' || c == '$')
360198e903e7SBaptiste Daroussin bp = get_name();
360298e903e7SBaptiste Daroussin else if (c == '\'' || c == '"')
360398e903e7SBaptiste Daroussin bp = get_literal();
360498e903e7SBaptiste Daroussin else
360598e903e7SBaptiste Daroussin {
360698e903e7SBaptiste Daroussin syntax_error(lineno, line, cptr);
3607c5b5d71aSJung-uk Kim /*NOTREACHED */
360898e903e7SBaptiste Daroussin }
360998e903e7SBaptiste Daroussin
361098e903e7SBaptiste Daroussin if (rprec[nrules] != UNDEFINED && bp->prec != rprec[nrules])
361198e903e7SBaptiste Daroussin prec_redeclared();
361298e903e7SBaptiste Daroussin
361398e903e7SBaptiste Daroussin rprec[nrules] = bp->prec;
361498e903e7SBaptiste Daroussin rassoc[nrules] = bp->assoc;
361598e903e7SBaptiste Daroussin return (0);
361698e903e7SBaptiste Daroussin }
361798e903e7SBaptiste Daroussin
361898e903e7SBaptiste Daroussin static void
read_grammar(void)361998e903e7SBaptiste Daroussin read_grammar(void)
362098e903e7SBaptiste Daroussin {
362198e903e7SBaptiste Daroussin initialize_grammar();
362298e903e7SBaptiste Daroussin advance_to_start();
362398e903e7SBaptiste Daroussin
362498e903e7SBaptiste Daroussin for (;;)
362598e903e7SBaptiste Daroussin {
36268e022d3cSDag-Erling Smørgrav int c = nextc();
36278e022d3cSDag-Erling Smørgrav
362898e903e7SBaptiste Daroussin if (c == EOF)
362998e903e7SBaptiste Daroussin break;
3630b53bb29fSJung-uk Kim if (isalpha(UCH(c))
363198e903e7SBaptiste Daroussin || c == '_'
363298e903e7SBaptiste Daroussin || c == '.'
363398e903e7SBaptiste Daroussin || c == '$'
363498e903e7SBaptiste Daroussin || c == '\''
363598e903e7SBaptiste Daroussin || c == '"')
36368e022d3cSDag-Erling Smørgrav {
363798e903e7SBaptiste Daroussin add_symbol();
36388e022d3cSDag-Erling Smørgrav }
36398e022d3cSDag-Erling Smørgrav else if (c == L_CURL || c == '='
36400c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
36418e022d3cSDag-Erling Smørgrav || (backtrack && c == L_BRAC)
36420c8de5b0SBaptiste Daroussin #endif
36438e022d3cSDag-Erling Smørgrav )
36448e022d3cSDag-Erling Smørgrav {
364598e903e7SBaptiste Daroussin copy_action();
36468e022d3cSDag-Erling Smørgrav }
364798e903e7SBaptiste Daroussin else if (c == '|')
364898e903e7SBaptiste Daroussin {
364998e903e7SBaptiste Daroussin end_rule();
365098e903e7SBaptiste Daroussin start_rule(plhs[nrules - 1], 0);
365198e903e7SBaptiste Daroussin ++cptr;
365298e903e7SBaptiste Daroussin }
365398e903e7SBaptiste Daroussin else if (c == '%')
365498e903e7SBaptiste Daroussin {
365598e903e7SBaptiste Daroussin if (mark_symbol())
365698e903e7SBaptiste Daroussin break;
365798e903e7SBaptiste Daroussin }
365898e903e7SBaptiste Daroussin else
365998e903e7SBaptiste Daroussin syntax_error(lineno, line, cptr);
366098e903e7SBaptiste Daroussin }
366198e903e7SBaptiste Daroussin end_rule();
36620c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
36630c8de5b0SBaptiste Daroussin if (goal->args > 0)
36640c8de5b0SBaptiste Daroussin start_requires_args(goal->name);
36650c8de5b0SBaptiste Daroussin #endif
366698e903e7SBaptiste Daroussin }
366798e903e7SBaptiste Daroussin
366898e903e7SBaptiste Daroussin static void
free_tags(void)366998e903e7SBaptiste Daroussin free_tags(void)
367098e903e7SBaptiste Daroussin {
367198e903e7SBaptiste Daroussin int i;
367298e903e7SBaptiste Daroussin
367398e903e7SBaptiste Daroussin if (tag_table == 0)
367498e903e7SBaptiste Daroussin return;
367598e903e7SBaptiste Daroussin
367698e903e7SBaptiste Daroussin for (i = 0; i < ntags; ++i)
367798e903e7SBaptiste Daroussin {
367898e903e7SBaptiste Daroussin assert(tag_table[i]);
367998e903e7SBaptiste Daroussin FREE(tag_table[i]);
368098e903e7SBaptiste Daroussin }
368198e903e7SBaptiste Daroussin FREE(tag_table);
368298e903e7SBaptiste Daroussin }
368398e903e7SBaptiste Daroussin
368498e903e7SBaptiste Daroussin static void
pack_names(void)368598e903e7SBaptiste Daroussin pack_names(void)
368698e903e7SBaptiste Daroussin {
368798e903e7SBaptiste Daroussin bucket *bp;
36888e022d3cSDag-Erling Smørgrav char *p;
36898e022d3cSDag-Erling Smørgrav char *t;
369098e903e7SBaptiste Daroussin
369198e903e7SBaptiste Daroussin name_pool_size = 13; /* 13 == sizeof("$end") + sizeof("$accept") */
369298e903e7SBaptiste Daroussin for (bp = first_symbol; bp; bp = bp->next)
369398e903e7SBaptiste Daroussin name_pool_size += strlen(bp->name) + 1;
369498e903e7SBaptiste Daroussin
36953e066022SBaptiste Daroussin name_pool = TMALLOC(char, name_pool_size);
369698e903e7SBaptiste Daroussin NO_SPACE(name_pool);
369798e903e7SBaptiste Daroussin
369898e903e7SBaptiste Daroussin strcpy(name_pool, "$accept");
369998e903e7SBaptiste Daroussin strcpy(name_pool + 8, "$end");
370098e903e7SBaptiste Daroussin t = name_pool + 13;
370198e903e7SBaptiste Daroussin for (bp = first_symbol; bp; bp = bp->next)
370298e903e7SBaptiste Daroussin {
37038e022d3cSDag-Erling Smørgrav char *s = bp->name;
37048e022d3cSDag-Erling Smørgrav
370598e903e7SBaptiste Daroussin p = t;
370698e903e7SBaptiste Daroussin while ((*t++ = *s++) != 0)
370798e903e7SBaptiste Daroussin continue;
370898e903e7SBaptiste Daroussin FREE(bp->name);
370998e903e7SBaptiste Daroussin bp->name = p;
371098e903e7SBaptiste Daroussin }
371198e903e7SBaptiste Daroussin }
371298e903e7SBaptiste Daroussin
371398e903e7SBaptiste Daroussin static void
check_symbols(void)371498e903e7SBaptiste Daroussin check_symbols(void)
371598e903e7SBaptiste Daroussin {
371698e903e7SBaptiste Daroussin bucket *bp;
371798e903e7SBaptiste Daroussin
371898e903e7SBaptiste Daroussin if (goal->class == UNKNOWN)
371998e903e7SBaptiste Daroussin undefined_goal(goal->name);
372098e903e7SBaptiste Daroussin
372198e903e7SBaptiste Daroussin for (bp = first_symbol; bp; bp = bp->next)
372298e903e7SBaptiste Daroussin {
372398e903e7SBaptiste Daroussin if (bp->class == UNKNOWN)
372498e903e7SBaptiste Daroussin {
372598e903e7SBaptiste Daroussin undefined_symbol_warning(bp->name);
372698e903e7SBaptiste Daroussin bp->class = TERM;
372798e903e7SBaptiste Daroussin }
372898e903e7SBaptiste Daroussin }
372998e903e7SBaptiste Daroussin }
373098e903e7SBaptiste Daroussin
373198e903e7SBaptiste Daroussin static void
protect_string(char * src,char ** des)373298e903e7SBaptiste Daroussin protect_string(char *src, char **des)
373398e903e7SBaptiste Daroussin {
373498e903e7SBaptiste Daroussin *des = src;
373598e903e7SBaptiste Daroussin if (src)
373698e903e7SBaptiste Daroussin {
37378e022d3cSDag-Erling Smørgrav char *s;
37388e022d3cSDag-Erling Smørgrav char *d;
37398e022d3cSDag-Erling Smørgrav
37408e022d3cSDag-Erling Smørgrav unsigned len = 1;
37418e022d3cSDag-Erling Smørgrav
374298e903e7SBaptiste Daroussin s = src;
374398e903e7SBaptiste Daroussin while (*s)
374498e903e7SBaptiste Daroussin {
374598e903e7SBaptiste Daroussin if ('\\' == *s || '"' == *s)
374698e903e7SBaptiste Daroussin len++;
374798e903e7SBaptiste Daroussin s++;
374898e903e7SBaptiste Daroussin len++;
374998e903e7SBaptiste Daroussin }
375098e903e7SBaptiste Daroussin
37513e066022SBaptiste Daroussin *des = d = TMALLOC(char, len);
375298e903e7SBaptiste Daroussin NO_SPACE(d);
375398e903e7SBaptiste Daroussin
375498e903e7SBaptiste Daroussin s = src;
375598e903e7SBaptiste Daroussin while (*s)
375698e903e7SBaptiste Daroussin {
375798e903e7SBaptiste Daroussin if ('\\' == *s || '"' == *s)
375898e903e7SBaptiste Daroussin *d++ = '\\';
375998e903e7SBaptiste Daroussin *d++ = *s++;
376098e903e7SBaptiste Daroussin }
376198e903e7SBaptiste Daroussin *d = '\0';
376298e903e7SBaptiste Daroussin }
376398e903e7SBaptiste Daroussin }
376498e903e7SBaptiste Daroussin
376598e903e7SBaptiste Daroussin static void
pack_symbols(void)376698e903e7SBaptiste Daroussin pack_symbols(void)
376798e903e7SBaptiste Daroussin {
376898e903e7SBaptiste Daroussin bucket *bp;
376998e903e7SBaptiste Daroussin bucket **v;
377098e903e7SBaptiste Daroussin Value_t i, j, k, n;
37710c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
37720c8de5b0SBaptiste Daroussin Value_t max_tok_pval;
37730c8de5b0SBaptiste Daroussin #endif
377498e903e7SBaptiste Daroussin
377598e903e7SBaptiste Daroussin nsyms = 2;
377698e903e7SBaptiste Daroussin ntokens = 1;
377798e903e7SBaptiste Daroussin for (bp = first_symbol; bp; bp = bp->next)
377898e903e7SBaptiste Daroussin {
377998e903e7SBaptiste Daroussin ++nsyms;
378098e903e7SBaptiste Daroussin if (bp->class == TERM)
378198e903e7SBaptiste Daroussin ++ntokens;
378298e903e7SBaptiste Daroussin }
378398e903e7SBaptiste Daroussin start_symbol = (Value_t)ntokens;
37840c8de5b0SBaptiste Daroussin nvars = (Value_t)(nsyms - ntokens);
378598e903e7SBaptiste Daroussin
37863e066022SBaptiste Daroussin symbol_name = TMALLOC(char *, nsyms);
378798e903e7SBaptiste Daroussin NO_SPACE(symbol_name);
378898e903e7SBaptiste Daroussin
37893e066022SBaptiste Daroussin symbol_value = TMALLOC(Value_t, nsyms);
379098e903e7SBaptiste Daroussin NO_SPACE(symbol_value);
379198e903e7SBaptiste Daroussin
37920c8de5b0SBaptiste Daroussin symbol_prec = TMALLOC(Value_t, nsyms);
379398e903e7SBaptiste Daroussin NO_SPACE(symbol_prec);
379498e903e7SBaptiste Daroussin
37953e066022SBaptiste Daroussin symbol_assoc = TMALLOC(char, nsyms);
379698e903e7SBaptiste Daroussin NO_SPACE(symbol_assoc);
379798e903e7SBaptiste Daroussin
37980c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
37990c8de5b0SBaptiste Daroussin symbol_pval = TMALLOC(Value_t, nsyms);
38000c8de5b0SBaptiste Daroussin NO_SPACE(symbol_pval);
38010c8de5b0SBaptiste Daroussin
38020c8de5b0SBaptiste Daroussin if (destructor)
38030c8de5b0SBaptiste Daroussin {
38040c8de5b0SBaptiste Daroussin symbol_destructor = CALLOC(sizeof(char *), nsyms);
38050c8de5b0SBaptiste Daroussin NO_SPACE(symbol_destructor);
38060c8de5b0SBaptiste Daroussin
38070c8de5b0SBaptiste Daroussin symbol_type_tag = CALLOC(sizeof(char *), nsyms);
38080c8de5b0SBaptiste Daroussin NO_SPACE(symbol_type_tag);
38090c8de5b0SBaptiste Daroussin }
38100c8de5b0SBaptiste Daroussin #endif
38110c8de5b0SBaptiste Daroussin
38123e066022SBaptiste Daroussin v = TMALLOC(bucket *, nsyms);
381398e903e7SBaptiste Daroussin NO_SPACE(v);
381498e903e7SBaptiste Daroussin
381598e903e7SBaptiste Daroussin v[0] = 0;
381698e903e7SBaptiste Daroussin v[start_symbol] = 0;
381798e903e7SBaptiste Daroussin
381898e903e7SBaptiste Daroussin i = 1;
381998e903e7SBaptiste Daroussin j = (Value_t)(start_symbol + 1);
382098e903e7SBaptiste Daroussin for (bp = first_symbol; bp; bp = bp->next)
382198e903e7SBaptiste Daroussin {
382298e903e7SBaptiste Daroussin if (bp->class == TERM)
382398e903e7SBaptiste Daroussin v[i++] = bp;
382498e903e7SBaptiste Daroussin else
382598e903e7SBaptiste Daroussin v[j++] = bp;
382698e903e7SBaptiste Daroussin }
382798e903e7SBaptiste Daroussin assert(i == ntokens && j == nsyms);
382898e903e7SBaptiste Daroussin
382998e903e7SBaptiste Daroussin for (i = 1; i < ntokens; ++i)
383098e903e7SBaptiste Daroussin v[i]->index = i;
383198e903e7SBaptiste Daroussin
383298e903e7SBaptiste Daroussin goal->index = (Index_t)(start_symbol + 1);
383398e903e7SBaptiste Daroussin k = (Value_t)(start_symbol + 2);
383498e903e7SBaptiste Daroussin while (++i < nsyms)
383598e903e7SBaptiste Daroussin if (v[i] != goal)
383698e903e7SBaptiste Daroussin {
383798e903e7SBaptiste Daroussin v[i]->index = k;
383898e903e7SBaptiste Daroussin ++k;
383998e903e7SBaptiste Daroussin }
384098e903e7SBaptiste Daroussin
384198e903e7SBaptiste Daroussin goal->value = 0;
384298e903e7SBaptiste Daroussin k = 1;
384398e903e7SBaptiste Daroussin for (i = (Value_t)(start_symbol + 1); i < nsyms; ++i)
384498e903e7SBaptiste Daroussin {
384598e903e7SBaptiste Daroussin if (v[i] != goal)
384698e903e7SBaptiste Daroussin {
384798e903e7SBaptiste Daroussin v[i]->value = k;
384898e903e7SBaptiste Daroussin ++k;
384998e903e7SBaptiste Daroussin }
385098e903e7SBaptiste Daroussin }
385198e903e7SBaptiste Daroussin
385298e903e7SBaptiste Daroussin k = 0;
385398e903e7SBaptiste Daroussin for (i = 1; i < ntokens; ++i)
385498e903e7SBaptiste Daroussin {
385598e903e7SBaptiste Daroussin n = v[i]->value;
385698e903e7SBaptiste Daroussin if (n > 256)
385798e903e7SBaptiste Daroussin {
385898e903e7SBaptiste Daroussin for (j = k++; j > 0 && symbol_value[j - 1] > n; --j)
385998e903e7SBaptiste Daroussin symbol_value[j] = symbol_value[j - 1];
386098e903e7SBaptiste Daroussin symbol_value[j] = n;
386198e903e7SBaptiste Daroussin }
386298e903e7SBaptiste Daroussin }
386398e903e7SBaptiste Daroussin
386498e903e7SBaptiste Daroussin assert(v[1] != 0);
386598e903e7SBaptiste Daroussin
386698e903e7SBaptiste Daroussin if (v[1]->value == UNDEFINED)
386798e903e7SBaptiste Daroussin v[1]->value = 256;
386898e903e7SBaptiste Daroussin
386998e903e7SBaptiste Daroussin j = 0;
387098e903e7SBaptiste Daroussin n = 257;
387198e903e7SBaptiste Daroussin for (i = 2; i < ntokens; ++i)
387298e903e7SBaptiste Daroussin {
387398e903e7SBaptiste Daroussin if (v[i]->value == UNDEFINED)
387498e903e7SBaptiste Daroussin {
387598e903e7SBaptiste Daroussin while (j < k && n == symbol_value[j])
387698e903e7SBaptiste Daroussin {
387798e903e7SBaptiste Daroussin while (++j < k && n == symbol_value[j])
387898e903e7SBaptiste Daroussin continue;
387998e903e7SBaptiste Daroussin ++n;
388098e903e7SBaptiste Daroussin }
388198e903e7SBaptiste Daroussin v[i]->value = n;
388298e903e7SBaptiste Daroussin ++n;
388398e903e7SBaptiste Daroussin }
388498e903e7SBaptiste Daroussin }
388598e903e7SBaptiste Daroussin
388698e903e7SBaptiste Daroussin symbol_name[0] = name_pool + 8;
388798e903e7SBaptiste Daroussin symbol_value[0] = 0;
388898e903e7SBaptiste Daroussin symbol_prec[0] = 0;
388998e903e7SBaptiste Daroussin symbol_assoc[0] = TOKEN;
38900c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
38910c8de5b0SBaptiste Daroussin symbol_pval[0] = 0;
38920c8de5b0SBaptiste Daroussin max_tok_pval = 0;
38930c8de5b0SBaptiste Daroussin #endif
389498e903e7SBaptiste Daroussin for (i = 1; i < ntokens; ++i)
389598e903e7SBaptiste Daroussin {
389698e903e7SBaptiste Daroussin symbol_name[i] = v[i]->name;
389798e903e7SBaptiste Daroussin symbol_value[i] = v[i]->value;
389898e903e7SBaptiste Daroussin symbol_prec[i] = v[i]->prec;
389998e903e7SBaptiste Daroussin symbol_assoc[i] = v[i]->assoc;
39000c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
39010c8de5b0SBaptiste Daroussin symbol_pval[i] = v[i]->value;
39020c8de5b0SBaptiste Daroussin if (symbol_pval[i] > max_tok_pval)
39030c8de5b0SBaptiste Daroussin max_tok_pval = symbol_pval[i];
39040c8de5b0SBaptiste Daroussin if (destructor)
39050c8de5b0SBaptiste Daroussin {
39060c8de5b0SBaptiste Daroussin symbol_destructor[i] = v[i]->destructor;
39070c8de5b0SBaptiste Daroussin symbol_type_tag[i] = v[i]->tag;
39080c8de5b0SBaptiste Daroussin }
39090c8de5b0SBaptiste Daroussin #endif
391098e903e7SBaptiste Daroussin }
391198e903e7SBaptiste Daroussin symbol_name[start_symbol] = name_pool;
391298e903e7SBaptiste Daroussin symbol_value[start_symbol] = -1;
391398e903e7SBaptiste Daroussin symbol_prec[start_symbol] = 0;
391498e903e7SBaptiste Daroussin symbol_assoc[start_symbol] = TOKEN;
39150c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
39160c8de5b0SBaptiste Daroussin symbol_pval[start_symbol] = (Value_t)(max_tok_pval + 1);
39170c8de5b0SBaptiste Daroussin #endif
391898e903e7SBaptiste Daroussin for (++i; i < nsyms; ++i)
391998e903e7SBaptiste Daroussin {
392098e903e7SBaptiste Daroussin k = v[i]->index;
392198e903e7SBaptiste Daroussin symbol_name[k] = v[i]->name;
392298e903e7SBaptiste Daroussin symbol_value[k] = v[i]->value;
392398e903e7SBaptiste Daroussin symbol_prec[k] = v[i]->prec;
392498e903e7SBaptiste Daroussin symbol_assoc[k] = v[i]->assoc;
39250c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
39260c8de5b0SBaptiste Daroussin symbol_pval[k] = (Value_t)((max_tok_pval + 1) + v[i]->value + 1);
39270c8de5b0SBaptiste Daroussin if (destructor)
39280c8de5b0SBaptiste Daroussin {
39290c8de5b0SBaptiste Daroussin symbol_destructor[k] = v[i]->destructor;
39300c8de5b0SBaptiste Daroussin symbol_type_tag[k] = v[i]->tag;
39310c8de5b0SBaptiste Daroussin }
39320c8de5b0SBaptiste Daroussin #endif
393398e903e7SBaptiste Daroussin }
393498e903e7SBaptiste Daroussin
393598e903e7SBaptiste Daroussin if (gflag)
393698e903e7SBaptiste Daroussin {
39373e066022SBaptiste Daroussin symbol_pname = TMALLOC(char *, nsyms);
393898e903e7SBaptiste Daroussin NO_SPACE(symbol_pname);
393998e903e7SBaptiste Daroussin
394098e903e7SBaptiste Daroussin for (i = 0; i < nsyms; ++i)
394198e903e7SBaptiste Daroussin protect_string(symbol_name[i], &(symbol_pname[i]));
394298e903e7SBaptiste Daroussin }
394398e903e7SBaptiste Daroussin
394498e903e7SBaptiste Daroussin FREE(v);
394598e903e7SBaptiste Daroussin }
394698e903e7SBaptiste Daroussin
394798e903e7SBaptiste Daroussin static void
pack_grammar(void)394898e903e7SBaptiste Daroussin pack_grammar(void)
394998e903e7SBaptiste Daroussin {
395098e903e7SBaptiste Daroussin int i;
395198e903e7SBaptiste Daroussin Value_t j;
395298e903e7SBaptiste Daroussin
39533e066022SBaptiste Daroussin ritem = TMALLOC(Value_t, nitems);
395498e903e7SBaptiste Daroussin NO_SPACE(ritem);
395598e903e7SBaptiste Daroussin
39563e066022SBaptiste Daroussin rlhs = TMALLOC(Value_t, nrules);
395798e903e7SBaptiste Daroussin NO_SPACE(rlhs);
395898e903e7SBaptiste Daroussin
39593e066022SBaptiste Daroussin rrhs = TMALLOC(Value_t, nrules + 1);
396098e903e7SBaptiste Daroussin NO_SPACE(rrhs);
396198e903e7SBaptiste Daroussin
39623e066022SBaptiste Daroussin rprec = TREALLOC(Value_t, rprec, nrules);
396398e903e7SBaptiste Daroussin NO_SPACE(rprec);
396498e903e7SBaptiste Daroussin
39653e066022SBaptiste Daroussin rassoc = TREALLOC(Assoc_t, rassoc, nrules);
396698e903e7SBaptiste Daroussin NO_SPACE(rassoc);
396798e903e7SBaptiste Daroussin
396898e903e7SBaptiste Daroussin ritem[0] = -1;
396998e903e7SBaptiste Daroussin ritem[1] = goal->index;
397098e903e7SBaptiste Daroussin ritem[2] = 0;
397198e903e7SBaptiste Daroussin ritem[3] = -2;
397298e903e7SBaptiste Daroussin rlhs[0] = 0;
397398e903e7SBaptiste Daroussin rlhs[1] = 0;
397498e903e7SBaptiste Daroussin rlhs[2] = start_symbol;
397598e903e7SBaptiste Daroussin rrhs[0] = 0;
397698e903e7SBaptiste Daroussin rrhs[1] = 0;
397798e903e7SBaptiste Daroussin rrhs[2] = 1;
397898e903e7SBaptiste Daroussin
397998e903e7SBaptiste Daroussin j = 4;
398098e903e7SBaptiste Daroussin for (i = 3; i < nrules; ++i)
398198e903e7SBaptiste Daroussin {
39828e022d3cSDag-Erling Smørgrav Assoc_t assoc;
39838e022d3cSDag-Erling Smørgrav Value_t prec2;
39848e022d3cSDag-Erling Smørgrav
39850c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
39860c8de5b0SBaptiste Daroussin if (plhs[i]->args > 0)
39870c8de5b0SBaptiste Daroussin {
39880c8de5b0SBaptiste Daroussin if (plhs[i]->argnames)
39890c8de5b0SBaptiste Daroussin {
39900c8de5b0SBaptiste Daroussin FREE(plhs[i]->argnames);
39910c8de5b0SBaptiste Daroussin plhs[i]->argnames = NULL;
39920c8de5b0SBaptiste Daroussin }
39930c8de5b0SBaptiste Daroussin if (plhs[i]->argtags)
39940c8de5b0SBaptiste Daroussin {
39950c8de5b0SBaptiste Daroussin FREE(plhs[i]->argtags);
39960c8de5b0SBaptiste Daroussin plhs[i]->argtags = NULL;
39970c8de5b0SBaptiste Daroussin }
39980c8de5b0SBaptiste Daroussin }
39990c8de5b0SBaptiste Daroussin #endif /* defined(YYBTYACC) */
400098e903e7SBaptiste Daroussin rlhs[i] = plhs[i]->index;
400198e903e7SBaptiste Daroussin rrhs[i] = j;
400298e903e7SBaptiste Daroussin assoc = TOKEN;
400398e903e7SBaptiste Daroussin prec2 = 0;
400498e903e7SBaptiste Daroussin while (pitem[j])
400598e903e7SBaptiste Daroussin {
400698e903e7SBaptiste Daroussin ritem[j] = pitem[j]->index;
400798e903e7SBaptiste Daroussin if (pitem[j]->class == TERM)
400898e903e7SBaptiste Daroussin {
400998e903e7SBaptiste Daroussin prec2 = pitem[j]->prec;
401098e903e7SBaptiste Daroussin assoc = pitem[j]->assoc;
401198e903e7SBaptiste Daroussin }
401298e903e7SBaptiste Daroussin ++j;
401398e903e7SBaptiste Daroussin }
401498e903e7SBaptiste Daroussin ritem[j] = (Value_t)-i;
401598e903e7SBaptiste Daroussin ++j;
401698e903e7SBaptiste Daroussin if (rprec[i] == UNDEFINED)
401798e903e7SBaptiste Daroussin {
401898e903e7SBaptiste Daroussin rprec[i] = prec2;
401998e903e7SBaptiste Daroussin rassoc[i] = assoc;
402098e903e7SBaptiste Daroussin }
402198e903e7SBaptiste Daroussin }
402298e903e7SBaptiste Daroussin rrhs[i] = j;
402398e903e7SBaptiste Daroussin
402498e903e7SBaptiste Daroussin FREE(plhs);
402598e903e7SBaptiste Daroussin FREE(pitem);
40260c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
40270c8de5b0SBaptiste Daroussin clean_arg_cache();
40280c8de5b0SBaptiste Daroussin #endif
402998e903e7SBaptiste Daroussin }
403098e903e7SBaptiste Daroussin
403198e903e7SBaptiste Daroussin static void
print_grammar(void)403298e903e7SBaptiste Daroussin print_grammar(void)
403398e903e7SBaptiste Daroussin {
403498e903e7SBaptiste Daroussin int i, k;
403598e903e7SBaptiste Daroussin size_t j, spacing = 0;
403698e903e7SBaptiste Daroussin FILE *f = verbose_file;
403798e903e7SBaptiste Daroussin
403898e903e7SBaptiste Daroussin if (!vflag)
403998e903e7SBaptiste Daroussin return;
404098e903e7SBaptiste Daroussin
404198e903e7SBaptiste Daroussin k = 1;
404298e903e7SBaptiste Daroussin for (i = 2; i < nrules; ++i)
404398e903e7SBaptiste Daroussin {
404498e903e7SBaptiste Daroussin if (rlhs[i] != rlhs[i - 1])
404598e903e7SBaptiste Daroussin {
404698e903e7SBaptiste Daroussin if (i != 2)
404798e903e7SBaptiste Daroussin fprintf(f, "\n");
404898e903e7SBaptiste Daroussin fprintf(f, "%4d %s :", i - 2, symbol_name[rlhs[i]]);
404998e903e7SBaptiste Daroussin spacing = strlen(symbol_name[rlhs[i]]) + 1;
405098e903e7SBaptiste Daroussin }
405198e903e7SBaptiste Daroussin else
405298e903e7SBaptiste Daroussin {
405398e903e7SBaptiste Daroussin fprintf(f, "%4d ", i - 2);
405498e903e7SBaptiste Daroussin j = spacing;
405598e903e7SBaptiste Daroussin while (j-- != 0)
405698e903e7SBaptiste Daroussin putc(' ', f);
405798e903e7SBaptiste Daroussin putc('|', f);
405898e903e7SBaptiste Daroussin }
405998e903e7SBaptiste Daroussin
406098e903e7SBaptiste Daroussin while (ritem[k] >= 0)
406198e903e7SBaptiste Daroussin {
406298e903e7SBaptiste Daroussin fprintf(f, " %s", symbol_name[ritem[k]]);
406398e903e7SBaptiste Daroussin ++k;
406498e903e7SBaptiste Daroussin }
406598e903e7SBaptiste Daroussin ++k;
406698e903e7SBaptiste Daroussin putc('\n', f);
406798e903e7SBaptiste Daroussin }
406898e903e7SBaptiste Daroussin }
406998e903e7SBaptiste Daroussin
40700c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
40710c8de5b0SBaptiste Daroussin static void
finalize_destructors(void)40720c8de5b0SBaptiste Daroussin finalize_destructors(void)
40730c8de5b0SBaptiste Daroussin {
40740c8de5b0SBaptiste Daroussin int i;
40750c8de5b0SBaptiste Daroussin bucket *bp;
40760c8de5b0SBaptiste Daroussin
40770c8de5b0SBaptiste Daroussin for (i = 2; i < nsyms; ++i)
40780c8de5b0SBaptiste Daroussin {
40798e022d3cSDag-Erling Smørgrav char *tag = symbol_type_tag[i];
40808e022d3cSDag-Erling Smørgrav
40810c8de5b0SBaptiste Daroussin if (symbol_destructor[i] == NULL)
40820c8de5b0SBaptiste Daroussin {
40830c8de5b0SBaptiste Daroussin if (tag == NULL)
40840c8de5b0SBaptiste Daroussin { /* use <> destructor, if there is one */
40850c8de5b0SBaptiste Daroussin if ((bp = default_destructor[UNTYPED_DEFAULT]) != NULL)
40860c8de5b0SBaptiste Daroussin {
40870c8de5b0SBaptiste Daroussin symbol_destructor[i] = TMALLOC(char,
40880c8de5b0SBaptiste Daroussin strlen(bp->destructor) + 1);
40890c8de5b0SBaptiste Daroussin NO_SPACE(symbol_destructor[i]);
40900c8de5b0SBaptiste Daroussin strcpy(symbol_destructor[i], bp->destructor);
40910c8de5b0SBaptiste Daroussin }
40920c8de5b0SBaptiste Daroussin }
40930c8de5b0SBaptiste Daroussin else
40940c8de5b0SBaptiste Daroussin { /* use type destructor for this tag, if there is one */
40950c8de5b0SBaptiste Daroussin bp = lookup_type_destructor(tag);
40960c8de5b0SBaptiste Daroussin if (bp->destructor != NULL)
40970c8de5b0SBaptiste Daroussin {
40980c8de5b0SBaptiste Daroussin symbol_destructor[i] = TMALLOC(char,
40990c8de5b0SBaptiste Daroussin strlen(bp->destructor) + 1);
41000c8de5b0SBaptiste Daroussin NO_SPACE(symbol_destructor[i]);
41010c8de5b0SBaptiste Daroussin strcpy(symbol_destructor[i], bp->destructor);
41020c8de5b0SBaptiste Daroussin }
41030c8de5b0SBaptiste Daroussin else
41040c8de5b0SBaptiste Daroussin { /* use <*> destructor, if there is one */
41050c8de5b0SBaptiste Daroussin if ((bp = default_destructor[TYPED_DEFAULT]) != NULL)
41060c8de5b0SBaptiste Daroussin /* replace "$$" with "(*val).tag" in destructor code */
41070c8de5b0SBaptiste Daroussin symbol_destructor[i]
41080c8de5b0SBaptiste Daroussin = process_destructor_XX(bp->destructor, tag);
41090c8de5b0SBaptiste Daroussin }
41100c8de5b0SBaptiste Daroussin }
41110c8de5b0SBaptiste Daroussin }
41120c8de5b0SBaptiste Daroussin else
41130c8de5b0SBaptiste Daroussin { /* replace "$$" with "(*val)[.tag]" in destructor code */
41148e022d3cSDag-Erling Smørgrav char *destructor_source = symbol_destructor[i];
41150c8de5b0SBaptiste Daroussin symbol_destructor[i]
41168e022d3cSDag-Erling Smørgrav = process_destructor_XX(destructor_source, tag);
41178e022d3cSDag-Erling Smørgrav FREE(destructor_source);
41180c8de5b0SBaptiste Daroussin }
41190c8de5b0SBaptiste Daroussin }
41200c8de5b0SBaptiste Daroussin /* 'symbol_type_tag[]' elements are freed by 'free_tags()' */
41210c8de5b0SBaptiste Daroussin DO_FREE(symbol_type_tag); /* no longer needed */
41220c8de5b0SBaptiste Daroussin if ((bp = default_destructor[UNTYPED_DEFAULT]) != NULL)
41230c8de5b0SBaptiste Daroussin {
41240c8de5b0SBaptiste Daroussin FREE(bp->name);
41250c8de5b0SBaptiste Daroussin /* 'bp->tag' is a static value, don't free */
41260c8de5b0SBaptiste Daroussin FREE(bp->destructor);
41270c8de5b0SBaptiste Daroussin FREE(bp);
41280c8de5b0SBaptiste Daroussin }
41290c8de5b0SBaptiste Daroussin if ((bp = default_destructor[TYPED_DEFAULT]) != NULL)
41300c8de5b0SBaptiste Daroussin {
41310c8de5b0SBaptiste Daroussin FREE(bp->name);
41320c8de5b0SBaptiste Daroussin /* 'bp->tag' is a static value, don't free */
41330c8de5b0SBaptiste Daroussin FREE(bp->destructor);
41340c8de5b0SBaptiste Daroussin FREE(bp);
41350c8de5b0SBaptiste Daroussin }
41360c8de5b0SBaptiste Daroussin if ((bp = default_destructor[TYPE_SPECIFIED]) != NULL)
41370c8de5b0SBaptiste Daroussin {
41380c8de5b0SBaptiste Daroussin bucket *p;
41390c8de5b0SBaptiste Daroussin for (; bp; bp = p)
41400c8de5b0SBaptiste Daroussin {
41410c8de5b0SBaptiste Daroussin p = bp->link;
41420c8de5b0SBaptiste Daroussin FREE(bp->name);
41430c8de5b0SBaptiste Daroussin /* 'bp->tag' freed by 'free_tags()' */
41440c8de5b0SBaptiste Daroussin FREE(bp->destructor);
41450c8de5b0SBaptiste Daroussin FREE(bp);
41460c8de5b0SBaptiste Daroussin }
41470c8de5b0SBaptiste Daroussin }
41480c8de5b0SBaptiste Daroussin }
41490c8de5b0SBaptiste Daroussin #endif /* defined(YYBTYACC) */
41500c8de5b0SBaptiste Daroussin
415198e903e7SBaptiste Daroussin void
reader(void)415298e903e7SBaptiste Daroussin reader(void)
415398e903e7SBaptiste Daroussin {
415498e903e7SBaptiste Daroussin write_section(code_file, banner);
415598e903e7SBaptiste Daroussin create_symbol_table();
415698e903e7SBaptiste Daroussin read_declarations();
415798e903e7SBaptiste Daroussin read_grammar();
415898e903e7SBaptiste Daroussin free_symbol_table();
415998e903e7SBaptiste Daroussin pack_names();
416098e903e7SBaptiste Daroussin check_symbols();
416198e903e7SBaptiste Daroussin pack_symbols();
416298e903e7SBaptiste Daroussin pack_grammar();
416398e903e7SBaptiste Daroussin free_symbols();
416498e903e7SBaptiste Daroussin print_grammar();
41650c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
41660c8de5b0SBaptiste Daroussin if (destructor)
41670c8de5b0SBaptiste Daroussin finalize_destructors();
41680c8de5b0SBaptiste Daroussin #endif
41690c8de5b0SBaptiste Daroussin free_tags();
417098e903e7SBaptiste Daroussin }
417198e903e7SBaptiste Daroussin
417298e903e7SBaptiste Daroussin #ifdef NO_LEAKS
417398e903e7SBaptiste Daroussin static param *
free_declarations(param * list)417498e903e7SBaptiste Daroussin free_declarations(param *list)
417598e903e7SBaptiste Daroussin {
417698e903e7SBaptiste Daroussin while (list != 0)
417798e903e7SBaptiste Daroussin {
417898e903e7SBaptiste Daroussin param *next = list->next;
417998e903e7SBaptiste Daroussin free(list->type);
418098e903e7SBaptiste Daroussin free(list->name);
418198e903e7SBaptiste Daroussin free(list->type2);
418298e903e7SBaptiste Daroussin free(list);
418398e903e7SBaptiste Daroussin list = next;
418498e903e7SBaptiste Daroussin }
418598e903e7SBaptiste Daroussin return list;
418698e903e7SBaptiste Daroussin }
418798e903e7SBaptiste Daroussin
418898e903e7SBaptiste Daroussin void
reader_leaks(void)418998e903e7SBaptiste Daroussin reader_leaks(void)
419098e903e7SBaptiste Daroussin {
419198e903e7SBaptiste Daroussin lex_param = free_declarations(lex_param);
419298e903e7SBaptiste Daroussin parse_param = free_declarations(parse_param);
419398e903e7SBaptiste Daroussin
419498e903e7SBaptiste Daroussin DO_FREE(line);
419598e903e7SBaptiste Daroussin DO_FREE(rrhs);
419698e903e7SBaptiste Daroussin DO_FREE(rlhs);
419798e903e7SBaptiste Daroussin DO_FREE(rprec);
419898e903e7SBaptiste Daroussin DO_FREE(ritem);
419998e903e7SBaptiste Daroussin DO_FREE(rassoc);
420098e903e7SBaptiste Daroussin DO_FREE(cache);
420198e903e7SBaptiste Daroussin DO_FREE(name_pool);
420298e903e7SBaptiste Daroussin DO_FREE(symbol_name);
420398e903e7SBaptiste Daroussin DO_FREE(symbol_prec);
420498e903e7SBaptiste Daroussin DO_FREE(symbol_assoc);
420598e903e7SBaptiste Daroussin DO_FREE(symbol_value);
42060c8de5b0SBaptiste Daroussin #if defined(YYBTYACC)
42070c8de5b0SBaptiste Daroussin DO_FREE(symbol_pval);
42080c8de5b0SBaptiste Daroussin DO_FREE(symbol_destructor);
42090c8de5b0SBaptiste Daroussin DO_FREE(symbol_type_tag);
42100c8de5b0SBaptiste Daroussin #endif
421198e903e7SBaptiste Daroussin }
421298e903e7SBaptiste Daroussin #endif
4213