Initial check-in introducing experimental GLR parsing. See entry in

ChangeLog dated 2002-06-27 from Paul Hilfinger for details.
This commit is contained in:
Paul Hilfinger
2002-06-28 02:26:44 +00:00
parent 01241d47b4
commit 676385e29c
31 changed files with 2422 additions and 1299 deletions

View File

@@ -331,12 +331,15 @@ count_sr_conflicts (state_t *state)
}
/*----------------------------------------------.
| Count the number of reduce/reduce conflicts. |
`----------------------------------------------*/
/*----------------------------------------------------------------.
| Count the number of reduce/reduce conflicts. If ONE_PER_TOKEN, |
| count one conflict for each token that has any reduce/reduce |
| conflicts. Otherwise, count one conflict for each pair of |
| conflicting reductions. |
+`----------------------------------------------------------------*/
static int
count_rr_conflicts (state_t *state)
count_rr_conflicts (state_t *state, int one_per_token)
{
int i;
int rrc_count = 0;
@@ -353,7 +356,7 @@ count_rr_conflicts (state_t *state)
count++;
if (count >= 2)
rrc_count++;
rrc_count += one_per_token ? 1 : count-1;
}
return rrc_count;
@@ -412,13 +415,37 @@ conflicts_output (FILE *out)
{
fprintf (out, _("State %d contains "), i);
fputs (conflict_report (count_sr_conflicts (states[i]),
count_rr_conflicts (states[i])), out);
count_rr_conflicts (states[i], TRUE)), out);
printed_sth = TRUE;
}
if (printed_sth)
fputs ("\n\n", out);
}
/*--------------------------------------------------------.
| Total the number of S/R and R/R conflicts. Unlike the |
| code in conflicts_output, however, count EACH pair of |
| reductions for the same state and lookahead as one |
| conflict. |
`--------------------------------------------------------*/
int
conflicts_total_count (void)
{
int i;
int count;
/* Conflicts by state. */
count = 0;
for (i = 0; i < nstates; i++)
if (conflicts[i])
{
count += count_sr_conflicts (states[i]);
count += count_rr_conflicts (states[i], FALSE);
}
return count;
}
/*------------------------------------------.
| Reporting the total number of conflicts. |
@@ -442,7 +469,7 @@ conflicts_print (void)
if (conflicts[i])
{
src_total += count_sr_conflicts (states[i]);
rrc_total += count_rr_conflicts (states[i]);
rrc_total += count_rr_conflicts (states[i], TRUE);
}
src_ok = src_total == (expected_conflicts == -1 ? 0 : expected_conflicts);

View File

@@ -24,6 +24,7 @@
void conflicts_solve PARAMS ((void));
void conflicts_print PARAMS ((void));
int conflicts_total_count PARAMS ((void));
void conflicts_output PARAMS ((FILE *out));
void conflicts_free PARAMS ((void));

View File

@@ -43,6 +43,7 @@ symbol_number_t *token_translations = NULL;
int max_user_token_number = 256;
int glr_parser = 0;
int pure_parser = 0;
@@ -249,4 +250,5 @@ grammar_free (void)
XFREE (token_translations);
/* Free the symbol table data structure. */
symbols_free ();
free_merger_functions ();
}

View File

@@ -68,6 +68,10 @@
RULES[R].assoc -- the associativity of R.
RULES[R].dprec -- the dynamic precedence level of R (for GLR parsing).
RULES[R].merger -- index of merging function for R (for GLR parsing).
RULES[R].line -- the line where R was defined.
RULES[R].useful -- TRUE iff the rule is used (i.e., FALSE if thrown
@@ -141,6 +145,9 @@ typedef struct rule_s
/* This symbol provides both the associativity, and the precedence. */
symbol_t *prec;
short dprec;
short merger;
/* This symbol was attached to the rule via %prec. */
symbol_t *precsym;
@@ -163,6 +170,12 @@ extern symbol_number_t *token_translations;
extern int max_user_token_number;
/* GLR_PARSER is nonzero if the input file says to use the GLR
(Generalized LR) parser, and to output some additional
information used by the GLR algorithm. */
extern int glr_parser;
/* PURE_PARSER is nonzero if should generate a parser that is all pure
and reentrant. */

View File

@@ -115,14 +115,21 @@ static int nvectors;
static int nentries;
static short **froms = NULL;
static short **tos = NULL;
static unsigned int **conflict_tos = NULL;
static short *tally = NULL;
static short *width = NULL;
static short *actrow = NULL;
static short *conflrow = NULL;
static short *state_count = NULL;
static short *order = NULL;
static short *base = NULL;
static short *pos = NULL;
static unsigned int *conflict_table = NULL;
static unsigned int *conflict_list = NULL;
static int conflict_list_cnt;
static int conflict_list_free;
/* TABLE_SIZE is the allocated size of both TABLE and CHECK.
We start with the original hard-coded value: SHRT_MAX
(yes, not USHRT_MAX). */
@@ -157,6 +164,8 @@ table_grow (size_t desired)
table = XREALLOC (table, short, table_size);
check = XREALLOC (check, short, table_size);
if (glr_parser)
conflict_table = XREALLOC (conflict_table, unsigned int, table_size);
for (/* Nothing. */; old_size < table_size; ++old_size)
{
@@ -278,7 +287,7 @@ prepare_tokens (void)
/*-------------------------------------------------------------.
| Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
| rline. |
| rline, dprec, merger |
`-------------------------------------------------------------*/
static void
@@ -291,6 +300,8 @@ prepare_rules (void)
unsigned int *rline = XMALLOC (unsigned int, nrules + 1);
symbol_number_t *r1 = XMALLOC (symbol_number_t, nrules + 1);
unsigned int *r2 = XMALLOC (unsigned int, nrules + 1);
short *dprec = XMALLOC (short, nrules + 1);
short *merger = XMALLOC (short, nrules + 1);
for (r = 1; r < nrules + 1; ++r)
{
@@ -308,6 +319,10 @@ prepare_rules (void)
rhs[i++] = -1;
/* Line where rule was defined. */
rline[r] = rules[r].location.first_line;
/* Dynamic precedence (GLR) */
dprec[r] = rules[r].dprec;
/* Merger-function index (GLR) */
merger[r] = rules[r].merger;
}
assert (i == nritems);
@@ -316,12 +331,16 @@ prepare_rules (void)
muscle_insert_unsigned_int_table ("rline", rline, 0, 1, nrules + 1);
muscle_insert_symbol_number_table ("r1", r1, 0, 1, nrules + 1);
muscle_insert_unsigned_int_table ("r2", r2, 0, 1, nrules + 1);
muscle_insert_short_table ("dprec", dprec, 0, 1, nrules + 1);
muscle_insert_short_table ("merger", merger, 0, 1, nrules + 1);
free (rhs);
free (prhs);
free (rline);
free (r1);
free (r2);
free (dprec);
free (merger);
}
/*--------------------------------------------.
@@ -341,6 +360,50 @@ prepare_states (void)
}
/*-------------------------------------------------------------------.
| For GLR parsers, for each conflicted token in STATE, as indicated |
| by non-zero entries in conflrow, create a list of possible |
| reductions that are alternatives to the shift or reduction |
| currently recorded for that token in STATE. Store the alternative |
| reductions followed by a 0 in conflict_list, updating |
| conflict_list_cnt, and storing an index to the start of the list |
| back into conflrow. |
`-------------------------------------------------------------------*/
static void
conflict_row (state_t *state)
{
int i, j;
if (! glr_parser)
return;
for (j = 0; j < ntokens; j += 1)
if (conflrow[j])
{
conflrow[j] = conflict_list_cnt;
/* find all reductions for token j, and record all that do
* not match actrow[j] */
for (i = 0; i < state->nlookaheads; i += 1)
if (bitset_test (state->lookaheads[i], j)
&& actrow[j] != -state->lookaheads_rule[i]->number)
{
assert (conflict_list_free > 0);
conflict_list[conflict_list_cnt]
= state->lookaheads_rule[i]->number;
conflict_list_cnt += 1;
conflict_list_free -= 1;
}
/* Leave a 0 at the end */
assert (conflict_list_free > 0);
conflict_list_cnt += 1;
conflict_list_free -= 1;
}
}
/*------------------------------------------------------------------.
| Decide what to do for each type of token if seen as the lookahead |
| token in specified state. The value returned is used as the |
@@ -353,6 +416,11 @@ prepare_states (void)
| This is where conflicts are resolved. The loop over lookahead |
| rules considered lower-numbered rules last, and the last rule |
| considered that likes a token gets to handle it. |
| |
| For GLR parsers, also sets conflrow[SYM] to an index into |
| conflict_list iff there is an unresolved conflict (s/r or r/r) |
| with symbol SYM. The default reduction is not used for a symbol |
| that has any such conflicts. |
`------------------------------------------------------------------*/
static int
@@ -365,9 +433,10 @@ action_row (state_t *state)
errs *errp = state->errs;
/* set nonzero to inhibit having any default reduction */
int nodefault = 0;
int conflicted = 0;
for (i = 0; i < ntokens; i++)
actrow[i] = 0;
actrow[i] = conflrow[i] = 0;
if (redp->nreds >= 1)
{
@@ -381,7 +450,11 @@ action_row (state_t *state)
/* and record this rule as the rule to use if that
token follows. */
if (bitset_test (state->lookaheads[i], j))
actrow[j] = -state->lookaheads_rule[i]->number;
{
if (actrow[j] != 0)
conflicted = conflrow[j] = 1;
actrow[j] = -state->lookaheads_rule[i]->number;
}
}
/* Now see which tokens are allowed for shifts in this state. For
@@ -399,6 +472,8 @@ action_row (state_t *state)
if (ISVAR (symbol))
break;
if (actrow[symbol] != 0)
conflicted = conflrow[symbol] = 1;
actrow[symbol] = shift_state;
/* Do not use any default reduction if there is a shift for
@@ -442,18 +517,20 @@ action_row (state_t *state)
}
}
/* actions which match the default are replaced with zero,
which means "use the default" */
/* GLR parsers need space for conflict lists, so we can't
default conflicted entries. For non-conflicted entries
or as long as we are not building a GLR parser,
actions that match the default are replaced with zero,
which means "use the default". */
if (max > 0)
{
int j;
for (j = 0; j < ntokens; j++)
if (actrow[j] == default_rule)
if (actrow[j] == default_rule && ! (glr_parser && conflrow[j]))
actrow[j] = 0;
default_rule = -default_rule;
}
default_rule = -default_rule;
}
}
@@ -465,6 +542,9 @@ action_row (state_t *state)
if (actrow[i] == SHRT_MIN)
actrow[i] = 0;
if (conflicted)
conflict_row (state);
return default_rule;
}
@@ -477,6 +557,7 @@ save_row (int state)
short *sp;
short *sp1;
short *sp2;
unsigned int *sp3;
count = 0;
for (i = 0; i < ntokens; i++)
@@ -488,12 +569,18 @@ save_row (int state)
froms[state] = sp1 = sp = XCALLOC (short, count);
tos[state] = sp2 = XCALLOC (short, count);
if (glr_parser)
conflict_tos[state] = sp3 = XCALLOC (unsigned int, count);
else
conflict_tos[state] = NULL;
for (i = 0; i < ntokens; i++)
if (actrow[i] != 0)
{
*sp1++ = i;
*sp2++ = actrow[i];
if (glr_parser)
*sp3++ = conflrow[i];
}
tally[state] = count;
@@ -513,9 +600,22 @@ static void
token_actions (void)
{
size_t i;
int nconflict = conflicts_total_count ();
short *yydefact = XCALLOC (short, nstates);
actrow = XCALLOC (short, ntokens);
conflrow = XCALLOC (short, ntokens);
if (glr_parser)
{
conflict_list = XCALLOC (unsigned int, 1 + 2 * nconflict);
conflict_list_free = 2 * nconflict;
conflict_list_cnt = 1;
}
else
conflict_list_free = conflict_list_cnt = 0;
for (i = 0; i < nstates; ++i)
{
yydefact[i] = action_row (states[i]);
@@ -525,6 +625,7 @@ token_actions (void)
muscle_insert_short_table ("defact", yydefact,
yydefact[0], 1, nstates);
XFREE (actrow);
XFREE (conflrow);
XFREE (yydefact);
}
@@ -555,6 +656,28 @@ actions_output (FILE *out)
fputs ("]])\n\n", out);
}
/*--------------------------------------.
| Output the merge functions to OUT. |
`--------------------------------------*/
void
merger_output (FILE *out)
{
int n;
merger_list* p;
fputs ("m4_define([b4_mergers], \n[[", out);
for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
{
if (p->type[0] == '\0')
fprintf (out, " case %d: yyval = %s (*yy0, *yy1); break;\n",
n, p->name);
else
fprintf (out, " case %d: yyval.%s = %s (*yy0, *yy1); break;\n",
n, p->type, p->name);
}
fputs ("]])\n\n", out);
}
/*---------------------------------------.
| Output the tokens definition to OOUT. |
@@ -844,6 +967,7 @@ pack_vector (int vector)
int loc = 0;
short *from = froms[i];
short *to = tos[i];
unsigned int *conflict_to = conflict_tos[i];
assert (t);
@@ -872,6 +996,8 @@ pack_vector (int vector)
{
loc = j + from[k];
table[loc] = to[k];
if (glr_parser && conflict_to != NULL)
conflict_table[loc] = conflict_to[k];
check[loc] = from[k];
}
@@ -900,6 +1026,8 @@ pack_table (void)
base = XCALLOC (short, nvectors);
pos = XCALLOC (short, nentries);
table = XCALLOC (short, table_size);
if (glr_parser)
conflict_table = XCALLOC (unsigned int, table_size);
check = XCALLOC (short, table_size);
lowzero = 0;
@@ -928,14 +1056,16 @@ pack_table (void)
{
XFREE (froms[i]);
XFREE (tos[i]);
XFREE (conflict_tos[i]);
}
XFREE (froms);
XFREE (tos);
XFREE (conflict_tos);
XFREE (pos);
}
/* the following functions output yytable, yycheck
/* the following functions output yytable, yycheck, yyconflp, yyconfl,
and the vectors whose elements index the portion starts */
static void
@@ -961,6 +1091,28 @@ output_table (void)
}
static void
output_conflicts (void)
{
/* GLR parsing slightly modifies yytable and yycheck
(and thus yypact) so that in states with unresolved conflicts,
the default reduction is not used in the conflicted entries, so
that there is a place to put a conflict pointer. This means that
yyconflp and yyconfl are nonsense for a non-GLR parser, so we
avoid accidents by not writing them out in that case. */
if (! glr_parser)
return;
muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
conflict_table[0], 1, high+1);
muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
conflict_list[0], 1, conflict_list_cnt);
XFREE (conflict_table);
XFREE (conflict_list);
}
static void
output_check (void)
{
@@ -982,6 +1134,7 @@ output_actions (void)
froms = XCALLOC (short *, nvectors);
tos = XCALLOC (short *, nvectors);
conflict_tos = XCALLOC (unsigned int *, nvectors);
tally = XCALLOC (short, nvectors);
width = XCALLOC (short, nvectors);
@@ -999,6 +1152,7 @@ output_actions (void)
output_base ();
output_table ();
output_conflicts ();
output_check ();
@@ -1084,6 +1238,7 @@ output_skeleton (void)
fputs ("m4_init()\n", out);
actions_output (out);
merger_output (out);
token_definitions_output (out);
symbol_destructors_output (out);
symbol_printers_output (out);
@@ -1140,7 +1295,12 @@ prepare (void)
/* Find the right skeleton file. */
if (!skeleton)
skeleton = "yacc.c";
{
if (glr_parser)
skeleton = "glr.c";
else
skeleton = "yacc.c";
}
/* Parse the skeleton file and output the needed parsers. */
muscle_insert ("skeleton", skeleton);

File diff suppressed because it is too large Load Diff

View File

@@ -23,30 +23,33 @@
PERCENT_EXPECT = 270,
PERCENT_START = 271,
PERCENT_PREC = 272,
PERCENT_VERBOSE = 273,
PERCENT_ERROR_VERBOSE = 274,
PERCENT_OUTPUT = 275,
PERCENT_FILE_PREFIX = 276,
PERCENT_NAME_PREFIX = 277,
PERCENT_DEFINE = 278,
PERCENT_PURE_PARSER = 279,
PERCENT_DEFINES = 280,
PERCENT_YACC = 281,
PERCENT_DEBUG = 282,
PERCENT_LOCATIONS = 283,
PERCENT_NO_LINES = 284,
PERCENT_SKELETON = 285,
PERCENT_TOKEN_TABLE = 286,
TYPE = 287,
EQUAL = 288,
SEMICOLON = 289,
COLON = 290,
PIPE = 291,
ID = 292,
PERCENT_PERCENT = 293,
PROLOGUE = 294,
EPILOGUE = 295,
BRACED_CODE = 296
PERCENT_DPREC = 273,
PERCENT_MERGE = 274,
PERCENT_VERBOSE = 275,
PERCENT_ERROR_VERBOSE = 276,
PERCENT_OUTPUT = 277,
PERCENT_FILE_PREFIX = 278,
PERCENT_NAME_PREFIX = 279,
PERCENT_DEFINE = 280,
PERCENT_PURE_PARSER = 281,
PERCENT_GLR_PARSER = 282,
PERCENT_DEFINES = 283,
PERCENT_YACC = 284,
PERCENT_DEBUG = 285,
PERCENT_LOCATIONS = 286,
PERCENT_NO_LINES = 287,
PERCENT_SKELETON = 288,
PERCENT_TOKEN_TABLE = 289,
TYPE = 290,
EQUAL = 291,
SEMICOLON = 292,
COLON = 293,
PIPE = 294,
ID = 295,
PERCENT_PERCENT = 296,
PROLOGUE = 297,
EPILOGUE = 298,
BRACED_CODE = 299
};
# endif
/* POSIX requires `int' for tokens in interfaces. */
@@ -68,30 +71,33 @@
#define PERCENT_EXPECT 270
#define PERCENT_START 271
#define PERCENT_PREC 272
#define PERCENT_VERBOSE 273
#define PERCENT_ERROR_VERBOSE 274
#define PERCENT_OUTPUT 275
#define PERCENT_FILE_PREFIX 276
#define PERCENT_NAME_PREFIX 277
#define PERCENT_DEFINE 278
#define PERCENT_PURE_PARSER 279
#define PERCENT_DEFINES 280
#define PERCENT_YACC 281
#define PERCENT_DEBUG 282
#define PERCENT_LOCATIONS 283
#define PERCENT_NO_LINES 284
#define PERCENT_SKELETON 285
#define PERCENT_TOKEN_TABLE 286
#define TYPE 287
#define EQUAL 288
#define SEMICOLON 289
#define COLON 290
#define PIPE 291
#define ID 292
#define PERCENT_PERCENT 293
#define PROLOGUE 294
#define EPILOGUE 295
#define BRACED_CODE 296
#define PERCENT_DPREC 273
#define PERCENT_MERGE 274
#define PERCENT_VERBOSE 275
#define PERCENT_ERROR_VERBOSE 276
#define PERCENT_OUTPUT 277
#define PERCENT_FILE_PREFIX 278
#define PERCENT_NAME_PREFIX 279
#define PERCENT_DEFINE 280
#define PERCENT_PURE_PARSER 281
#define PERCENT_GLR_PARSER 282
#define PERCENT_DEFINES 283
#define PERCENT_YACC 284
#define PERCENT_DEBUG 285
#define PERCENT_LOCATIONS 286
#define PERCENT_NO_LINES 287
#define PERCENT_SKELETON 288
#define PERCENT_TOKEN_TABLE 289
#define TYPE 290
#define EQUAL 291
#define SEMICOLON 292
#define COLON 293
#define PIPE 294
#define ID 295
#define PERCENT_PERCENT 296
#define PROLOGUE 297
#define EPILOGUE 298
#define BRACED_CODE 299
@@ -105,8 +111,8 @@ typedef union {
char *string;
associativity assoc;
} yystype;
/* Line 1331 of /usr/local/share/bison/bison.simple. */
#line 110 "y.tab.h"
/* Line 1343 of /home/cs/hilfingr/work/grammars/glr2/install/share/bison/yacc.c. */
#line 116 "y.tab.h"
# define YYSTYPE yystype
#endif

View File

@@ -114,6 +114,8 @@ braced_code_t current_braced_code = action_braced_code;
%token PERCENT_EXPECT "%expect"
%token PERCENT_START "%start"
%token PERCENT_PREC "%prec"
%token PERCENT_DPREC "%dprec"
%token PERCENT_MERGE "%merge"
%token PERCENT_VERBOSE "%verbose"
%token PERCENT_ERROR_VERBOSE "%error-verbose"
@@ -123,6 +125,7 @@ braced_code_t current_braced_code = action_braced_code;
%token PERCENT_DEFINE "%define"
%token PERCENT_PURE_PARSER "%pure-parser"
%token PERCENT_GLR_PARSER "%glr-parser"
%token PERCENT_DEFINES "%defines"
@@ -184,6 +187,7 @@ declaration:
| "%no-lines" { no_lines_flag = 1; }
| "%output" "=" string_content { spec_outfile = $3; }
| "%pure-parser" { pure_parser = 1; }
| "%glr-parser" { glr_parser = 1; }
| "%skeleton" string_content { skeleton = $2; }
| "%token-table" { token_table_flag = 1; }
| "%verbose" { report_flag = 1; }
@@ -355,6 +359,10 @@ rhs:
{ grammar_current_rule_action_append ($2, @2); }
| rhs "%prec" symbol
{ grammar_current_rule_prec_set ($3, @3); }
| rhs "%dprec" INT
{ grammar_current_rule_dprec_set ($3, @3); }
| rhs "%merge" TYPE
{ grammar_current_rule_merge_set ($3, @3); }
;
symbol:

View File

@@ -37,6 +37,7 @@
int lineno;
static symbol_list_t *grammar = NULL;
static int start_flag = 0;
merger_list *merge_functions;
/* Nonzero if %union has been seen. */
int typed = 0;
@@ -105,6 +106,60 @@ epilogue_set (const char *epilogue, location_t location)
/*-------------------------------------------------------------------.
| Return the merger index for a merging function named NAME, whose |
| arguments have type TYPE. Records the function, if new, in |
| merger_list. |
`-------------------------------------------------------------------*/
static int
get_merge_function (const char* name, const char* type)
{
merger_list *syms;
merger_list head;
int n;
if (! glr_parser)
return 0;
if (type == NULL)
type = "";
head.next = merge_functions;
for (syms = &head, n = 1; syms->next != NULL; syms = syms->next, n += 1)
if (strcmp (name, syms->next->name) == 0)
break;
if (syms->next == NULL) {
syms->next = XMALLOC (merger_list, 1);
syms->next->name = strdup (name);
syms->next->type = strdup (type);
syms->next->next = NULL;
merge_functions = head.next;
} else if (strcmp (type, syms->next->type) != 0)
warn (_("result type clash on merge function %s: `%s' vs. `%s'"),
name, type, syms->next->type);
return n;
}
/*--------------------------------------.
| Free all merge-function definitions. |
`--------------------------------------*/
void
free_merger_functions (void)
{
merger_list *L0;
if (! glr_parser)
return;
L0 = merge_functions;
while (L0 != NULL)
{
merger_list *L1 = L0->next;
free (L0);
L0 = L1;
}
}
/*-------------------------------------------------------------------.
| Generate a dummy symbol, a nonterminal, whose name cannot conflict |
| with the user's names. |
@@ -307,6 +362,34 @@ grammar_current_rule_prec_set (symbol_t *precsym, location_t location)
current_rule->ruleprec = precsym;
}
/* Attach dynamic precedence DPREC to the current rule. */
void
grammar_current_rule_dprec_set (int dprec, location_t location)
{
if (! glr_parser)
warn_at (location, _("%%dprec affects only GLR parsers"));
if (dprec <= 0)
complain_at (location, _("%%dprec must be followed by positive number"));
else if (current_rule->dprec != 0)
complain_at (location, _("only one %%dprec allowed per rule"));
current_rule->dprec = dprec;
}
/* Attach a merge function NAME with argument type TYPE to current
rule. */
void
grammar_current_rule_merge_set (const char* name, location_t location)
{
if (! glr_parser)
warn_at (location, _("%%merge affects only GLR parsers"));
if (current_rule->merger != 0)
complain_at (location, _("only one %%merge allowed per rule"));
current_rule->merger =
get_merge_function (name, current_rule->sym->type_name);
}
/* Attach a SYMBOL to the current rule. If needed, move the previous
action as a mid-rule action. */
@@ -319,7 +402,6 @@ grammar_current_rule_symbol_append (symbol_t *symbol, location_t location)
grammar_symbol_append (symbol, location);
}
/* Attach an ACTION to the current rule. If needed, move the previous
action as a mid-rule action. */
@@ -363,6 +445,8 @@ packgram (void)
rules[ruleno].useful = TRUE;
rules[ruleno].action = p->action;
rules[ruleno].action_location = p->action_location;
rules[ruleno].dprec = p->dprec;
rules[ruleno].merger = p->merger;
p = p->next;
while (p && p->sym)

View File

@@ -24,6 +24,14 @@
# include "symlist.h"
# include "parse-gram.h"
typedef struct merger_list
{
struct merger_list* next;
const char* name;
const char* type;
}
merger_list;
typedef struct gram_control_s
{
int errcode;
@@ -70,12 +78,21 @@ void grammar_rule_end PARAMS ((location_t l));
void grammar_midrule_action PARAMS ((void));
void grammar_current_rule_prec_set PARAMS ((symbol_t *precsym,
location_t l));
void grammar_current_rule_dprec_set PARAMS ((int dprec,
location_t l));
void grammer_current_rule_merge_set PARAMS ((const char* name,
location_t l));
void grammar_current_rule_symbol_append PARAMS ((symbol_t *symbol,
location_t l));
void grammar_current_rule_action_append PARAMS ((const char *action,
location_t l));
extern symbol_list_t *current_rule;
void reader PARAMS ((void));
void free_merger_functions PARAMS ((void));
extern merger_list *merge_functions;
extern int typed;
#endif /* !READER_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -124,12 +124,15 @@ blanks [ \t\f]+
"%define" return PERCENT_DEFINE;
"%defines" return PERCENT_DEFINES;
"%destructor" return PERCENT_DESTRUCTOR;
"%dprec" return PERCENT_DPREC;
"%error"[-_]"verbose" return PERCENT_ERROR_VERBOSE;
"%expect" return PERCENT_EXPECT;
"%file-prefix" return PERCENT_FILE_PREFIX;
"%fixed"[-_]"output"[-_]"files" return PERCENT_YACC;
"%glr"[-_]"parser" return PERCENT_GLR_PARSER;
"%left" return PERCENT_LEFT;
"%locations" return PERCENT_LOCATIONS;
"%merge" return PERCENT_MERGE;
"%name"[-_]"prefix" return PERCENT_NAME_PREFIX;
"%no"[-_]"lines" return PERCENT_NO_LINES;
"%nonassoc" return PERCENT_NONASSOC;

View File

@@ -36,6 +36,8 @@ symbol_list_new (symbol_t *sym, location_t location)
res->location = location;
res->action = NULL;
res->ruleprec = NULL;
res->dprec = 0;
res->merger = 0;
return res;
}

View File

@@ -35,6 +35,8 @@ typedef struct symbol_list_s
location_t action_location;
symbol_t *ruleprec;
int dprec;
int merger;
} symbol_list_t;