mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-08-15 05:35:14 +00:00
Compare commits
20
Commits
v2.7.91
...
partialorder
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8c9212bbd | ||
|
|
d992a222af | ||
|
|
86a2a43854 | ||
|
|
d8de391c38 | ||
|
|
f8a710c6f4 | ||
|
|
2d8fc07778 | ||
|
|
a910d26cfb | ||
|
|
a728075710 | ||
|
|
c4aa4ff541 | ||
|
|
b97bbbaed7 | ||
|
|
e386b50f26 | ||
|
|
534497f54b | ||
|
|
a62a7b014c | ||
|
|
de1a2f20dd | ||
|
|
afcc58c63e | ||
|
|
d3ae5af6ec | ||
|
|
41dfa1cbf0 | ||
|
|
b7171c45f4 | ||
|
|
ac953ff80a | ||
|
|
facb910cbd |
+1
-1
@@ -1 +1 @@
|
||||
2.7.90
|
||||
3.0
|
||||
|
||||
@@ -1,13 +1,35 @@
|
||||
GNU Bison NEWS
|
||||
|
||||
* Noteworthy changes in release 2.7.91 (2013-06-24) [beta]
|
||||
* Noteworthy changes in release ?.? (????-??-??) [?]
|
||||
|
||||
** Java skeleton improvements
|
||||
** New syntax: partial-order precedence relationships
|
||||
|
||||
The Java skeleton now supports push parsing.
|
||||
Contributed by Dennis Heimbigner.
|
||||
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.
|
||||
|
||||
* Noteworthy changes in release 2.7.90 (2013-05-30) [beta]
|
||||
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!
|
||||
|
||||
@@ -528,6 +550,9 @@ GNU Bison NEWS
|
||||
and "%define init_throws".
|
||||
Contributed by Paolo Bonzini.
|
||||
|
||||
The Java skeleton now supports push parsing.
|
||||
Contributed by Dennis Heimbigner.
|
||||
|
||||
** C++ skeletons improvements
|
||||
|
||||
*** The parser header is no longer mandatory (lalr1.cc, glr.cc)
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Print a version string.
|
||||
scriptversion=2013-05-08.20; # UTC
|
||||
scriptversion=2013-07-03.20; # UTC
|
||||
|
||||
# Bootstrap this package from checked-out sources.
|
||||
|
||||
@@ -256,12 +256,12 @@ esac
|
||||
# Extra files from gnulib, which override files from other sources.
|
||||
test -z "${gnulib_extra_files}" && \
|
||||
gnulib_extra_files="
|
||||
$build_aux/install-sh
|
||||
$build_aux/mdate-sh
|
||||
$build_aux/texinfo.tex
|
||||
$build_aux/depcomp
|
||||
$build_aux/config.guess
|
||||
$build_aux/config.sub
|
||||
build-aux/install-sh
|
||||
build-aux/mdate-sh
|
||||
build-aux/texinfo.tex
|
||||
build-aux/depcomp
|
||||
build-aux/config.guess
|
||||
build-aux/config.sub
|
||||
doc/INSTALL
|
||||
"
|
||||
|
||||
@@ -551,7 +551,7 @@ fi
|
||||
echo "$0: Bootstrapping from checked-out $package sources..."
|
||||
|
||||
# See if we can use gnulib's git-merge-changelog merge driver.
|
||||
if test -d .git && (git --version) >/dev/null 2>/dev/null ; then
|
||||
if $use_git && test -d .git && (git --version) >/dev/null 2>/dev/null ; then
|
||||
if git config merge.merge-changelog.driver >/dev/null ; then
|
||||
:
|
||||
elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; then
|
||||
@@ -574,13 +574,17 @@ git_modules_config () {
|
||||
test -f .gitmodules && git config --file .gitmodules "$@"
|
||||
}
|
||||
|
||||
gnulib_path=$(git_modules_config submodule.gnulib.path)
|
||||
test -z "$gnulib_path" && gnulib_path=gnulib
|
||||
if $use_git; then
|
||||
gnulib_path=$(git_modules_config submodule.gnulib.path)
|
||||
test -z "$gnulib_path" && gnulib_path=gnulib
|
||||
fi
|
||||
|
||||
# Get gnulib files.
|
||||
# Get gnulib files. Populate $GNULIB_SRCDIR, possibly updating a
|
||||
# submodule, for use in the rest of the script.
|
||||
|
||||
case ${GNULIB_SRCDIR--} in
|
||||
-)
|
||||
# Note that $use_git is necessarily true in this case.
|
||||
if git_modules_config submodule.gnulib.url >/dev/null; then
|
||||
echo "$0: getting gnulib files..."
|
||||
git submodule init || exit $?
|
||||
@@ -601,8 +605,8 @@ case ${GNULIB_SRCDIR--} in
|
||||
GNULIB_SRCDIR=$gnulib_path
|
||||
;;
|
||||
*)
|
||||
# Use GNULIB_SRCDIR as a reference.
|
||||
if test -d "$GNULIB_SRCDIR"/.git && \
|
||||
# Use GNULIB_SRCDIR directly or as a reference.
|
||||
if $use_git && test -d "$GNULIB_SRCDIR"/.git && \
|
||||
git_modules_config submodule.gnulib.url >/dev/null; then
|
||||
echo "$0: getting gnulib files..."
|
||||
if git submodule -h|grep -- --reference > /dev/null; then
|
||||
@@ -628,6 +632,9 @@ case ${GNULIB_SRCDIR--} in
|
||||
;;
|
||||
esac
|
||||
|
||||
# $GNULIB_SRCDIR now points to the version of gnulib to use, and
|
||||
# we no longer need to use git or $gnulib_path below here.
|
||||
|
||||
if $bootstrap_sync; then
|
||||
cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || {
|
||||
echo "$0: updating bootstrap and restarting..."
|
||||
|
||||
@@ -221,6 +221,25 @@ m4_define([b4_attribute_define],
|
||||
#else
|
||||
# define YYUSE(E) /* empty */
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
|
||||
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
|
||||
_Pragma ("GCC diagnostic push") \
|
||||
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
|
||||
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
|
||||
_Pragma ("GCC diagnostic pop")
|
||||
#else
|
||||
# define YY_INITIAL_VALUE(Value) Value
|
||||
#endif
|
||||
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_END
|
||||
#endif
|
||||
#ifndef YY_INITIAL_VALUE
|
||||
# define YY_INITIAL_VALUE(Value) /* Nothing. */
|
||||
#endif
|
||||
])
|
||||
|
||||
|
||||
@@ -446,7 +465,9 @@ m4_ifset([b4_parse_param], [, b4_parse_param]))[
|
||||
yymsg = "Deleting";
|
||||
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
|
||||
|
||||
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||
]b4_symbol_actions([destructor])[
|
||||
YY_IGNORE_MAYBE_UNINITIALIZED_END
|
||||
}]dnl
|
||||
])
|
||||
|
||||
@@ -456,9 +477,9 @@ m4_ifset([b4_parse_param], [, b4_parse_param]))[
|
||||
# Define the "yy_symbol_print" function.
|
||||
m4_define_default([b4_yy_symbol_print_define],
|
||||
[[
|
||||
/*--------------------------------.
|
||||
| Print this symbol on YYOUTPUT. |
|
||||
`--------------------------------*/
|
||||
/*----------------------------------------.
|
||||
| Print this symbol's value on YYOUTPUT. |
|
||||
`----------------------------------------*/
|
||||
|
||||
]b4_function_define([yy_symbol_value_print],
|
||||
[static void],
|
||||
|
||||
+9
-26
@@ -175,36 +175,19 @@ m4_define([b4_declare_scanner_communication_variables], [[
|
||||
int yychar;
|
||||
|
||||
]b4_pure_if([[
|
||||
#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
|
||||
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
|
||||
_Pragma ("GCC diagnostic push") \
|
||||
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
|
||||
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
|
||||
_Pragma ("GCC diagnostic pop")
|
||||
#else
|
||||
/* The semantic value of the lookahead symbol. */
|
||||
/* Default value used for initialization, for pacifying older GCCs
|
||||
or non-GCC compilers. */
|
||||
static YYSTYPE yyval_default;
|
||||
# define YY_INITIAL_VALUE(Value) = Value
|
||||
#endif]b4_locations_if([[
|
||||
static YYLTYPE yyloc_default][]b4_yyloc_default[;]])])[
|
||||
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||
# define YY_IGNORE_MAYBE_UNINITIALIZED_END
|
||||
#endif
|
||||
#ifndef YY_INITIAL_VALUE
|
||||
# define YY_INITIAL_VALUE(Value) /* Nothing. */
|
||||
#endif
|
||||
|
||||
/* The semantic value of the lookahead symbol. */
|
||||
YYSTYPE yylval YY_INITIAL_VALUE (yyval_default);]b4_locations_if([[
|
||||
YY_INITIAL_VALUE (static YYSTYPE yyval_default;)
|
||||
YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);]b4_locations_if([[
|
||||
|
||||
/* Location data for the lookahead symbol. */
|
||||
YYLTYPE yylloc]b4_pure_if([ = yyloc_default], [b4_yyloc_default])[;
|
||||
]])b4_pure_if([], [[
|
||||
|
||||
static YYLTYPE yyloc_default]b4_yyloc_default[;
|
||||
YYLTYPE yylloc = yyloc_default;]])],
|
||||
[[/* The semantic value of the lookahead symbol. */
|
||||
YYSTYPE yylval;]b4_locations_if([[
|
||||
/* Location data for the lookahead symbol. */
|
||||
YYLTYPE yylloc]b4_yyloc_default[;]])[
|
||||
/* Number of syntax errors so far. */
|
||||
int yynerrs;]])])
|
||||
|
||||
|
||||
@@ -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!
|
||||
+14
-13
@@ -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
|
||||
EXTRA_DIST += \
|
||||
$(FIGS_DOT) \
|
||||
$(FIGS_DOT:.dot=.eps) $(FIGS_DOT:.dot=.pdf) $(FIGS_DOT:.dot=.png)
|
||||
SUFFIXES += .dot .eps .pdf .png
|
||||
FIGS_GV = \
|
||||
doc/figs/example.gv \
|
||||
doc/figs/example-reduce.gv doc/figs/example-shift.gv
|
||||
EXTRA_DIST += \
|
||||
$(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 $@
|
||||
|
||||
+1
-1
Submodule gnulib updated: e28fbd787c...03e96cc338
@@ -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. */
|
||||
|
||||
+81
-60
@@ -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 < %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 < %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:
|
||||
@@ -203,7 +212,13 @@ log_resolution (rule *r, symbol_number token,
|
||||
obstack_printf (&solved_conflicts_xml_obstack,
|
||||
"%%nonassoc %s",
|
||||
xml_escape (symbols[token]->tag));
|
||||
break;
|
||||
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,66 +277,73 @@ 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))
|
||||
{
|
||||
/* 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 (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)
|
||||
{
|
||||
register_precedence (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, shift_resolution);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
/* Shift-reduce conflict occurs for token number i
|
||||
and it has a precedence.
|
||||
The precedence of shifting is that of token i. */
|
||||
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 (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 if (is_prec_equal (redprecsym, symbols[i]->content->prec_node))
|
||||
/* Matching precedence levels.
|
||||
For non-defined associativity, keep both: unexpected
|
||||
associativity conflict.
|
||||
For left associativity, keep only the reduction.
|
||||
For right associativity, keep only the shift.
|
||||
For nonassociativity, keep neither. */
|
||||
|
||||
switch (symbols[i]->content->prec_node->assoc)
|
||||
{
|
||||
case undef_assoc:
|
||||
break;
|
||||
|
||||
case precedence_assoc:
|
||||
break;
|
||||
|
||||
case right_assoc:
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, right_resolution);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
break;
|
||||
|
||||
case left_assoc:
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, left_resolution);
|
||||
flush_shift (s, i);
|
||||
break;
|
||||
|
||||
case non_assoc:
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, nonassoc_resolution);
|
||||
flush_shift (s, i);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
/* Record an explicit error for this token. */
|
||||
errors[(*nerrs)++] = symbols[i];
|
||||
break;
|
||||
}
|
||||
else
|
||||
log_resolution (redrule, i, uncomparable_resolution);
|
||||
}
|
||||
else
|
||||
/* Matching precedence levels.
|
||||
For non-defined associativity, keep both: unexpected
|
||||
associativity conflict.
|
||||
For left associativity, keep only the reduction.
|
||||
For right associativity, keep only the shift.
|
||||
For nonassociativity, keep neither. */
|
||||
|
||||
switch (symbols[i]->assoc)
|
||||
{
|
||||
case undef_assoc:
|
||||
abort ();
|
||||
|
||||
case precedence_assoc:
|
||||
break;
|
||||
|
||||
case right_assoc:
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, right_resolution);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
break;
|
||||
|
||||
case left_assoc:
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, left_resolution);
|
||||
flush_shift (s, i);
|
||||
break;
|
||||
|
||||
case non_assoc:
|
||||
register_assoc (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, nonassoc_resolution);
|
||||
flush_shift (s, i);
|
||||
flush_reduce (lookahead_tokens, i);
|
||||
/* Record an explicit error for this token. */
|
||||
errors[(*nerrs)++] = symbols[i];
|
||||
break;
|
||||
}
|
||||
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
+795
-659
File diff suppressed because it is too large
Load Diff
+67
-60
@@ -1,4 +1,4 @@
|
||||
/* A Bison parser, made by GNU Bison 2.7.90. */
|
||||
/* A Bison parser, made by GNU Bison 3.0. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
@@ -48,11 +48,11 @@
|
||||
extern int gram_debug;
|
||||
#endif
|
||||
/* "%code requires" blocks. */
|
||||
#line 21 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
#line 21 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
|
||||
#include "symlist.h"
|
||||
#include "symtab.h"
|
||||
#line 221 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
#line 233 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -61,10 +61,10 @@ extern int gram_debug;
|
||||
param_parse = 1 << 1,
|
||||
param_both = param_lex | param_parse
|
||||
} param_type;
|
||||
#line 645 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
#line 723 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
#include "muscle-tab.h"
|
||||
|
||||
#line 68 "src/parse-gram.h" /* yacc.c:1926 */
|
||||
#line 68 "src/parse-gram.h" /* yacc.c:1909 */
|
||||
|
||||
/* Token type. */
|
||||
#ifndef GRAM_TOKENTYPE
|
||||
@@ -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:1926 */
|
||||
#line 187 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
unsigned char character;
|
||||
#line 186 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
#line 191 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
char *code;
|
||||
#line 191 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
#line 196 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
uniqstr uniqstr;
|
||||
#line 199 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
#line 204 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
int integer;
|
||||
#line 203 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
#line 208 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
symbol *symbol;
|
||||
#line 208 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
#line 213 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
assoc assoc;
|
||||
#line 211 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
#line 216 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
symbol_list *list;
|
||||
#line 214 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
#line 219 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
named_ref *named_ref;
|
||||
#line 241 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
#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:1926 */
|
||||
#line 423 "src/parse-gram.y" /* yacc.c:1909 */
|
||||
code_props_type code_type;
|
||||
#line 647 "src/parse-gram.y" /* yacc.c:1926 */
|
||||
#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:1926 */
|
||||
#line 174 "src/parse-gram.h" /* yacc.c:1909 */
|
||||
};
|
||||
# define GRAM_STYPE_IS_TRIVIAL 1
|
||||
# define GRAM_STYPE_IS_DECLARED 1
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
+607
-157
File diff suppressed because it is too large
Load Diff
+114
-8
@@ -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
@@ -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
|
||||
|
||||
@@ -50,6 +50,37 @@ CXXFLAGS="$NO_WERROR_CXXFLAGS @WERROR_CXXFLAGS@"
|
||||
# If 'exit 77'; skip all C++ tests; otherwise ':'.
|
||||
BISON_CXX_WORKS='@BISON_CXX_WORKS@'
|
||||
|
||||
# Be sure that the C++ compiler is not broken because of gnulib. This
|
||||
# cannot be checked in configure (gnulib is not parameterized yet),
|
||||
# and checking this in every C++ test in AC_COMPILE_CXX is too costly.
|
||||
#
|
||||
# http://lists.gnu.org/archive/html/bug-bison/2013-06/msg00001.html
|
||||
#
|
||||
# FIXME: Check (say 2014) whether this is still needed.
|
||||
if $BISON_CXX_WORKS; then
|
||||
# See AT_DATA_SOURCE_PROLOGUE.
|
||||
cat >conftest.cc <<EOF
|
||||
#include <config.h>
|
||||
/* We don't need perfect functions for these tests. */
|
||||
#undef malloc
|
||||
#undef memcmp
|
||||
#undef realloc
|
||||
#include <iostream>
|
||||
|
||||
int main ()
|
||||
{
|
||||
std::cout << "Works" << std::endl;
|
||||
}
|
||||
EOF
|
||||
ls
|
||||
$CXX $CXXFLAGS $CPPFLAGS $LDFLAGS $LIBS -o conftest conftest.cc
|
||||
case $? in
|
||||
0);;
|
||||
*) BISON_CXX_WORKS="as_fn_error 77 cannot-compile-simple-program";;
|
||||
esac
|
||||
rm -f conftest*
|
||||
fi
|
||||
|
||||
# Whether the compiler supports POSIXLY_CORRECT defined.
|
||||
: ${C_COMPILER_POSIXLY_CORRECT='@C_COMPILER_POSIXLY_CORRECT@'}
|
||||
: ${CXX_COMPILER_POSIXLY_CORRECT='@CXX_COMPILER_POSIXLY_CORRECT@'}
|
||||
|
||||
+3
-3
@@ -795,11 +795,11 @@ item:
|
||||
// Not just 'E', otherwise we reduce when 'E' is the lookahead, and
|
||||
// then the stack is emptied, defeating the point of the test.
|
||||
| 'E' 'a' { YYUSE($][1); $][$ = $][2; }
|
||||
| 'R' { $][$ = YY_NULL; ]AT_VARIANT_IF([], [delete $][1]; )[YYERROR; }
|
||||
| 'R' { ]AT_VARIANT_IF([], [$][$ = YY_NULL; delete $][1]; )[YYERROR; }
|
||||
| 'p' { $][$ = $][1; }
|
||||
| 's' { $][$ = $][1; throw std::runtime_error ("reduction"); }
|
||||
| 'T' { $][$ = YY_NULL; ]AT_VARIANT_IF([], [delete $][1]; )[YYABORT; }
|
||||
| error { $][$ = YY_NULL; yyerrok; }
|
||||
| 'T' { ]AT_VARIANT_IF([], [$][$ = YY_NULL; delete $][1]; )[YYABORT; }
|
||||
| error { ]AT_VARIANT_IF([], [$][$ = YY_NULL; ])[yyerrok; }
|
||||
;
|
||||
%%
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
+4
-3
@@ -339,9 +339,9 @@ m4_define([AT_LANG_DISPATCH],
|
||||
|
||||
|
||||
# AT_DATA_SOURCE_PROLOGUE
|
||||
# ------------------------
|
||||
# -----------------------
|
||||
# The prologue that should be included in any source code that is
|
||||
# meant to be compiled.
|
||||
# meant to be compiled. Keep atlocal.in sync (BISON_CXX_WORKS).
|
||||
m4_define([AT_DATA_SOURCE_PROLOGUE],
|
||||
[[#include <config.h>
|
||||
/* We don't need perfect functions for these tests. */
|
||||
@@ -754,6 +754,7 @@ AT_CHECK(m4_join([ ],
|
||||
[m4_bmatch([$1], [[.]], [], [$LIBS])]),
|
||||
0, [ignore], [ignore])])
|
||||
|
||||
|
||||
# AT_COMPILE_CXX(OUTPUT, [SOURCES = OUTPUT.cc])
|
||||
# ---------------------------------------------
|
||||
# Compile SOURCES into OUTPUT. If the C++ compiler does not work,
|
||||
@@ -761,7 +762,7 @@ AT_CHECK(m4_join([ ],
|
||||
#
|
||||
# If OUTPUT does not contain '.', assume that we are linking too,
|
||||
# otherwise pass "-c"; this is a hack. The default SOURCES is OUTPUT
|
||||
# with trailing .o removed, and ".cc" appended.
|
||||
# with trailing ".o" removed, and ".cc" appended.
|
||||
m4_define([AT_COMPILE_CXX],
|
||||
[AT_KEYWORDS(c++)
|
||||
AT_CHECK([$BISON_CXX_WORKS], 0, ignore, ignore)
|
||||
|
||||
+5
-4
@@ -37,10 +37,11 @@ foo: {};
|
||||
|
||||
]AT_BISON_CHECK([$3 $1 $5], 0)[
|
||||
# Ignore the files non-generated files
|
||||
]AT_CHECK([find . -type f -and -not -path './$1' -and -not -path './testsuite.log' |
|
||||
sed 's,\./,,' |
|
||||
sort |
|
||||
xargs echo],
|
||||
]AT_CHECK([[find . -type f |
|
||||
$PERL -ne '
|
||||
s,\./,,; chomp;
|
||||
push @file, $_ unless m{^($1|testsuite.log)$};
|
||||
END { print join (" ", sort @file), "\n" }']],
|
||||
[], [$4
|
||||
])[
|
||||
]$6[
|
||||
|
||||
+1
-2
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user