Compare commits

...
11 Commits
Author SHA1 Message Date
Valentin Tolmer c8c9212bbd news: new syntax (%gprec and %precr) 2013-08-01 15:56:00 +02:00
Valentin Tolmer d992a222af regen 2013-08-01 15:56:00 +02:00
Valentin Tolmer 86a2a43854 tests: new tests for %gprec and %precr
3 grammars: one typical, with normal test cases, one to display all the
warnings introduced, and one with the errors introduced.

* tests/conflicts.at: New
2013-08-01 15:24:52 +02:00
Valentin Tolmer d8de391c38 syntax: introducing %precr to add specific precedence relations
It is now possible to add specific precedence relations between two symbols,
or a symbol and a group, with the %precr keyword:

%gprec arith {
  %left '+' '-'
  %left '*' '/'
}
%gprec boolean {
  %left OR
  %left AND
}
%right '^'

%precr '^' > arith
%precr OR AND > '^'

Here, the symbol ^ is of higher priority than the the ones in arith, but of
lower priority than both OR and AND. OR and '+', for example, cannot be
compared.

* src/parse-gram.y, src/scan-gram.l: Lexer and grammar implementation of
%precr.
* src/symtab.c, src/symtab.h: implementation of the addition of single link
precedence relationships.
2013-08-01 15:24:52 +02:00
Valentin Tolmer f8a710c6f4 syntax: introducing %gprec for precedence groups
It is now possible to introduce precedence groups, with precedence
relationships inside the group, but not with the outside tokens.  Ex:

%gprec arith {
  %left '+' '-'
  %left '*' '/'
  %right '^'
}

%gprec {
  %left OR
  %left AND
}

%left OTHER
%precedence OTHER2

Here, the arithmetical operators (in the "arith" group) can be compared, the
boolean operators can be compared, but OTHER can only be compared to OTHER2.

* src/gram.c, src/gram.h, src/scan-gram.l, src/parse-gram.y: {} blocks after
%gprec are understood by the lexer
* src/parse-gram.y: New syntax
* tests/input.at, tests/regression.at: Fix due to lexer change
2013-08-01 15:24:52 +02:00
Valentin Tolmer 2d8fc07778 conflicts: switch to partial order precedence system
Even though it is not yet fully deployed, this commit lays the ground for
the partial order precedence system, by changing to a graph-based order and
introducing precedence groups (only the default one can be used for now).

* src/symtab.h (struct symbol): Removed extra fields
* src/symtab.h: New function declarations
* src/symtab.c: New functions for precedence and groups, new hash table for
groups
* src/AnnotationList.c, src/conflicts.c, src/gram.c, src/print-xml.c,
* src/symtab.c: Adaptation to the new prec_node structure
* tests/existing.at (GAWK LALR): Fix
2013-08-01 15:24:52 +02:00
Valentin Tolmer a910d26cfb introduction of the new structures to prepare for partial order precedence
New structures: symgroup, prec_link, prec_node, and an enum of the
precedence relation operators.  Symbols have two more fields to prepare for
the precedence graph and grouping to come.

* src/symtab.h (struct symbol): Two new fields
* src/symtab.h: New structures
2013-08-01 15:24:52 +02:00
Valentin TolmerandAkim Demaille a728075710 symbols: improve symbol aliasing
Rather than having duplicate info in the symbol and the alias that has
to be resolved later on, both the symbol and the alias have a common
pointer to a separate structure containing this info.

* src/symtab.h (sym_content): New structure.
* src/symtab.c (sym_content_new, sym_content_free, symbol_free): New

* src/AnnotationList.c, src/conflicts.c, src/gram.c, src/gram.h,
* src/graphviz.c, src/ielr.c, src/output.c, src/parse-gram.y, src/print.c
* src/print-xml.c, src/print_graph.c, src/reader.c, src/reduce.c,
* src/state.h, src/symlist.c, src/symtab.c, src/symtab.h, src/tables.c:
Adjust.

* tests/input.at: Fix expectations (order changes).
2013-08-01 12:49:51 +02:00
Akim Demaille c4aa4ff541 build: ship the ASCII art figures
We don't ship the *.txt files that are used to build the info
file.
Reported by Colin Daley.

* doc/figs/example.txt: New.
* doc/local.mk (bison.info): Depend on the txt files.
And ship them.
2013-08-01 11:41:49 +02:00
Akim Demaille b97bbbaed7 doc: prefer the ".gv" extension to ".dot"
See http://marc.info/?l=graphviz-devel&m=129418103126092 for the
motivation (basically, some word processor now uses *.dot).

* doc/figs/example-reduce.dot: Rename as...
* doc/figs/example-reduce.gv: this.
* doc/figs/example-shift.dot: Rename as...
* doc/figs/example-shift.gv: this.
* doc/figs/example.dot: Rename as...
* doc/figs/example.gv: this.
* doc/local.mk: Adjust.
2013-08-01 11:20:13 +02:00
Akim Demaille e386b50f26 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2013-07-25 18:13:53 +02:00
33 changed files with 2064 additions and 1052 deletions
+1 -1
View File
@@ -1 +1 @@
2.7.91
3.0
+29
View File
@@ -1,5 +1,34 @@
GNU Bison NEWS
* Noteworthy changes in release ?.? (????-??-??) [?]
** New syntax: partial-order precedence relationships
Formerly, the precedence order of tokens was linear, depending only on the
order in which they were declared. With the new syntax, all the tokens are
not necessarily comparable. It is possible to declare a group of tokens with
no links outside of the group, and to later on add only those needed.
The uncomparability of tokens would allow for more feedback on new conflicts
silently resolved via precedence.
An example of the new syntax applied to arithmetic and boolean operators,
with '^' serving as both numerical power and boolean XOR:
%gprec arith {
%left '+' '-'
%left '*' '/'
}
%gprec bool {
%left OR
%left AND
}
%gprec { %right '^' }
%precr '^' > arith
%precr OR AND > '^'
Here, AND is not comparable with '+', but '^' > '+' and AND > '^'
* Noteworthy changes in release 3.0 (2013-07-25) [stable]
** WARNING: Future backward-incompatibilities!
+1
View File
@@ -25,6 +25,7 @@ Bruce Lilly [email protected]
Bruno Haible [email protected]
Charles-Henri de Boysson [email protected]
Christian Burger [email protected]
Colin Daley [email protected]
Cris Bailiff [email protected]
Cris van Pelt [email protected]
Csaba Raduly [email protected]
+2
View File
@@ -0,0 +1,2 @@
This file is a stub, not used by the documentation. If you feel like
contributing ASCII art for example.gv, please step forward!
+13 -12
View File
@@ -23,9 +23,10 @@ doc_bison_TEXINFOS = \
# Cannot express dependencies directly on file names because of Automake.
# Obfuscate with a variable.
doc_bison = doc/bison
$(doc_bison).dvi: $(FIGS_DOT:.dot=.eps)
$(doc_bison).pdf: $(FIGS_DOT:.dot=.pdf)
$(doc_bison).html: $(FIGS_DOT:.dot=.png)
$(doc_bison).dvi: $(FIGS_GV:.gv=.eps)
$(doc_bison).info: $(FIGS_GV:.gv=.txt)
$(doc_bison).pdf: $(FIGS_GV:.gv=.pdf)
$(doc_bison).html: $(FIGS_GV:.gv=.png)
TEXI2DVI = texi2dvi --build-dir=doc/bison.t2d -I doc
CLEANDIRS = doc/bison.t2d
@@ -124,25 +125,25 @@ nodist_man_MANS = doc/yacc.1
## ----------------------------- ##
CLEANDIRS += doc/figs
FIGS_DOT = \
doc/figs/example.dot \
doc/figs/example-reduce.dot doc/figs/example-shift.dot
FIGS_GV = \
doc/figs/example.gv \
doc/figs/example-reduce.gv doc/figs/example-shift.gv
EXTRA_DIST += \
$(FIGS_DOT) \
$(FIGS_DOT:.dot=.eps) $(FIGS_DOT:.dot=.pdf) $(FIGS_DOT:.dot=.png)
SUFFIXES += .dot .eps .pdf .png
$(FIGS_GV) $(FIGS_GV:.gv=.txt) \
$(FIGS_GV:.gv=.eps) $(FIGS_GV:.gv=.pdf) $(FIGS_GV:.gv=.png)
SUFFIXES += .gv .eps .pdf .png
.dot.eps:
.gv.eps:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Teps $< >$@.tmp
$(AM_V_at) mv $@.tmp $@
.dot.pdf:
.gv.pdf:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Tpdf $< >$@.tmp
$(AM_V_at) mv $@.tmp $@
.dot.png:
.gv.png:
$(AM_V_GEN) $(MKDIR_P) `echo "./$@" | sed -e 's,/[^/]*$$,,'`
$(AM_V_at) $(DOT) -Gmargin=0 -Tpng $< >$@.tmp
$(AM_V_at) mv $@.tmp $@
+9 -8
View File
@@ -242,7 +242,7 @@ AnnotationList__computePredecessorAnnotations (AnnotationList *self, state *s,
{
symbol_number contribution_token =
InadequacyList__getContributionToken (self->inadequacyNode, ci)
->number;
->content->number;
if (AnnotationList__isContributionAlways (self, ci))
{
annotation_node->contributions[ci] = NULL;
@@ -549,7 +549,7 @@ AnnotationList__compute_from_inadequacies (
does discard annotations in the simplest case of a S/R
conflict with no token precedence. */
aver (!bitset_test (shift_tokens, conflicted_token)
|| symbols[conflicted_token]->prec);
|| symbols[conflicted_token]->content->prec);
++annotation_counts[s->number];
if (contribution_count > *max_contributionsp)
*max_contributionsp = contribution_count;
@@ -595,7 +595,7 @@ AnnotationList__debug (AnnotationList const *self, size_t nitems, int spaces)
{
symbol_number token =
InadequacyList__getContributionToken (a->inadequacyNode, ci)
->number;
->content->number;
{
int j;
for (j = 0; j < spaces+2; ++j)
@@ -644,7 +644,7 @@ AnnotationList__computeLookaheadFilter (AnnotationList const *self,
Sbitset biter;
symbol_number token =
InadequacyList__getContributionToken (self->inadequacyNode, ci)
->number;
->content->number;
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
bitset_set (lookahead_filter[item], token);
}
@@ -679,7 +679,8 @@ AnnotationList__stateMakesContribution (AnnotationList const *self,
return false;
{
symbol_number token =
InadequacyList__getContributionToken (self->inadequacyNode, ci)->number;
InadequacyList__getContributionToken (self->inadequacyNode, ci)
->content->number;
Sbitset__Index item;
Sbitset biter;
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
@@ -709,7 +710,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
ContributionIndex ci;
int actioni;
ContributionIndex ci_rr_dominator = ContributionIndex__none;
int shift_precedence = token->prec;
int shift_precedence = token->content->prec;
/* If the token has no precedence set, shift is always chosen. */
if (!shift_precedence)
@@ -739,7 +740,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
if (reduce_precedence
&& (reduce_precedence < shift_precedence
|| (reduce_precedence == shift_precedence
&& token->assoc == right_assoc)))
&& token->content->prec_node->assoc == right_assoc)))
continue;
if (!AnnotationList__stateMakesContribution (self, nitems, ci,
lookaheads))
@@ -747,7 +748,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
/* This uneliminated reduction contributes, so see if it can cause
an error action. */
if (reduce_precedence == shift_precedence
&& token->assoc == non_assoc)
&& token->content->prec_node->assoc == non_assoc)
{
/* It's not possible to find split-stable domination over
shift after a potential %nonassoc. */
+36 -15
View File
@@ -53,7 +53,8 @@ enum conflict_resolution
reduce_resolution,
left_resolution,
right_resolution,
nonassoc_resolution
nonassoc_resolution,
uncomparable_resolution
};
@@ -90,6 +91,7 @@ log_resolution (rule *r, symbol_number token,
break;
case nonassoc_resolution:
case uncomparable_resolution:
obstack_printf (&solved_conflicts_obstack,
_(" Conflict between rule %d and token %s"
" resolved as an error"),
@@ -104,7 +106,7 @@ log_resolution (rule *r, symbol_number token,
case shift_resolution:
obstack_printf (&solved_conflicts_obstack,
" (%s < %s)",
r->prec->tag,
r->prec->symbol->tag,
symbols[token]->tag);
break;
@@ -112,7 +114,7 @@ log_resolution (rule *r, symbol_number token,
obstack_printf (&solved_conflicts_obstack,
" (%s < %s)",
symbols[token]->tag,
r->prec->tag);
r->prec->symbol->tag);
break;
case left_resolution:
@@ -132,6 +134,12 @@ log_resolution (rule *r, symbol_number token,
" (%%nonassoc %s)",
symbols[token]->tag);
break;
case uncomparable_resolution:
obstack_printf (&solved_conflicts_obstack,
" (%s uncomparable with %s)",
r->prec->symbol->tag,
symbols[token]->tag);
break;
}
obstack_sgrow (&solved_conflicts_obstack, ".\n");
@@ -161,6 +169,7 @@ log_resolution (rule *r, symbol_number token,
xml_escape (symbols[token]->tag));
break;
case uncomparable_resolution:
case nonassoc_resolution:
obstack_printf (&solved_conflicts_xml_obstack,
" <resolution rule=\"%d\" symbol=\"%s\""
@@ -176,7 +185,7 @@ log_resolution (rule *r, symbol_number token,
case shift_resolution:
obstack_printf (&solved_conflicts_xml_obstack,
"%s &lt; %s",
xml_escape_n (0, r->prec->tag),
xml_escape_n (0, r->prec->symbol->tag),
xml_escape_n (1, symbols[token]->tag));
break;
@@ -184,7 +193,7 @@ log_resolution (rule *r, symbol_number token,
obstack_printf (&solved_conflicts_xml_obstack,
"%s &lt; %s",
xml_escape_n (0, symbols[token]->tag),
xml_escape_n (1, r->prec->tag));
xml_escape_n (1, r->prec->symbol->tag));
break;
case left_resolution:
@@ -204,6 +213,12 @@ log_resolution (rule *r, symbol_number token,
"%%nonassoc %s",
xml_escape (symbols[token]->tag));
break;
case uncomparable_resolution:
obstack_printf (&solved_conflicts_xml_obstack,
"%s uncomparable with %s",
xml_escape_n (0, symbols[token]->tag),
xml_escape_n (1, r->prec->symbol->tag));
break;
}
obstack_sgrow (&solved_conflicts_xml_obstack, "</resolution>\n");
@@ -243,7 +258,6 @@ flush_reduce (bitset lookahead_tokens, int token)
bitset_reset (lookahead_tokens, token);
}
/*------------------------------------------------------------------.
| Attempt to resolve shift-reduce conflict for one rule by means of |
| precedence declarations. It has already been checked that the |
@@ -263,30 +277,32 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
reductions *reds = s->reductions;
/* Find the rule to reduce by to get precedence of reduction. */
rule *redrule = reds->rules[ruleno];
int redprec = redrule->prec->prec;
prec_node *redprecsym = redrule->prec->prec_node;
bitset lookahead_tokens = reds->lookahead_tokens[ruleno];
for (i = 0; i < ntokens; i++)
if (bitset_test (lookahead_tokens, i)
&& bitset_test (lookahead_set, i)
&& symbols[i]->prec)
&& bitset_test (lookahead_set, i))
{
if (redprecsym && symbols[i]->content->prec_node)
{
/* Shift-reduce conflict occurs for token number i
and it has a precedence.
The precedence of shifting is that of token i. */
if (symbols[i]->prec < redprec)
if (is_prec_superior (redprecsym, symbols[i]->content->prec_node))
{
register_precedence (redrule->prec->number, i);
log_resolution (redrule, i, reduce_resolution);
flush_shift (s, i);
}
else if (symbols[i]->prec > redprec)
else if (is_prec_superior (symbols[i]->content->prec_node,
redprecsym))
{
register_precedence (i, redrule->prec->number);
log_resolution (redrule, i, shift_resolution);
flush_reduce (lookahead_tokens, i);
}
else
else if (is_prec_equal (redprecsym, symbols[i]->content->prec_node))
/* Matching precedence levels.
For non-defined associativity, keep both: unexpected
associativity conflict.
@@ -294,10 +310,10 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
For right associativity, keep only the shift.
For nonassociativity, keep neither. */
switch (symbols[i]->assoc)
switch (symbols[i]->content->prec_node->assoc)
{
case undef_assoc:
abort ();
break;
case precedence_assoc:
break;
@@ -323,6 +339,11 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
errors[(*nerrs)++] = symbols[i];
break;
}
else
log_resolution (redrule, i, uncomparable_resolution);
}
else
log_resolution (redrule, i, uncomparable_resolution);
}
}
@@ -354,7 +375,7 @@ set_conflicts (state *s, symbol **errors)
check for shift-reduce conflict, and try to resolve using
precedence. */
for (i = 0; i < reds->num; ++i)
if (reds->rules[i]->prec && reds->rules[i]->prec->prec
if (reds->rules[i]->prec /* && reds->rules[i]->prec->prec */
&& !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
resolve_sr_conflict (s, i, errors, &nerrs);
+11 -9
View File
@@ -44,6 +44,8 @@ int nvars = 0;
symbol_number *token_translations = NULL;
enum braces_state prec_braces = 0;
int max_user_token_number = 256;
bool
@@ -65,19 +67,19 @@ rule_useless_in_parser_p (rule const *r)
}
void
rule_lhs_print (rule const *r, symbol const *previous_lhs, FILE *out)
rule_lhs_print (rule const *r, sym_content const *previous_lhs, FILE *out)
{
fprintf (out, " %3d ", r->number);
if (previous_lhs != r->lhs)
fprintf (out, "%s:", r->lhs->tag);
fprintf (out, "%s:", r->lhs->symbol->tag);
else
fprintf (out, "%*s|", (int) strlen (previous_lhs->tag), "");
fprintf (out, "%*s|", (int) strlen (previous_lhs->symbol->tag), "");
}
void
rule_lhs_print_xml (rule const *r, FILE *out, int level)
{
xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->tag);
xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->symbol->tag);
}
size_t
@@ -158,7 +160,7 @@ grammar_rules_partial_print (FILE *out, const char *title,
{
rule_number r;
bool first = true;
symbol *previous_lhs = NULL;
sym_content *previous_lhs = NULL;
/* rule # : LHS -> RHS */
for (r = 0; r < nrules + nuseless_productions; r++)
@@ -209,7 +211,7 @@ grammar_rules_print_xml (FILE *out, int level)
rules[r].number, usefulness);
if (rules[r].precsym)
fprintf (out, " percent_prec=\"%s\"",
xml_escape (rules[r].precsym->tag));
xml_escape (rules[r].precsym->symbol->tag));
fputs (">\n", out);
}
rule_lhs_print_xml (&rules[r], out, level + 3);
@@ -239,7 +241,7 @@ grammar_dump (FILE *out, const char *title)
for (i = ntokens; i < nsyms; i++)
fprintf (out, "%5d %5d %5d %s\n",
i,
symbols[i]->prec, symbols[i]->assoc,
symbols[i]->content->prec, symbols[i]->content->prec_node->assoc,
symbols[i]->tag);
fprintf (out, "\n\n");
}
@@ -262,7 +264,7 @@ grammar_dump (FILE *out, const char *title)
fprintf (out, "%3d (%2d, %2d, %2d, %2u-%2u) %2d ->",
i,
rule_i->prec ? rule_i->prec->prec : 0,
rule_i->prec ? rule_i->prec->assoc : 0,
rule_i->prec ? rule_i->prec->prec_node->assoc : 0,
rule_i->useful,
rhs_itemno,
rhs_itemno + rhs_count - 1,
@@ -280,7 +282,7 @@ grammar_dump (FILE *out, const char *title)
rule_number r;
for (r = 0; r < nrules + nuseless_productions; r++)
{
fprintf (out, "%-5d %s:", r, rules[r].lhs->tag);
fprintf (out, "%-5d %s:", r, rules[r].lhs->symbol->tag);
rule_rhs_print (&rules[r], out);
fprintf (out, "\n");
}
+16 -4
View File
@@ -117,6 +117,17 @@ typedef int item_number;
extern item_number *ritem;
extern unsigned int nritems;
enum braces_state
{
default_braces_state,
gprec_seen,
group_name_seen,
braces_seen
};
/* Marker for the lexer and parser, to correctly interpret braces. */
extern enum braces_state prec_braces;
/* There is weird relationship between OT1H item_number and OTOH
symbol_number and rule_number: we store the latter in
item_number. symbol_number values are stored as-is, while
@@ -180,17 +191,17 @@ typedef struct
except if some rules are useless. */
rule_number number;
symbol *lhs;
sym_content *lhs;
item_number *rhs;
/* This symbol provides both the associativity, and the precedence. */
symbol *prec;
sym_content *prec;
int dprec;
int merger;
/* This symbol was attached to the rule via %prec. */
symbol *precsym;
sym_content *precsym;
location location;
bool useful;
@@ -220,7 +231,8 @@ bool rule_useless_in_parser_p (rule const *r);
/* Print this rule's number and lhs on OUT. If a PREVIOUS_LHS was
already displayed (by a previous call for another rule), avoid
useless repetitions. */
void rule_lhs_print (rule const *r, symbol const *previous_lhs, FILE *out);
void rule_lhs_print (rule const *r, sym_content const *previous_lhs,
FILE *out);
void rule_lhs_print_xml (rule const *r, FILE *out, int level);
/* Return the length of the RHS. */
+1 -1
View File
@@ -93,7 +93,7 @@ no_reduce_bitset_init (state const *s, bitset *no_reduce_set)
bitset_set (*no_reduce_set, TRANSITION_SYMBOL (s->transitions, n));
for (n = 0; n < s->errs->num; ++n)
if (s->errs->symbols[n])
bitset_set (*no_reduce_set, s->errs->symbols[n]->number);
bitset_set (*no_reduce_set, s->errs->symbols[n]->content->number);
}
static void
+2 -2
View File
@@ -424,7 +424,7 @@ ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item,
if (item_number_is_rule_number (ritem[s->items[item] - 2]))
{
state **predecessor;
aver (lhs != accept->number);
aver (lhs != accept->content->number);
for (predecessor = predecessors[s->number];
*predecessor;
++predecessor)
@@ -580,7 +580,7 @@ typedef struct state_list {
static void
ielr_compute_goto_follow_set (bitsetv follow_kernel_items,
bitsetv always_follows, state_list *s,
symbol *n, bitset follow_set)
sym_content *n, bitset follow_set)
{
goto_number n_goto = map_goto (s->lr0Isocore->state->number, n->number);
bitset_copy (follow_set, always_follows[n_goto]);
+12 -10
View File
@@ -149,7 +149,7 @@ prepare_symbols (void)
MUSCLE_INSERT_INT ("tokens_number", ntokens);
MUSCLE_INSERT_INT ("nterms_number", nvars);
MUSCLE_INSERT_INT ("symbols_number", nsyms);
MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number);
MUSCLE_INSERT_INT ("undef_token_number", undeftoken->content->number);
MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number);
muscle_insert_symbol_number_table ("translate",
@@ -197,7 +197,7 @@ prepare_symbols (void)
int i;
int *values = xnmalloc (ntokens, sizeof *values);
for (i = 0; i < ntokens; ++i)
values[i] = symbols[i]->user_token_number;
values[i] = symbols[i]->content->user_token_number;
muscle_insert_int_table ("toknum", values,
values[0], 1, ntokens);
free (values);
@@ -283,9 +283,9 @@ prepare_states (void)
static int
symbol_type_name_cmp (const symbol **lhs, const symbol **rhs)
{
int res = uniqstr_cmp ((*lhs)->type_name, (*rhs)->type_name);
int res = uniqstr_cmp ((*lhs)->content->type_name, (*rhs)->content->type_name);
if (!res)
res = (*lhs)->number - (*rhs)->number;
res = (*lhs)->content->number - (*rhs)->content->number;
return res;
}
@@ -320,8 +320,9 @@ type_names_output (FILE *out)
/* The index of the first symbol of the current type-name. */
int i0 = i;
fputs (i ? ",\n[" : "[", out);
for (; i < nsyms && syms[i]->type_name == syms[i0]->type_name; ++i)
fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->number);
for (; i < nsyms
&& syms[i]->content->type_name == syms[i0]->content->type_name; ++i)
fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->content->number);
fputs ("]", out);
}
fputs ("])\n\n", out);
@@ -428,20 +429,21 @@ prepare_symbol_definitions (void)
MUSCLE_INSERT_STRING (key, sym->tag);
SET_KEY ("user_number");
MUSCLE_INSERT_INT (key, sym->user_token_number);
MUSCLE_INSERT_INT (key, sym->content->user_token_number);
SET_KEY ("is_token");
MUSCLE_INSERT_INT (key,
i < ntokens && sym != errtoken && sym != undeftoken);
SET_KEY ("number");
MUSCLE_INSERT_INT (key, sym->number);
MUSCLE_INSERT_INT (key, sym->content->number);
SET_KEY ("has_type");
MUSCLE_INSERT_INT (key, !!sym->type_name);
MUSCLE_INSERT_INT (key, !!sym->content->type_name);
SET_KEY ("type");
MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : "");
MUSCLE_INSERT_STRING (key, sym->content->type_name
? sym->content->type_name : "");
{
int j;
+787 -652
View File
File diff suppressed because it is too large Load Diff
+64 -57
View File
@@ -52,7 +52,7 @@ extern int gram_debug;
#include "symlist.h"
#include "symtab.h"
#line 221 "src/parse-gram.y" /* yacc.c:1909 */
#line 233 "src/parse-gram.y" /* yacc.c:1909 */
typedef enum
{
@@ -61,7 +61,7 @@ extern int gram_debug;
param_parse = 1 << 1,
param_both = param_lex | param_parse
} param_type;
#line 645 "src/parse-gram.y" /* yacc.c:1909 */
#line 723 "src/parse-gram.y" /* yacc.c:1909 */
#include "muscle-tab.h"
#line 68 "src/parse-gram.h" /* yacc.c:1909 */
@@ -84,49 +84,54 @@ extern int gram_debug;
PERCENT_PRECEDENCE = 267,
PERCENT_PREC = 268,
PERCENT_DPREC = 269,
PERCENT_MERGE = 270,
PERCENT_CODE = 271,
PERCENT_DEFAULT_PREC = 272,
PERCENT_DEFINE = 273,
PERCENT_DEFINES = 274,
PERCENT_ERROR_VERBOSE = 275,
PERCENT_EXPECT = 276,
PERCENT_EXPECT_RR = 277,
PERCENT_FLAG = 278,
PERCENT_FILE_PREFIX = 279,
PERCENT_GLR_PARSER = 280,
PERCENT_INITIAL_ACTION = 281,
PERCENT_LANGUAGE = 282,
PERCENT_NAME_PREFIX = 283,
PERCENT_NO_DEFAULT_PREC = 284,
PERCENT_NO_LINES = 285,
PERCENT_NONDETERMINISTIC_PARSER = 286,
PERCENT_OUTPUT = 287,
PERCENT_REQUIRE = 288,
PERCENT_SKELETON = 289,
PERCENT_START = 290,
PERCENT_TOKEN_TABLE = 291,
PERCENT_VERBOSE = 292,
PERCENT_YACC = 293,
BRACED_CODE = 294,
BRACED_PREDICATE = 295,
BRACKETED_ID = 296,
CHAR = 297,
EPILOGUE = 298,
EQUAL = 299,
ID = 300,
ID_COLON = 301,
PERCENT_PERCENT = 302,
PIPE = 303,
PROLOGUE = 304,
SEMICOLON = 305,
TAG = 306,
TAG_ANY = 307,
TAG_NONE = 308,
INT = 309,
PERCENT_PARAM = 310,
PERCENT_UNION = 311,
PERCENT_EMPTY = 312
PERCENT_GPREC = 270,
PERCENT_PRECR = 271,
PERCENT_MERGE = 272,
PERCENT_CODE = 273,
PERCENT_DEFAULT_PREC = 274,
PERCENT_DEFINE = 275,
PERCENT_DEFINES = 276,
PERCENT_ERROR_VERBOSE = 277,
PERCENT_EXPECT = 278,
PERCENT_EXPECT_RR = 279,
PERCENT_FLAG = 280,
PERCENT_FILE_PREFIX = 281,
PERCENT_GLR_PARSER = 282,
PERCENT_INITIAL_ACTION = 283,
PERCENT_LANGUAGE = 284,
PERCENT_NAME_PREFIX = 285,
PERCENT_NO_DEFAULT_PREC = 286,
PERCENT_NO_LINES = 287,
PERCENT_NONDETERMINISTIC_PARSER = 288,
PERCENT_OUTPUT = 289,
PERCENT_REQUIRE = 290,
PERCENT_SKELETON = 291,
PERCENT_START = 292,
PERCENT_TOKEN_TABLE = 293,
PERCENT_VERBOSE = 294,
PERCENT_YACC = 295,
BRACED_CODE = 296,
BRACED_PREDICATE = 297,
BRACKETED_ID = 298,
CHAR = 299,
EPILOGUE = 300,
EQUAL = 301,
ID = 302,
ID_COLON = 303,
PERCENT_PERCENT = 304,
PIPE = 305,
PROLOGUE = 306,
SEMICOLON = 307,
GT = 308,
TAG = 309,
TAG_ANY = 310,
TAG_NONE = 311,
LBRACE = 312,
RBRACE = 313,
INT = 314,
PERCENT_PARAM = 315,
PERCENT_UNION = 316,
PERCENT_EMPTY = 317
};
#endif
@@ -135,27 +140,29 @@ extern int gram_debug;
typedef union GRAM_STYPE GRAM_STYPE;
union GRAM_STYPE
{
#line 182 "src/parse-gram.y" /* yacc.c:1909 */
#line 187 "src/parse-gram.y" /* yacc.c:1909 */
unsigned char character;
#line 186 "src/parse-gram.y" /* yacc.c:1909 */
char *code;
#line 191 "src/parse-gram.y" /* yacc.c:1909 */
char *code;
#line 196 "src/parse-gram.y" /* yacc.c:1909 */
uniqstr uniqstr;
#line 199 "src/parse-gram.y" /* yacc.c:1909 */
#line 204 "src/parse-gram.y" /* yacc.c:1909 */
int integer;
#line 203 "src/parse-gram.y" /* yacc.c:1909 */
symbol *symbol;
#line 208 "src/parse-gram.y" /* yacc.c:1909 */
symbol *symbol;
#line 213 "src/parse-gram.y" /* yacc.c:1909 */
assoc assoc;
#line 211 "src/parse-gram.y" /* yacc.c:1909 */
#line 216 "src/parse-gram.y" /* yacc.c:1909 */
symbol_list *list;
#line 214 "src/parse-gram.y" /* yacc.c:1909 */
#line 219 "src/parse-gram.y" /* yacc.c:1909 */
named_ref *named_ref;
#line 241 "src/parse-gram.y" /* yacc.c:1909 */
#line 224 "src/parse-gram.y" /* yacc.c:1909 */
prec_rel_comparator prec_rel_comparator;
#line 253 "src/parse-gram.y" /* yacc.c:1909 */
param_type param;
#line 409 "src/parse-gram.y" /* yacc.c:1909 */
#line 423 "src/parse-gram.y" /* yacc.c:1909 */
code_props_type code_type;
#line 647 "src/parse-gram.y" /* yacc.c:1909 */
#line 725 "src/parse-gram.y" /* yacc.c:1909 */
struct
{
@@ -163,7 +170,7 @@ code_props_type code_type;
muscle_kind kind;
} value;
#line 167 "src/parse-gram.h" /* yacc.c:1909 */
#line 174 "src/parse-gram.h" /* yacc.c:1909 */
};
# define GRAM_STYPE_IS_TRIVIAL 1
# define GRAM_STYPE_IS_DECLARED 1
+78
View File
@@ -130,6 +130,8 @@
%token PERCENT_PREC "%prec"
%token PERCENT_DPREC "%dprec"
%token PERCENT_GPREC "%gprec"
%token PERCENT_PRECR "%precr"
%token PERCENT_MERGE "%merge"
/*----------------------.
@@ -175,9 +177,12 @@
%token PIPE "|"
%token PROLOGUE "%{...%}"
%token SEMICOLON ";"
%token GT ">"
%token TAG "<tag>"
%token TAG_ANY "<*>"
%token TAG_NONE "<>"
%token LBRACE "{"
%token RBRACE "}"
%union {unsigned char character;}
%type <character> CHAR
@@ -214,6 +219,13 @@
%union {named_ref *named_ref;}
%type <named_ref> named_ref.opt
%type <uniqstr> prec_group_name.opt string_or_id
%union {prec_rel_comparator prec_rel_comparator;}
%type <prec_rel_comparator> prec_rel_comparator
%type <list> precedence_relation_symbols precedence_symbol
/*---------.
| %param. |
`---------*/
@@ -365,6 +377,8 @@ params:
grammar_declaration:
precedence_declaration
| precedence_group_declaration
| precedence_relation_declaration
| symbol_declaration
| "%start" symbol
{
@@ -457,6 +471,30 @@ symbol_declaration:
}
;
/* A group of symbols for precedence declaration */
precedence_group_declaration:
"%gprec" prec_group_name.opt
{
set_current_group ($2, &@2);
}
"{" precedence_declarations "}"
{
set_current_group (DEFAULT_GROUP_NAME, NULL);
}
;
/* Name for the precedence group. If none is present a new unique one is
generated. */
prec_group_name.opt:
%empty { $$ = new_anonymous_group_name (); }
| variable /* Just a string, maybe there's a better way? */
;
precedence_declarations:
precedence_declaration
| precedence_declarations precedence_declaration
;
precedence_declaration:
precedence_declarator tag.opt symbols.prec
{
@@ -484,6 +522,46 @@ tag.opt:
| TAG { current_type = $1; tag_seen = true; }
;
/* Declaration of a precedence relation between two (lists of) tokens */
precedence_relation_declaration:
"%precr" precedence_relation_symbols
{ prec_braces = default_braces_state; }
prec_rel_comparator
precedence_relation_symbols
{ declare_precedence_relation ($2, $5, $4, @4); }
;
precedence_relation_symbols:
precedence_symbol { $$ = $1; }
| precedence_relation_symbols precedence_symbol
{ $$ = symbol_list_append ($1, $2); }
;
precedence_symbol:
string_or_id
{
if (is_prec_group ($1))
$$ = expand_symbol_group (symgroup_from_uniqstr($1, &@1), @1);
else
$$ = symbol_list_sym_new (symbol_from_uniqstr ($1, @1), @1);
}
| CHAR
{
$$ = symbol_list_sym_new (symbol_from_uniqstr (uniqstr_new (char_name ($1)), @1), @1);
}
;
string_or_id:
STRING { $$ = uniqstr_new (quotearg_style (c_quoting_style, $1)); }
| ID { $$ = $1; }
;
prec_rel_comparator:
">" { $$ = prec_superior; }
| "=" { $$ = prec_equal; }
| ">" ">" { $$ = prec_superior_strict; }
;
/* Just like symbols.1 but accept INT for the sake of POSIX. */
symbols.prec:
symbol.prec
+5 -4
View File
@@ -260,7 +260,7 @@ print_reductions (FILE *out, int level, state *s)
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
for (i = 0; i < s->errs->num; ++i)
if (s->errs->symbols[i])
bitset_set (no_reduce_set, s->errs->symbols[i]->number);
bitset_set (no_reduce_set, s->errs->symbols[i]->content->number);
if (default_reduction)
report = true;
@@ -388,11 +388,12 @@ print_grammar (FILE *out, int level)
/* Terminals */
xml_puts (out, level + 1, "<terminals>");
for (i = 0; i < max_user_token_number + 1; i++)
if (token_translations[i] != undeftoken->number)
if (token_translations[i] != undeftoken->content->number)
{
char const *tag = symbols[token_translations[i]]->tag;
int precedence = symbols[token_translations[i]]->prec;
assoc associativity = symbols[token_translations[i]]->assoc;
int precedence = symbols[token_translations[i]]->content->prec;
assoc associativity = symbols[token_translations[i]]->content->prec_node
->assoc;
xml_indent (out, level + 2);
fprintf (out,
"<terminal symbol-number=\"%d\" token-number=\"%d\""
+5 -4
View File
@@ -72,7 +72,7 @@ print_core (FILE *out, state *s)
size_t i;
item_number *sitems = s->items;
size_t snritems = s->nitems;
symbol *previous_lhs = NULL;
sym_content *previous_lhs = NULL;
/* Output all the items of a state, not only its kernel. */
if (report_flag & report_itemsets)
@@ -223,7 +223,8 @@ print_reduction (FILE *out, size_t width,
if (!enabled)
fputc ('[', out);
if (r->number)
fprintf (out, _("reduce using rule %d (%s)"), r->number, r->lhs->tag);
fprintf (out, _("reduce using rule %d (%s)"), r->number,
r->lhs->symbol->tag);
else
fprintf (out, _("accept"));
if (!enabled)
@@ -257,7 +258,7 @@ print_reductions (FILE *out, state *s)
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
for (i = 0; i < s->errs->num; ++i)
if (s->errs->symbols[i])
bitset_set (no_reduce_set, s->errs->symbols[i]->number);
bitset_set (no_reduce_set, s->errs->symbols[i]->content->number);
/* Compute the width of the lookahead token column. */
if (default_reduction)
@@ -408,7 +409,7 @@ print_grammar (FILE *out)
/* TERMINAL (type #) : rule #s terminal is on RHS */
fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
for (i = 0; i < max_user_token_number + 1; i++)
if (token_translations[i] != undeftoken->number)
if (token_translations[i] != undeftoken->content->number)
{
const char *tag = symbols[token_translations[i]]->tag;
rule_number r;
+5 -4
View File
@@ -46,7 +46,7 @@ static void
print_core (struct obstack *oout, state *s)
{
item_number const *sitems = s->items;
symbol *previous_lhs = NULL;
sym_content *previous_lhs = NULL;
size_t i;
size_t snritems = s->nitems;
@@ -72,11 +72,12 @@ print_core (struct obstack *oout, state *s)
r = &rules[item_number_as_rule_number (*sp)];
obstack_printf (oout, "%3d ", r->number);
if (previous_lhs && UNIQSTR_EQ (previous_lhs->tag, r->lhs->tag))
if (previous_lhs && UNIQSTR_EQ (previous_lhs->symbol->tag,
r->lhs->symbol->tag))
obstack_printf (oout, "%*s| ",
(int) strlen (previous_lhs->tag), "");
(int) strlen (previous_lhs->symbol->tag), "");
else
obstack_printf (oout, "%s: ", escape (r->lhs->tag));
obstack_printf (oout, "%s: ", escape (r->lhs->symbol->tag));
previous_lhs = r->lhs;
for (sp = r->rhs; sp < sp1; sp++)
+27 -26
View File
@@ -240,13 +240,13 @@ grammar_current_rule_begin (symbol *lhs, location loc,
current_rule = grammar_end;
/* Mark the rule's lhs as a nonterminal if not already so. */
if (lhs->class == unknown_sym)
if (lhs->content->class == unknown_sym)
{
lhs->class = nterm_sym;
lhs->number = nvars;
lhs->content->class = nterm_sym;
lhs->content->number = nvars;
++nvars;
}
else if (lhs->class == token_sym)
else if (lhs->content->class == token_sym)
complain (&loc, complaint, _("rule given for %s, which is a token"),
lhs->tag);
}
@@ -292,15 +292,15 @@ grammar_rule_check (const symbol_list *r)
Don't worry about the default action if $$ is untyped, since $$'s
value can't be used. */
if (!r->action_props.code && r->content.sym->type_name)
if (!r->action_props.code && r->content.sym->content->type_name)
{
symbol *first_rhs = r->next->content.sym;
/* If $$ is being set in default way, report if any type mismatch. */
if (first_rhs)
{
char const *lhs_type = r->content.sym->type_name;
char const *lhs_type = r->content.sym->content->type_name;
const char *rhs_type =
first_rhs->type_name ? first_rhs->type_name : "";
first_rhs->content->type_name ? first_rhs->content->type_name : "";
if (!UNIQSTR_EQ (lhs_type, rhs_type))
complain (&r->location, Wother,
_("type clash on default action: <%s> != <%s>"),
@@ -350,7 +350,8 @@ grammar_rule_check (const symbol_list *r)
it for char literals and strings, which are always tokens. */
if (r->ruleprec
&& r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"'
&& r->ruleprec->status != declared && !r->ruleprec->prec)
&& r->ruleprec->content->status != declared
&& !r->ruleprec->content->prec)
complain (&r->location, Wother,
_("token for %%prec is not defined: %s"), r->ruleprec->tag);
}
@@ -517,8 +518,8 @@ grammar_current_rule_symbol_append (symbol *sym, location loc,
p = grammar_symbol_append (sym, loc);
if (name)
assign_named_ref (p, name);
if (sym->status == undeclared || sym->status == used)
sym->status = needed;
if (sym->content->status == undeclared || sym->content->status == used)
sym->content->status = needed;
}
/* Attach an ACTION to the current rule. */
@@ -558,11 +559,11 @@ packgram (void)
for (p = grammar; p; p = p->next)
{
symbol *ruleprec = p->ruleprec;
record_merge_function_type (p->merger, p->content.sym->type_name,
record_merge_function_type (p->merger, p->content.sym->content->type_name,
p->merger_declaration_location);
rules[ruleno].user_number = ruleno;
rules[ruleno].number = ruleno;
rules[ruleno].lhs = p->content.sym;
rules[ruleno].lhs = p->content.sym->content;
rules[ruleno].rhs = ritem + itemno;
rules[ruleno].prec = NULL;
rules[ruleno].dprec = p->dprec;
@@ -604,11 +605,11 @@ packgram (void)
/* item_number = symbol_number.
But the former needs to contain more: negative rule numbers. */
ritem[itemno++] =
symbol_number_as_item_number (p->content.sym->number);
symbol_number_as_item_number (p->content.sym->content->number);
/* A rule gets by default the precedence and associativity
of its last token. */
if (p->content.sym->class == token_sym && default_prec)
rules[ruleno].prec = p->content.sym;
if (p->content.sym->content->class == token_sym && default_prec)
rules[ruleno].prec = p->content.sym->content;
}
}
@@ -616,8 +617,8 @@ packgram (void)
the specified symbol's precedence replaces the default. */
if (ruleprec)
{
rules[ruleno].precsym = ruleprec;
rules[ruleno].prec = ruleprec;
rules[ruleno].precsym = ruleprec->content;
rules[ruleno].prec = ruleprec->content;
}
/* An item ends by the rule number (negated). */
ritem[itemno++] = rule_number_as_item_number (ruleno);
@@ -647,19 +648,19 @@ reader (void)
/* Construct the accept symbol. */
accept = symbol_get ("$accept", empty_location);
accept->class = nterm_sym;
accept->number = nvars++;
accept->content->class = nterm_sym;
accept->content->number = nvars++;
/* Construct the error token */
errtoken = symbol_get ("error", empty_location);
errtoken->class = token_sym;
errtoken->number = ntokens++;
errtoken->content->class = token_sym;
errtoken->content->number = ntokens++;
/* Construct a token that represents all undefined literal tokens.
It is always token number 2. */
undeftoken = symbol_get ("$undefined", empty_location);
undeftoken->class = token_sym;
undeftoken->number = ntokens++;
undeftoken->content->class = token_sym;
undeftoken->content->number = ntokens++;
gram_in = xfopen (grammar_file, "r");
@@ -721,10 +722,10 @@ check_and_convert_grammar (void)
if (!endtoken)
{
endtoken = symbol_get ("$end", empty_location);
endtoken->class = token_sym;
endtoken->number = 0;
endtoken->content->class = token_sym;
endtoken->content->number = 0;
/* Value specified by POSIX. */
endtoken->user_token_number = 0;
endtoken->content->user_token_number = 0;
}
/* Report any undefined symbols and consider them nonterminals. */
+9 -9
View File
@@ -163,9 +163,9 @@ inaccessable_symbols (void)
Pp = bitset_create (nrules, BITSET_FIXED);
/* If the start symbol isn't useful, then nothing will be useful. */
if (bitset_test (N, accept->number - ntokens))
if (bitset_test (N, accept->content->number - ntokens))
{
bitset_set (V, accept->number);
bitset_set (V, accept->content->number);
while (1)
{
@@ -196,9 +196,9 @@ inaccessable_symbols (void)
V = Vp;
/* Tokens 0, 1, and 2 are internal to Bison. Consider them useful. */
bitset_set (V, endtoken->number); /* end-of-input token */
bitset_set (V, errtoken->number); /* error token */
bitset_set (V, undeftoken->number); /* some undefined token */
bitset_set (V, endtoken->content->number); /* end-of-input token */
bitset_set (V, errtoken->content->number); /* error token */
bitset_set (V, undeftoken->content->number); /* some undefined token */
bitset_free (P);
P = Pp;
@@ -298,7 +298,7 @@ nonterminals_reduce (void)
if (!bitset_test (V, i))
{
nontermmap[i - ntokens] = n++;
if (symbols[i]->status != used)
if (symbols[i]->content->status != used)
complain (&symbols[i]->location, Wother,
_("nonterminal useless in grammar: %s"),
symbols[i]->tag);
@@ -310,7 +310,7 @@ nonterminals_reduce (void)
symbol **symbols_sorted = xnmalloc (nvars, sizeof *symbols_sorted);
for (i = ntokens; i < nsyms; i++)
symbols[i]->number = nontermmap[i - ntokens];
symbols[i]->content->number = nontermmap[i - ntokens];
for (i = ntokens; i < nsyms; i++)
symbols_sorted[nontermmap[i - ntokens] - ntokens] = symbols[i];
for (i = ntokens; i < nsyms; i++)
@@ -328,7 +328,7 @@ nonterminals_reduce (void)
*rhsp = symbol_number_as_item_number (nontermmap[*rhsp
- ntokens]);
}
accept->number = nontermmap[accept->number - ntokens];
accept->content->number = nontermmap[accept->content->number - ntokens];
}
nsyms -= nuseless_nonterminals;
@@ -415,7 +415,7 @@ reduce_grammar (void)
reduce_print ();
if (!bitset_test (N, accept->number - ntokens))
if (!bitset_test (N, accept->content->number - ntokens))
complain (&startsymbol_location, fatal,
_("start symbol %s does not derive any sentence"),
startsymbol->tag);
+17
View File
@@ -223,6 +223,10 @@ eqopt ([[:space:]]*=)?
"%fixed-output-files" return PERCENT_YACC;
"%initial-action" return PERCENT_INITIAL_ACTION;
"%glr-parser" return PERCENT_GLR_PARSER;
"%gprec" {
prec_braces = gprec_seen;
return PERCENT_GPREC;
}
"%language" return PERCENT_LANGUAGE;
"%left" return PERCENT_LEFT;
"%lex-param" RETURN_PERCENT_PARAM(lex);
@@ -239,6 +243,7 @@ eqopt ([[:space:]]*=)?
"%parse-param" RETURN_PERCENT_PARAM(parse);
"%prec" return PERCENT_PREC;
"%precedence" return PERCENT_PRECEDENCE;
"%precr" return PERCENT_PRECR;
"%printer" return PERCENT_PRINTER;
"%pure-parser" RETURN_PERCENT_FLAG("api.pure");
"%require" return PERCENT_REQUIRE;
@@ -273,10 +278,17 @@ eqopt ([[:space:]]*=)?
"=" return EQUAL;
"|" return PIPE;
";" return SEMICOLON;
"}" return RBRACE;
">" return GT;
{id} {
val->uniqstr = uniqstr_new (yytext);
id_loc = *loc;
if (prec_braces == gprec_seen)
{
prec_braces = group_name_seen;
return ID;
}
bracketed_id_str = NULL;
BEGIN SC_AFTER_IDENTIFIER;
}
@@ -307,6 +319,11 @@ eqopt ([[:space:]]*=)?
/* Code in between braces. */
"{" {
if (prec_braces == gprec_seen || prec_braces == group_name_seen)
{
prec_braces = braces_seen;
return LBRACE;
}
STRING_GROW;
nesting = 0;
code_start = loc->start;
+1 -1
View File
@@ -135,7 +135,7 @@ typedef struct
/* Is the TRANSITIONS->states[Num] labelled by the error token? */
# define TRANSITION_IS_ERROR(Transitions, Num) \
(TRANSITION_SYMBOL (Transitions, Num) == errtoken->number)
(TRANSITION_SYMBOL (Transitions, Num) == errtoken->content->number)
/* When resolving a SR conflicts, if the reduction wins, the shift is
disabled. */
+3 -3
View File
@@ -205,7 +205,7 @@ symbol_list_n_type_name_get (symbol_list *l, location loc, int n)
return NULL;
}
aver (l->content_type == SYMLIST_SYMBOL);
return l->content.sym->type_name;
return l->content.sym->content->type_name;
}
bool
@@ -223,8 +223,8 @@ symbol_list_code_props_set (symbol_list *node, code_props_type kind,
{
case SYMLIST_SYMBOL:
symbol_code_props_set (node->content.sym, kind, cprops);
if (node->content.sym->status == undeclared)
node->content.sym->status = used;
if (node->content.sym->content->status == undeclared)
node->content.sym->content->status = used;
break;
case SYMLIST_TYPE:
semantic_type_code_props_set
+606 -156
View File
File diff suppressed because it is too large Load Diff
+114 -8
View File
@@ -31,6 +31,8 @@
# include "scan-code.h"
# include "uniqstr.h"
typedef struct symbol_list symbol_list;
/*----------.
| Symbols. |
`----------*/
@@ -50,6 +52,7 @@ typedef int symbol_number;
typedef struct symbol symbol;
typedef struct sym_content sym_content;
/* Declaration status of a symbol.
@@ -61,6 +64,8 @@ typedef struct symbol symbol;
When status are checked at the end, "declared" symbols are fine,
"used" symbols trigger warnings, otherwise it's an error. */
typedef struct prec_node prec_node;
typedef enum
{
/** Used in the input file for an unknown reason (error). */
@@ -82,8 +87,6 @@ enum code_props_type
enum { CODE_PROPS_SIZE = 2 };
/* When extending this structure, be sure to complete
symbol_check_alias_consistency. */
struct symbol
{
/** The key, name of the symbol. */
@@ -91,6 +94,20 @@ struct symbol
/** The location of its first occurrence. */
location location;
/* Points to the other in the symbol-string pair for an alias. */
symbol *alias;
/** Whether this symbol is the alias of another or not. */
bool is_alias;
/** All the info about the pointed symbol is there. */
sym_content *content;
};
struct sym_content
{
symbol *symbol;
/** Its \c \%type.
Beware that this is the type_name as was entered by the user,
@@ -112,17 +129,21 @@ struct symbol
code_props props[CODE_PROPS_SIZE];
symbol_number number;
location prec_location;
/* Not used anymore, to remove. */
int prec;
assoc assoc;
int user_token_number;
/* Points to the other in the symbol-string pair for an alias.
Special value USER_NUMBER_HAS_STRING_ALIAS in the symbol half of the
symbol-string pair for an alias. */
symbol *alias;
symbol_class class;
status status;
/* The next element in the symbol precedence group. */
sym_content *group_next;
/* The graph node containing all the precedence information for this
symbol. */
prec_node *prec_node;
};
/** Undefined user number. */
@@ -277,6 +298,91 @@ void print_precedence_warnings (void);
void register_assoc (graphid i, graphid j);
/*------------------.
| Groups of symbols |
`------------------*/
#define DEFAULT_GROUP_NAME uniqstr_new ("__default__")
typedef struct symgroup symgroup;
struct symgroup
{
/** The name of the group. */
uniqstr tag;
/** The list of symbols in the group. */
sym_content * symbol_list;
location location;
} ;
/** Get a dummy name for an anonymous group. */
uniqstr new_anonymous_group_name (void);
/** Set the current group in the token precedence declaration to a new group
* with this name */
void set_current_group (const uniqstr name, location *loc);
/** Get or create the group by that name. The location information is used for
* creation when available. */
symgroup *
symgroup_from_uniqstr (const uniqstr key, location *loc);
/** Check if there is a symbol precedence group by that name. */
bool
is_prec_group (const uniqstr key);
/*----------------------------------.
| Graph of precedence relationships |
`----------------------------------*/
typedef struct prec_link prec_link;
struct prec_link
{
prec_node *target;
bool transitive;
prec_link *next;
};
struct prec_node
{
symbol *symbol;
/** Associativity for the symbol. */
assoc assoc;
location prec_location;
prec_link *sons;
prec_link *equals;
};
typedef enum prec_rel_comparator prec_rel_comparator;
enum prec_rel_comparator
{
prec_equal,
prec_superior,
prec_superior_strict,
};
/** Declare a precedence relationship between the symbols of the two lists,
* as defined by the operator. */
void
declare_precedence_relation (symbol_list *l1, symbol_list *l2,
prec_rel_comparator c, location loc);
/** Return the list of symbols contained in the group. */
symbol_list *
expand_symbol_group (symgroup * group, location loc);
/** Check if s1 and s2 have the same precedence level. */
bool is_prec_equal (prec_node * s1, prec_node * s2);
/** Check if from > to . */
bool is_prec_superior (prec_node * from, prec_node * to);
/*-----------------.
| Semantic types. |
`-----------------*/
+2 -2
View File
@@ -290,7 +290,7 @@ action_row (state *s)
/* Do not use any default reduction if there is a shift for
error */
if (sym == errtoken->number)
if (sym == errtoken->content->number)
nodefault = true;
}
@@ -300,7 +300,7 @@ action_row (state *s)
for (i = 0; i < errp->num; i++)
{
symbol *sym = errp->symbols[i];
actrow[sym->number] = ACTION_NUMBER_MINIMUM;
actrow[sym->content->number] = ACTION_NUMBER_MINIMUM;
}
/* Turn off default reductions where requested by the user. See
+146
View File
@@ -17,6 +17,152 @@
AT_BANNER([[Conflicts.]])
## ----------------- ##
## Precedence groups ##
## ----------------- ##
# Sample use case of precedence groups and relations, working.
AT_SETUP([Precedence groups])
AT_DATA_GRAMMAR([[input.y]],
[[%token CARET "^"
%token NUM BOOL '^' OR AND
%left '+' '-'
%gprec {
%right CARET
}
%gprec boolean {
%left OR
%left AND
}
%left '*' '/'
%precr boolean >> "^"
%precr CARET > '*' '/' '-' '+'
%%
stmt:
exp
| bool_exp
exp:
NUM
| exp '+' exp
| exp '-' exp
| exp '*' exp
| exp '/' exp
| exp "^" exp
bool_exp:
BOOL
| bool_exp AND bool_exp
| bool_exp OR bool_exp
| bool_exp CARET bool_exp
]])
AT_BISON_CHECK([[--report=all -o input.c input.y]], 0, [])
AT_CLEANUP
## -------------------------------- ##
## Conflicting precedence relations ##
## -------------------------------- ##
AT_SETUP([Conflicting precedence relations])
AT_DATA_GRAMMAR([[input.y]],
[[%token TOKEN
%precedence A
%precedence B
%precedence C
%precedence D E
%gprec group {
%precedence F
%precedence G
}
%precr B = C
%precr A > B
%precr C > B
%precr F > G
%precr F > A
%%
exp:
TOKEN
| exp A exp
| exp B exp
| exp C exp
| exp D exp
| exp E exp
| exp F exp
| exp G exp
]])
AT_BISON_CHECK([[-Wall -o input.c input.y]], 0, [],
[[input.y:20.10: warning: contradicting declaration: B = C is in conflict with the previous declaration: B > C [-Wprecedence]
input.y:21.10: warning: contradicting declaration: A > B is in conflict with the previous declaration: A < B [-Wprecedence]
input.y:22.10: warning: contradicting declaration: C > B is in conflict with the previous declaration: C = B [-Wprecedence]
input.y:23.10: warning: contradicting declaration: F > G is in conflict with the previous declaration: F < G [-Wprecedence]
input.y: warning: 27 shift/reduce conflicts [-Wconflicts-sr]
]])
AT_CLEANUP
## ------------------------------ ##
## Duplicate precedence relations ##
## ------------------------------ ##
AT_SETUP([Duplicate precedence relations])
AT_DATA_GRAMMAR([[input.y]],
[[%token TOKEN
%precedence A
%precedence B
%precedence C
%precedence D E
%gprec group {
%precedence F
%precedence G
}
%precr D = E
%precr B > A
%precr C > B
%precr G > F
%precr F > A
%precr C > group
%precr C > F
%%
exp:
TOKEN
| exp A exp
| exp B exp
| exp C exp
| exp D exp
| exp E exp
| exp F exp
| exp G exp
]])
AT_BISON_CHECK([[-Wall -o input.c input.y]], 0, [],
[[input.y:20.10: warning: duplicate declaration of the precedence relationship D = E [-Wprecedence]
input.y:20.10: warning: duplicate declaration of the precedence relationship E = D [-Wprecedence]
input.y:21.10: warning: duplicate declaration of the precedence relationship B > A [-Wprecedence]
input.y:22.10: warning: duplicate declaration of the precedence relationship C > B [-Wprecedence]
input.y:23.10: warning: duplicate declaration of the precedence relationship G > F [-Wprecedence]
input.y:26.10: warning: duplicate declaration of the precedence relationship C > F [-Wprecedence]
input.y: warning: 23 shift/reduce conflicts [-Wconflicts-sr]
]])
AT_CLEANUP
## ------------------------- ##
## Token declaration order. ##
## ------------------------- ##
+4 -4
View File
@@ -484,7 +484,7 @@ dnl - 61 -> 328: reduce -> shift on '*', '/', and '%'
NAME [reduce using rule 152 (opt_variable)]
'$' [reduce using rule 152 (opt_variable)]
@@ -5379,7 +5379,7 @@
@@ -5385,7 +5385,7 @@
156 | . '$' non_post_simp_exp
NAME shift, and go to state 9
@@ -493,7 +493,7 @@ dnl - 61 -> 328: reduce -> shift on '*', '/', and '%'
NAME [reduce using rule 152 (opt_variable)]
'$' [reduce using rule 152 (opt_variable)]
@@ -5399,7 +5399,7 @@
@@ -5405,7 +5405,7 @@
156 | . '$' non_post_simp_exp
NAME shift, and go to state 9
@@ -502,7 +502,7 @@ dnl - 61 -> 328: reduce -> shift on '*', '/', and '%'
NAME [reduce using rule 152 (opt_variable)]
'$' [reduce using rule 152 (opt_variable)]
@@ -6214,7 +6214,7 @@
@@ -6220,7 +6220,7 @@
156 | . '$' non_post_simp_exp
NAME shift, and go to state 9
@@ -511,7 +511,7 @@ dnl - 61 -> 328: reduce -> shift on '*', '/', and '%'
NAME [reduce using rule 152 (opt_variable)]
'$' [reduce using rule 152 (opt_variable)]
@@ -11099,3 +11099,274 @@
@@ -11117,3 +11117,274 @@
45 statement: LEX_FOR '(' opt_exp semi opt_nls exp semi opt_nls opt_exp r_paren opt_nls statement .
$default reduce using rule 45 (statement)
+10 -11
View File
@@ -64,14 +64,13 @@ AT_CHECK([[$PERL -pi -e 's/\\(\d{3})/chr(oct($1))/ge' input.y || exit 77]])
AT_BISON_CHECK([input.y], [1], [],
[[input.y:1.1-2: error: invalid characters: '\0\001\002\377?'
input.y:3.1: error: invalid character: '?'
input.y:4.14: error: invalid character: '}'
input.y:4.14: error: syntax error, unexpected }
input.y:5.1: error: invalid character: '%'
input.y:5.2: error: invalid character: '&'
input.y:6.1-17: error: invalid directive: '%a-does-not-exist'
input.y:7.1: error: invalid character: '%'
input.y:7.2: error: invalid character: '-'
input.y:8.1-9.0: error: missing '%}' at end of file
input.y:8.1-9.0: error: syntax error, unexpected %{...%}
]])
AT_CLEANUP
@@ -672,25 +671,25 @@ exp: foo;
]])
AT_BISON_CHECK([-fcaret input.y], [1], [],
[[input.y:8.7-11: error: %type redeclaration for foo
[[input.y:8.7-11: error: %type redeclaration for "foo"
%type <baz> "foo"
^^^^^
input.y:3.7-11: previous declaration
%type <bar> foo
^^^^^
input.y:10.13-17: error: %destructor redeclaration for foo
%destructor {baz} "foo"
^^^^^
input.y:5.13-17: previous declaration
%destructor {bar} foo
^^^^^
input.y:9.10-14: error: %printer redeclaration for foo
input.y:9.10-14: error: %printer redeclaration for "foo"
%printer {baz} "foo"
^^^^^
input.y:4.10-14: previous declaration
%printer {bar} foo
^^^^^
input.y:11.1-5: error: %left redeclaration for foo
input.y:10.13-17: error: %destructor redeclaration for "foo"
%destructor {baz} "foo"
^^^^^
input.y:5.13-17: previous declaration
%destructor {bar} foo
^^^^^
input.y:11.1-5: error: %left redeclaration for "foo"
%left "foo"
^^^^^
input.y:6.1-5: previous declaration
+1 -2
View File
@@ -405,14 +405,13 @@ default: 'a' }
AT_BISON_CHECK([input.y], [1], [],
[[input.y:2.1: error: invalid character: '?'
input.y:3.14: error: invalid character: '}'
input.y:3.14: error: syntax error, unexpected }
input.y:4.1: error: invalid character: '%'
input.y:4.2: error: invalid character: '&'
input.y:5.1-17: error: invalid directive: '%a-does-not-exist'
input.y:6.1: error: invalid character: '%'
input.y:6.2: error: invalid character: '-'
input.y:7.1-8.0: error: missing '%}' at end of file
input.y:7.1-8.0: error: syntax error, unexpected %{...%}
]])
AT_CLEANUP