mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-08-16 06:05:14 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d8565537b | ||
|
|
d6445ec10b | ||
|
|
7ca7a3abf3 | ||
|
|
eabb3df7aa | ||
|
|
875ef1b90c | ||
|
|
650af77812 | ||
|
|
c03a8db0cc | ||
|
|
8b06c6b871 | ||
|
|
c5da1a2adc | ||
|
|
dfd5b89d01 | ||
|
|
13e294ee55 | ||
|
|
8044fda634 | ||
|
|
b7d4c48e55 | ||
|
|
fc6c85664a | ||
|
|
4f3cc9c21b | ||
|
|
55a2063005 | ||
|
|
a728075710 |
+1
-1
@@ -1 +1 @@
|
|||||||
3.0.3
|
3.0.4
|
||||||
|
|||||||
@@ -1,5 +1,50 @@
|
|||||||
GNU Bison NEWS
|
GNU Bison NEWS
|
||||||
|
|
||||||
|
* Noteworthy changes in release ?.? (????-??-??) [?]
|
||||||
|
|
||||||
|
** Diagnostics about useless rules
|
||||||
|
|
||||||
|
In the following grammar, the 'exp' nonterminal is trivially useless. So,
|
||||||
|
of course, its rules are useless too.
|
||||||
|
|
||||||
|
%%
|
||||||
|
input: '0' | exp
|
||||||
|
exp: exp '+' exp | exp '-' exp | '(' exp ')'
|
||||||
|
|
||||||
|
Previously all the useless rules were reported, including those whose
|
||||||
|
left-hand side is the 'exp' nonterminal:
|
||||||
|
|
||||||
|
warning: 1 nonterminal useless in grammar [-Wother]
|
||||||
|
warning: 4 rules useless in grammar [-Wother]
|
||||||
|
2.14-16: warning: nonterminal useless in grammar: exp [-Wother]
|
||||||
|
input: '0' | exp
|
||||||
|
^^^
|
||||||
|
2.14-16: warning: rule useless in grammar [-Wother]
|
||||||
|
input: '0' | exp
|
||||||
|
^^^
|
||||||
|
3.6-16: warning: rule useless in grammar [-Wother]
|
||||||
|
exp: exp '+' exp | exp '-' exp | '(' exp ')'
|
||||||
|
^^^^^^^^^^^
|
||||||
|
3.20-30: warning: rule useless in grammar [-Wother]
|
||||||
|
exp: exp '+' exp | exp '-' exp | '(' exp ')'
|
||||||
|
^^^^^^^^^^^
|
||||||
|
3.34-44: warning: rule useless in grammar [-Wother]
|
||||||
|
exp: exp '+' exp | exp '-' exp | '(' exp ')'
|
||||||
|
^^^^^^^^^^^
|
||||||
|
|
||||||
|
Now, rules whose left-hand side symbol is useless are no longer reported
|
||||||
|
as useless. The locations of the errors have also been adjusted to point
|
||||||
|
to the first use of the nonterminal as a left-hand side of a rule:
|
||||||
|
|
||||||
|
warning: 1 nonterminal useless in grammar [-Wother]
|
||||||
|
warning: 4 rules useless in grammar [-Wother]
|
||||||
|
3.1-3: warning: nonterminal useless in grammar: exp [-Wother]
|
||||||
|
exp: exp '+' exp | exp '-' exp | '(' exp ')'
|
||||||
|
^^^
|
||||||
|
2.14-16: warning: rule useless in grammar [-Wother]
|
||||||
|
input: '0' | exp
|
||||||
|
^^^
|
||||||
|
|
||||||
* Noteworthy changes in release 3.0.4 (2015-01-23) [stable]
|
* Noteworthy changes in release 3.0.4 (2015-01-23) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
|
|||||||
+4
-15
@@ -1692,7 +1692,7 @@ yyreportAmbiguity (yySemanticOption* yyx0,
|
|||||||
* ending at YYS1. Has no effect on previously resolved states.
|
* ending at YYS1. Has no effect on previously resolved states.
|
||||||
* The first semantic option of a state is always chosen. */
|
* The first semantic option of a state is always chosen. */
|
||||||
static void
|
static void
|
||||||
yyresolveLocations (yyGLRState* yys1, int yyn1,
|
yyresolveLocations (yyGLRState *yys1, int yyn1,
|
||||||
yyGLRStack *yystackp]b4_user_formals[)
|
yyGLRStack *yystackp]b4_user_formals[)
|
||||||
{
|
{
|
||||||
if (0 < yyn1)
|
if (0 < yyn1)
|
||||||
@@ -1703,9 +1703,9 @@ yyresolveLocations (yyGLRState* yys1, int yyn1,
|
|||||||
yyGLRStackItem yyrhsloc[1 + YYMAXRHS];
|
yyGLRStackItem yyrhsloc[1 + YYMAXRHS];
|
||||||
int yynrhs;
|
int yynrhs;
|
||||||
yySemanticOption *yyoption = yys1->yysemantics.yyfirstVal;
|
yySemanticOption *yyoption = yys1->yysemantics.yyfirstVal;
|
||||||
YYASSERT (yyoption != YY_NULLPTR);
|
YYASSERT (yyoption);
|
||||||
yynrhs = yyrhsLength (yyoption->yyrule);
|
yynrhs = yyrhsLength (yyoption->yyrule);
|
||||||
if (yynrhs > 0)
|
if (0 < yynrhs)
|
||||||
{
|
{
|
||||||
yyGLRState *yys;
|
yyGLRState *yys;
|
||||||
int yyn;
|
int yyn;
|
||||||
@@ -1728,18 +1728,7 @@ yyresolveLocations (yyGLRState* yys1, int yyn1,
|
|||||||
yyGLRState *yyprevious = yyoption->yystate;
|
yyGLRState *yyprevious = yyoption->yystate;
|
||||||
yyrhsloc[0].yystate.yyloc = yyprevious->yyloc;
|
yyrhsloc[0].yystate.yyloc = yyprevious->yyloc;
|
||||||
}
|
}
|
||||||
{
|
YYLLOC_DEFAULT ((yys1->yyloc), yyrhsloc, yynrhs);
|
||||||
int yychar_current = yychar;
|
|
||||||
YYSTYPE yylval_current = yylval;
|
|
||||||
YYLTYPE yylloc_current = yylloc;
|
|
||||||
yychar = yyoption->yyrawchar;
|
|
||||||
yylval = yyoption->yyval;
|
|
||||||
yylloc = yyoption->yyloc;
|
|
||||||
YYLLOC_DEFAULT ((yys1->yyloc), yyrhsloc, yynrhs);
|
|
||||||
yychar = yychar_current;
|
|
||||||
yylval = yylval_current;
|
|
||||||
yylloc = yylloc_current;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}]])[
|
}]])[
|
||||||
|
|||||||
+319
-12
@@ -52,6 +52,8 @@ m4_define([b4_lac_flag],
|
|||||||
[none], [[0]], [[1]])])
|
[none], [[0]], [[1]])])
|
||||||
|
|
||||||
m4_include(b4_pkgdatadir/[c.m4])
|
m4_include(b4_pkgdatadir/[c.m4])
|
||||||
|
m4_define([b4_yaxx],[$1])
|
||||||
|
m4_define([b4_not_yaxx],[])
|
||||||
|
|
||||||
## ---------------- ##
|
## ---------------- ##
|
||||||
## Default values. ##
|
## Default values. ##
|
||||||
@@ -331,7 +333,11 @@ m4_if(b4_api_prefix, [yy], [],
|
|||||||
#define yydebug ]b4_prefix[debug
|
#define yydebug ]b4_prefix[debug
|
||||||
#define yynerrs ]b4_prefix[nerrs
|
#define yynerrs ]b4_prefix[nerrs
|
||||||
]]b4_pure_if([], [[
|
]]b4_pure_if([], [[
|
||||||
#define yylval ]b4_prefix[lval
|
#define yylval ]b4_prefix[lval]b4_yaxx([
|
||||||
|
#define yytext ]b4_prefix[text
|
||||||
|
#define YYYAXX_XML "b4_prefix[]yaxx.xml"
|
||||||
|
#define YYYAXX_DTD "b4_prefix[]yaxx.dtd"
|
||||||
|
])[
|
||||||
#define yychar ]b4_prefix[char]b4_locations_if([[
|
#define yychar ]b4_prefix[char]b4_locations_if([[
|
||||||
#define yylloc ]b4_prefix[lloc]])]))[
|
#define yylloc ]b4_prefix[lloc]])]))[
|
||||||
|
|
||||||
@@ -420,6 +426,10 @@ typedef short int yytype_int16;
|
|||||||
/* The parser invokes alloca or malloc; define the necessary symbols. */]dnl
|
/* The parser invokes alloca or malloc; define the necessary symbols. */]dnl
|
||||||
b4_push_if([], [b4_lac_if([], [[
|
b4_push_if([], [b4_lac_if([], [[
|
||||||
|
|
||||||
|
]b4_yaxx([
|
||||||
|
#define XML_ALLOC(X) malloc(X)
|
||||||
|
#define XML_FREE(X) free(X)
|
||||||
|
])[
|
||||||
# ifdef YYSTACK_USE_ALLOCA
|
# ifdef YYSTACK_USE_ALLOCA
|
||||||
# if YYSTACK_USE_ALLOCA
|
# if YYSTACK_USE_ALLOCA
|
||||||
# ifdef __GNUC__
|
# ifdef __GNUC__
|
||||||
@@ -494,7 +504,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
|
|||||||
union yyalloc
|
union yyalloc
|
||||||
{
|
{
|
||||||
yytype_int16 yyss_alloc;
|
yytype_int16 yyss_alloc;
|
||||||
YYSTYPE yyvs_alloc;]b4_locations_if([
|
YYSTYPE yyvs_alloc;]b4_yaxx([char *yyxs_alloc;])[]b4_locations_if([
|
||||||
YYLTYPE yyls_alloc;])[
|
YYLTYPE yyls_alloc;])[
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -505,10 +515,10 @@ union yyalloc
|
|||||||
N elements. */
|
N elements. */
|
||||||
]b4_locations_if(
|
]b4_locations_if(
|
||||||
[# define YYSTACK_BYTES(N) \
|
[# define YYSTACK_BYTES(N) \
|
||||||
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
|
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE) ]b4_yaxx([+ sizeof(char*) ])[) \
|
||||||
+ 2 * YYSTACK_GAP_MAXIMUM)],
|
+ 2 * YYSTACK_GAP_MAXIMUM)],
|
||||||
[# define YYSTACK_BYTES(N) \
|
[# define YYSTACK_BYTES(N) \
|
||||||
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
|
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) ]b4_yaxx([+ sizeof(char*) ])[) \
|
||||||
+ YYSTACK_GAP_MAXIMUM)])[
|
+ YYSTACK_GAP_MAXIMUM)])[
|
||||||
|
|
||||||
# define YYCOPY_NEEDED 1
|
# define YYCOPY_NEEDED 1
|
||||||
@@ -580,19 +590,27 @@ static const ]b4_int_type_for([b4_translate])[ yytranslate[] =
|
|||||||
]b4_translate[
|
]b4_translate[
|
||||||
};
|
};
|
||||||
|
|
||||||
|
]b4_not_yaxx([
|
||||||
#if ]b4_api_PREFIX[DEBUG
|
#if ]b4_api_PREFIX[DEBUG
|
||||||
|
])[
|
||||||
]b4_integral_parser_table_define([rline], [b4_rline],
|
]b4_integral_parser_table_define([rline], [b4_rline],
|
||||||
[[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
|
[[YYRLINE[YYN] -- Source line where rule number YYN was defined.]])[
|
||||||
|
]b4_not_yaxx([
|
||||||
#endif
|
#endif
|
||||||
|
])[
|
||||||
|
|
||||||
|
]b4_not_yaxx([
|
||||||
#if ]b4_api_PREFIX[DEBUG || YYERROR_VERBOSE || ]b4_token_table_flag[
|
#if ]b4_api_PREFIX[DEBUG || YYERROR_VERBOSE || ]b4_token_table_flag[
|
||||||
|
])[
|
||||||
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
|
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
|
||||||
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
|
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
|
||||||
static const char *const yytname[] =
|
static const char *const yytname[] =
|
||||||
{
|
{
|
||||||
]b4_tname[
|
]b4_tname[
|
||||||
};
|
};
|
||||||
|
]b4_not_yaxx([
|
||||||
#endif
|
#endif
|
||||||
|
])
|
||||||
|
|
||||||
# ifdef YYPRINT
|
# ifdef YYPRINT
|
||||||
/* YYTOKNUM[NUM] -- (External) token number corresponding to the
|
/* YYTOKNUM[NUM] -- (External) token number corresponding to the
|
||||||
@@ -1366,7 +1384,194 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
|
|||||||
[[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([,
|
[[[YYSTYPE const *yypushed_val]], [[yypushed_val]]]b4_locations_if([,
|
||||||
[[[YYLTYPE *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [,
|
[[[YYLTYPE *yypushed_loc]], [[yypushed_loc]]]])])m4_ifset([b4_parse_param], [,
|
||||||
b4_parse_param]))], [[
|
b4_parse_param]))], [[
|
||||||
|
]b4_yaxx([
|
||||||
|
extern char *b4_prefix[]text;
|
||||||
|
// Yijun Yu: utility functions -----------------------------------------------
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
/// replace character terminals into symbolic terminals
|
||||||
|
static char *YYTNAME(int r)
|
||||||
|
{
|
||||||
|
static char yytname_buf[[8]];
|
||||||
|
if (strlen(yytname[[r]])==3 && yytname[[r]][[0]] == '\'' && yytname[[r]][[2]] == '\'')
|
||||||
|
{
|
||||||
|
sprintf(yytname_buf, "CHAR%d", (int)yytname[[r]][[1]]);
|
||||||
|
return yytname_buf;
|
||||||
|
}
|
||||||
|
else if (strlen(yytname[[r]])>=2 && yytname[[r]][[0]] == 64 )
|
||||||
|
{
|
||||||
|
strcpy(yytname_buf,"ACTION");
|
||||||
|
strcat(yytname_buf,&(yytname[[r]][[1]]));
|
||||||
|
return yytname_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (char *)yytname[[r]];
|
||||||
|
}
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
static char *yytext_buf = NULL;
|
||||||
|
|
||||||
|
/// replace a special character in the text into an entity
|
||||||
|
static
|
||||||
|
void replace_entity(char c, char *s)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
char *i;
|
||||||
|
int len, l;
|
||||||
|
i = yytext_buf;
|
||||||
|
do {
|
||||||
|
i = (char *)index(i, c);
|
||||||
|
if (i) {
|
||||||
|
l = i - yytext_buf;
|
||||||
|
len = strlen(yytext_buf) + strlen(s) - 1;
|
||||||
|
//buf = (char*)YYSTACK_ALLOC(1000000);
|
||||||
|
buf = (char*)YYSTACK_ALLOC(len + 1); // Myo M Thein
|
||||||
|
if (l>0) {
|
||||||
|
#if 1 // Myo M Thein
|
||||||
|
strncpy(buf, yytext_buf, l);
|
||||||
|
#else
|
||||||
|
int t = 0;
|
||||||
|
while (t < l) {
|
||||||
|
buf[t] = yytext_buf[t];
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
buf[t] = 0;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
buf[[0]] = 0;
|
||||||
|
}
|
||||||
|
strcat(buf, s);
|
||||||
|
strncat(buf, yytext_buf + l + 1, strlen(yytext_buf) - l);
|
||||||
|
buf[[len]] = 0;
|
||||||
|
YYSTACK_FREE(yytext_buf);
|
||||||
|
//yytext_buf = buf;
|
||||||
|
memcpy(yytext_buf,buf,len+1);
|
||||||
|
i++;
|
||||||
|
if (*i=='\0')
|
||||||
|
i=NULL;
|
||||||
|
}
|
||||||
|
} while (i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// replace the special characters in the text into entities
|
||||||
|
static
|
||||||
|
char* xml_encode( char ch)
|
||||||
|
{
|
||||||
|
static char text[[2]];
|
||||||
|
switch(ch)
|
||||||
|
{
|
||||||
|
case '&':
|
||||||
|
return ( "&");
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
return ( ">");
|
||||||
|
break;
|
||||||
|
case '<' :
|
||||||
|
return ( "<" );
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
return ( """);
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
return ( "'");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
text[[0]]=ch;
|
||||||
|
text[[1]]=0;
|
||||||
|
return text;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void replace_special_entities(char *text,char *text_out)
|
||||||
|
{
|
||||||
|
int i,lg;
|
||||||
|
if (!text) { strcpy(text_out,"??");return ; }
|
||||||
|
lg = strlen(text);
|
||||||
|
strcpy(text_out,"");
|
||||||
|
for (i=0;i<lg;i++)
|
||||||
|
{
|
||||||
|
strcat(text_out,xml_encode(text[[i]]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static
|
||||||
|
void generate_xml_output(char **yyxsp,char **yyxs)
|
||||||
|
{
|
||||||
|
#ifndef YYYAXX_XML
|
||||||
|
#define YYYAXX_XML "yaxx.xml"
|
||||||
|
#endif
|
||||||
|
#ifndef YYYAXX_DTD
|
||||||
|
#define YYYAXX_DTD "yaxx.dtd"
|
||||||
|
#endif
|
||||||
|
int r, i, j;
|
||||||
|
char buf[[2000]];
|
||||||
|
int old_rule = 0;
|
||||||
|
FILE *stdout = fopen(YYYAXX_XML, "w");
|
||||||
|
char *p = *yyxsp + 6;
|
||||||
|
#if 0
|
||||||
|
char *v = strsep(&p, ">");
|
||||||
|
strcpy(buf, v);
|
||||||
|
#else
|
||||||
|
i = 0;
|
||||||
|
while (p[[i]]!='>') {
|
||||||
|
buf[[i]] = p[[i]];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
buf[[i]] = 0;
|
||||||
|
#endif
|
||||||
|
/// Generating the XML document
|
||||||
|
/// version
|
||||||
|
fprintf(stdout,"<?xml version=\"1.0\"?>\n");
|
||||||
|
/// DTD reference
|
||||||
|
fprintf(stdout,"<?xml-stylesheet type=\"text/xsl\" href=\"yaxx.xsl\"?>");
|
||||||
|
fprintf(stdout,"<!DOCTYPE %s SYSTEM \"" YYYAXX_DTD "\">\n", buf);
|
||||||
|
/// inserting name space before the XML data
|
||||||
|
fprintf(stdout,"<yaxx:%s xmlns:yaxx=\"urn:YAcc-Xml-eXtension\"%s\n", buf,
|
||||||
|
yyxs[[1]]+i+6); //ffprintf(stdout,f, "%s\n", yyxs[[1]]);
|
||||||
|
/// Generating the document type definition (DTD)
|
||||||
|
stdout = fopen(YYYAXX_DTD , "w");
|
||||||
|
/// DTD for non-terminals
|
||||||
|
for (r = 2; r < sizeof(yyr1)/sizeof(unsigned short); r++)
|
||||||
|
{
|
||||||
|
j = yyr1[[r]];
|
||||||
|
if (j != old_rule) {
|
||||||
|
if (old_rule!=0)
|
||||||
|
fprintf(stdout,")>\n");
|
||||||
|
fprintf(stdout,"<!ELEMENT %s (", YYTNAME(yyr1[[r]]));
|
||||||
|
} else
|
||||||
|
fprintf(stdout," | ");
|
||||||
|
if (yyr2[[r]]==0)
|
||||||
|
fprintf(stdout,"EMPTY");
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
int multiple = 0;
|
||||||
|
for (i = yyprhs[[r]]; yyrhs[[i]] > 0 ; i++)
|
||||||
|
if (i!=yyprhs[[r]]) {
|
||||||
|
multiple = 1; break;
|
||||||
|
}
|
||||||
|
if (multiple) fprintf(stdout,"(");
|
||||||
|
for (i = yyprhs[[r]]; yyrhs[[i]] > 0 ; i++) {
|
||||||
|
if (i!=yyprhs[[r]])
|
||||||
|
fprintf(stdout,",");
|
||||||
|
fprintf(stdout,"%s", YYTNAME(yyrhs[[i]]));
|
||||||
|
}
|
||||||
|
if (multiple) fprintf(stdout,")");
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
old_rule = j;
|
||||||
|
}
|
||||||
|
fprintf(stdout,")>\n");
|
||||||
|
/// DTD for terminals
|
||||||
|
for (r = 3; r < YYNTOKENS; r++)
|
||||||
|
{
|
||||||
|
fprintf(stdout,"<!ELEMENT %s (#PCDATA)>\n", YYTNAME(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
])[
|
||||||
|
|
||||||
/*----------.
|
/*----------.
|
||||||
| yyparse. |
|
| yyparse. |
|
||||||
@@ -1398,7 +1603,26 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
|
|||||||
YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
|
YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
]b4_yaxx([
|
||||||
|
|
||||||
|
/* The tags stack. */
|
||||||
|
char *yyxsa[[YYINITDEPTH]];
|
||||||
|
char **yyxs = yyxsa;
|
||||||
|
char **yyxsp;
|
||||||
|
])[
|
||||||
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)]b4_locations_if([, yylsp -= (N)])[)
|
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)]b4_locations_if([, yylsp -= (N)])[)
|
||||||
|
]b4_yaxx([
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#undef __GNUC_PREREQ
|
||||||
|
#define __GNUC_PREREQ(maj, min) (maj < 4)
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
static char * yyxml_str=NULL; // for XML
|
||||||
|
// for id attribute generation (by William Candillon)
|
||||||
|
int _id = 0;
|
||||||
|
char str[[256]];
|
||||||
|
])[
|
||||||
|
|
||||||
/* The number of symbols on the RHS of the reduced rule.
|
/* The number of symbols on the RHS of the reduced rule.
|
||||||
Keep to zero when no symbol should be popped. */
|
Keep to zero when no symbol should be popped. */
|
||||||
@@ -1410,7 +1634,9 @@ b4_function_define([[yyparse]], [[int]], b4_parse_param)[
|
|||||||
goto yyread_pushed_token;
|
goto yyread_pushed_token;
|
||||||
}]])[
|
}]])[
|
||||||
|
|
||||||
yyssp = yyss = yyssa;
|
yyssp = yyss = yyssa;]b4_yaxx([
|
||||||
|
yyxsp = yyxs = yyxsa;
|
||||||
|
])[
|
||||||
yyvsp = yyvs = yyvsa;]b4_locations_if([[
|
yyvsp = yyvs = yyvsa;]b4_locations_if([[
|
||||||
yylsp = yyls = yylsa;]])[
|
yylsp = yyls = yylsa;]])[
|
||||||
yystacksize = YYINITDEPTH;]b4_lac_if([[
|
yystacksize = YYINITDEPTH;]b4_lac_if([[
|
||||||
@@ -1460,7 +1686,7 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
|
|||||||
these so that the &'s don't force the real ones into
|
these so that the &'s don't force the real ones into
|
||||||
memory. */
|
memory. */
|
||||||
YYSTYPE *yyvs1 = yyvs;
|
YYSTYPE *yyvs1 = yyvs;
|
||||||
yytype_int16 *yyss1 = yyss;]b4_locations_if([
|
yytype_int16 *yyss1 = yyss;]b4_yaxx([ char **yyxs1 = yyxs;])[]b4_locations_if([
|
||||||
YYLTYPE *yyls1 = yyls;])[
|
YYLTYPE *yyls1 = yyls;])[
|
||||||
|
|
||||||
/* Each stack pointer address is followed by the size of the
|
/* Each stack pointer address is followed by the size of the
|
||||||
@@ -1469,9 +1695,9 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
|
|||||||
be undefined if yyoverflow is a macro. */
|
be undefined if yyoverflow is a macro. */
|
||||||
yyoverflow (YY_("memory exhausted"),
|
yyoverflow (YY_("memory exhausted"),
|
||||||
&yyss1, yysize * sizeof (*yyssp),
|
&yyss1, yysize * sizeof (*yyssp),
|
||||||
&yyvs1, yysize * sizeof (*yyvsp),]b4_locations_if([
|
&yyvs1, yysize * sizeof (*yyvsp),]b4_yaxx([&yyxs1, yysize * sizeof (*yyxsp),])[]b4_locations_if([
|
||||||
&yyls1, yysize * sizeof (*yylsp),])[
|
&yyls1, yysize * sizeof (*yylsp),])[
|
||||||
&yystacksize);
|
&yystacksize);]b4_yaxx([yyxs = yyxs1;])[
|
||||||
]b4_locations_if([
|
]b4_locations_if([
|
||||||
yyls = yyls1;])[
|
yyls = yyls1;])[
|
||||||
yyss = yyss1;
|
yyss = yyss1;
|
||||||
@@ -1495,7 +1721,7 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
|
|||||||
if (! yyptr)
|
if (! yyptr)
|
||||||
goto yyexhaustedlab;
|
goto yyexhaustedlab;
|
||||||
YYSTACK_RELOCATE (yyss_alloc, yyss);
|
YYSTACK_RELOCATE (yyss_alloc, yyss);
|
||||||
YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_locations_if([
|
YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_yaxx([YYSTACK_RELOCATE (yyxs_alloc, yyxs);])[]b4_locations_if([
|
||||||
YYSTACK_RELOCATE (yyls_alloc, yyls);])[
|
YYSTACK_RELOCATE (yyls_alloc, yyls);])[
|
||||||
# undef YYSTACK_RELOCATE
|
# undef YYSTACK_RELOCATE
|
||||||
if (yyss1 != yyssa)
|
if (yyss1 != yyssa)
|
||||||
@@ -1505,7 +1731,7 @@ b4_locations_if([[ yylsp[0] = ]b4_push_if([b4_pure_if([*])yypushed_loc], [yyllo
|
|||||||
#endif /* no yyoverflow */
|
#endif /* no yyoverflow */
|
||||||
|
|
||||||
yyssp = yyss + yysize - 1;
|
yyssp = yyss + yysize - 1;
|
||||||
yyvsp = yyvs + yysize - 1;]b4_locations_if([
|
yyvsp = yyvs + yysize - 1;]b4_yaxx([yyxsp = yyxs + yysize - 1;])[]b4_locations_if([
|
||||||
yylsp = yyls + yysize - 1;])[
|
yylsp = yyls + yysize - 1;])[
|
||||||
|
|
||||||
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
|
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
|
||||||
@@ -1570,7 +1796,33 @@ yyread_pushed_token:]])[
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
yytoken = YYTRANSLATE (yychar);
|
yytoken = YYTRANSLATE (yychar);]b4_yaxx([
|
||||||
|
{ // Yijun Yu: process the terminal
|
||||||
|
yyxml_str = (char *) XML_ALLOC(200);
|
||||||
|
strcpy(yyxml_str, "<yaxx:");
|
||||||
|
strcat(yyxml_str, YYTNAME(yytoken));
|
||||||
|
#if 1 //William Candillon
|
||||||
|
strcat(yyxml_str, " id=\"");
|
||||||
|
sprintf(str, "%x", _id);
|
||||||
|
strcat(yyxml_str, str);
|
||||||
|
strcat(yyxml_str, "\"");
|
||||||
|
_id++;
|
||||||
|
#endif
|
||||||
|
strcat(yyxml_str, ">");
|
||||||
|
if (yytoken < YYNTOKENS) {
|
||||||
|
if (yytext) {
|
||||||
|
char *tmp;
|
||||||
|
tmp=(char *)YYSTACK_ALLOC(6*strlen(yytext)+1);
|
||||||
|
replace_special_entities(yytext,tmp);
|
||||||
|
strcat(yyxml_str, tmp);
|
||||||
|
YYSTACK_FREE(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcat(yyxml_str, "</yaxx:");
|
||||||
|
strcat(yyxml_str, YYTNAME(yytoken));
|
||||||
|
strcat(yyxml_str, ">\n");
|
||||||
|
}
|
||||||
|
])[
|
||||||
YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
|
YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1607,6 +1859,10 @@ yyread_pushed_token:]])[
|
|||||||
|
|
||||||
yystate = yyn;
|
yystate = yyn;
|
||||||
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||||
|
]b4_yaxx([
|
||||||
|
*++yyxsp = yyxml_str;
|
||||||
|
yyxml_str = 0;
|
||||||
|
])[
|
||||||
*++yyvsp = yylval;
|
*++yyvsp = yylval;
|
||||||
YY_IGNORE_MAYBE_UNINITIALIZED_END
|
YY_IGNORE_MAYBE_UNINITIALIZED_END
|
||||||
]b4_locations_if([ *++yylsp = yylloc;])[
|
]b4_locations_if([ *++yylsp = yylloc;])[
|
||||||
@@ -1654,6 +1910,53 @@ yyreduce:
|
|||||||
if (yychar_backup != yychar)
|
if (yychar_backup != yychar)
|
||||||
YY_LAC_DISCARD ("yychar change");
|
YY_LAC_DISCARD ("yychar change");
|
||||||
}]], [[
|
}]], [[
|
||||||
|
]b4_yaxx([
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
int alloc_len=0;
|
||||||
|
int n = 0;
|
||||||
|
int yyi;
|
||||||
|
for (yyi = 0; yyi < yylen; yyi++)
|
||||||
|
{
|
||||||
|
int l;
|
||||||
|
char * yyxml_str = yyxsp[[yyi+1-yylen]];
|
||||||
|
if (yyxml_str==NULL) {
|
||||||
|
l = 0;
|
||||||
|
} else
|
||||||
|
l = strlen(yyxml_str);
|
||||||
|
len += l;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
alloc_len =len+100+2*strlen(YYTNAME(yyr1[[yyn]]));
|
||||||
|
yyxml_str = (char *) XML_ALLOC(alloc_len);
|
||||||
|
strcpy(yyxml_str, "<yaxx:");
|
||||||
|
strcat(yyxml_str, YYTNAME(yyr1[[yyn]]));
|
||||||
|
#if 1 //William Candillon
|
||||||
|
strcat(yyxml_str, " id=\"");
|
||||||
|
sprintf(str, "%x", _id);
|
||||||
|
strcat(yyxml_str, str);
|
||||||
|
strcat(yyxml_str, "\"");
|
||||||
|
_id++;
|
||||||
|
#endif
|
||||||
|
strcat(yyxml_str, ">\n");
|
||||||
|
for (yyi = 0; yyi < yylen; yyi++)
|
||||||
|
{
|
||||||
|
char * xml_str = yyxsp[[yyi+1-yylen]];
|
||||||
|
if (xml_str) {
|
||||||
|
strcat(yyxml_str, xml_str);
|
||||||
|
XML_FREE(xml_str);
|
||||||
|
yyxsp[[yyi+1-yylen]] = NULL;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Warning! the %d-th argument is empty", yyi+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcat(yyxml_str, "</yaxx:");
|
||||||
|
strcat(yyxml_str, YYTNAME(yyr1[[yyn]]));
|
||||||
|
strcat(yyxml_str, ">\n");
|
||||||
|
yyxsp -= n;
|
||||||
|
*++yyxsp = yyxml_str;
|
||||||
|
yyxml_str = NULL;
|
||||||
|
}])[
|
||||||
switch (yyn)
|
switch (yyn)
|
||||||
{
|
{
|
||||||
]b4_user_actions[
|
]b4_user_actions[
|
||||||
@@ -1829,6 +2132,10 @@ yyerrlab1:
|
|||||||
YY_LAC_DISCARD ("error recovery");]])[
|
YY_LAC_DISCARD ("error recovery");]])[
|
||||||
|
|
||||||
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
|
||||||
|
]b4_yaxx([
|
||||||
|
*++yyxsp = yyxml_str;
|
||||||
|
yyxml_str = 0;
|
||||||
|
])[
|
||||||
*++yyvsp = yylval;
|
*++yyvsp = yylval;
|
||||||
YY_IGNORE_MAYBE_UNINITIALIZED_END
|
YY_IGNORE_MAYBE_UNINITIALIZED_END
|
||||||
]b4_locations_if([[
|
]b4_locations_if([[
|
||||||
@@ -1848,7 +2155,7 @@ yyerrlab1:
|
|||||||
/*-------------------------------------.
|
/*-------------------------------------.
|
||||||
| yyacceptlab -- YYACCEPT comes here. |
|
| yyacceptlab -- YYACCEPT comes here. |
|
||||||
`-------------------------------------*/
|
`-------------------------------------*/
|
||||||
yyacceptlab:
|
yyacceptlab:]b4_yaxx([generate_xml_output(--yyxsp,yyxs);])[
|
||||||
yyresult = 0;
|
yyresult = 0;
|
||||||
goto yyreturn;
|
goto yyreturn;
|
||||||
|
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ AnnotationList__computePredecessorAnnotations (AnnotationList *self, state *s,
|
|||||||
{
|
{
|
||||||
symbol_number contribution_token =
|
symbol_number contribution_token =
|
||||||
InadequacyList__getContributionToken (self->inadequacyNode, ci)
|
InadequacyList__getContributionToken (self->inadequacyNode, ci)
|
||||||
->number;
|
->content->number;
|
||||||
if (AnnotationList__isContributionAlways (self, ci))
|
if (AnnotationList__isContributionAlways (self, ci))
|
||||||
{
|
{
|
||||||
annotation_node->contributions[ci] = NULL;
|
annotation_node->contributions[ci] = NULL;
|
||||||
@@ -553,7 +553,7 @@ AnnotationList__compute_from_inadequacies (
|
|||||||
does discard annotations in the simplest case of a S/R
|
does discard annotations in the simplest case of a S/R
|
||||||
conflict with no token precedence. */
|
conflict with no token precedence. */
|
||||||
aver (!bitset_test (shift_tokens, conflicted_token)
|
aver (!bitset_test (shift_tokens, conflicted_token)
|
||||||
|| symbols[conflicted_token]->prec);
|
|| symbols[conflicted_token]->content->prec);
|
||||||
++annotation_counts[s->number];
|
++annotation_counts[s->number];
|
||||||
if (contribution_count > *max_contributionsp)
|
if (contribution_count > *max_contributionsp)
|
||||||
*max_contributionsp = contribution_count;
|
*max_contributionsp = contribution_count;
|
||||||
@@ -599,7 +599,7 @@ AnnotationList__debug (AnnotationList const *self, size_t nitems, int spaces)
|
|||||||
{
|
{
|
||||||
symbol_number token =
|
symbol_number token =
|
||||||
InadequacyList__getContributionToken (a->inadequacyNode, ci)
|
InadequacyList__getContributionToken (a->inadequacyNode, ci)
|
||||||
->number;
|
->content->number;
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < spaces+2; ++j)
|
for (j = 0; j < spaces+2; ++j)
|
||||||
@@ -648,7 +648,7 @@ AnnotationList__computeLookaheadFilter (AnnotationList const *self,
|
|||||||
Sbitset biter;
|
Sbitset biter;
|
||||||
symbol_number token =
|
symbol_number token =
|
||||||
InadequacyList__getContributionToken (self->inadequacyNode, ci)
|
InadequacyList__getContributionToken (self->inadequacyNode, ci)
|
||||||
->number;
|
->content->number;
|
||||||
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
|
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
|
||||||
bitset_set (lookahead_filter[item], token);
|
bitset_set (lookahead_filter[item], token);
|
||||||
}
|
}
|
||||||
@@ -683,7 +683,8 @@ AnnotationList__stateMakesContribution (AnnotationList const *self,
|
|||||||
return false;
|
return false;
|
||||||
{
|
{
|
||||||
symbol_number token =
|
symbol_number token =
|
||||||
InadequacyList__getContributionToken (self->inadequacyNode, ci)->number;
|
InadequacyList__getContributionToken (self->inadequacyNode, ci)
|
||||||
|
->content->number;
|
||||||
Sbitset__Index item;
|
Sbitset__Index item;
|
||||||
Sbitset biter;
|
Sbitset biter;
|
||||||
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
|
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
|
||||||
@@ -713,7 +714,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
|
|||||||
ContributionIndex ci;
|
ContributionIndex ci;
|
||||||
int actioni;
|
int actioni;
|
||||||
ContributionIndex ci_rr_dominator = ContributionIndex__none;
|
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 the token has no precedence set, shift is always chosen. */
|
||||||
if (!shift_precedence)
|
if (!shift_precedence)
|
||||||
@@ -743,7 +744,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
|
|||||||
if (reduce_precedence
|
if (reduce_precedence
|
||||||
&& (reduce_precedence < shift_precedence
|
&& (reduce_precedence < shift_precedence
|
||||||
|| (reduce_precedence == shift_precedence
|
|| (reduce_precedence == shift_precedence
|
||||||
&& token->assoc == right_assoc)))
|
&& token->content->assoc == right_assoc)))
|
||||||
continue;
|
continue;
|
||||||
if (!AnnotationList__stateMakesContribution (self, nitems, ci,
|
if (!AnnotationList__stateMakesContribution (self, nitems, ci,
|
||||||
lookaheads))
|
lookaheads))
|
||||||
@@ -751,7 +752,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
|
|||||||
/* This uneliminated reduction contributes, so see if it can cause
|
/* This uneliminated reduction contributes, so see if it can cause
|
||||||
an error action. */
|
an error action. */
|
||||||
if (reduce_precedence == shift_precedence
|
if (reduce_precedence == shift_precedence
|
||||||
&& token->assoc == non_assoc)
|
&& token->content->assoc == non_assoc)
|
||||||
{
|
{
|
||||||
/* It's not possible to find split-stable domination over
|
/* It's not possible to find split-stable domination over
|
||||||
shift after a potential %nonassoc. */
|
shift after a potential %nonassoc. */
|
||||||
|
|||||||
+8
-8
@@ -104,7 +104,7 @@ log_resolution (rule *r, symbol_number token,
|
|||||||
case shift_resolution:
|
case shift_resolution:
|
||||||
obstack_printf (&solved_conflicts_obstack,
|
obstack_printf (&solved_conflicts_obstack,
|
||||||
" (%s < %s)",
|
" (%s < %s)",
|
||||||
r->prec->tag,
|
r->prec->symbol->tag,
|
||||||
symbols[token]->tag);
|
symbols[token]->tag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ log_resolution (rule *r, symbol_number token,
|
|||||||
obstack_printf (&solved_conflicts_obstack,
|
obstack_printf (&solved_conflicts_obstack,
|
||||||
" (%s < %s)",
|
" (%s < %s)",
|
||||||
symbols[token]->tag,
|
symbols[token]->tag,
|
||||||
r->prec->tag);
|
r->prec->symbol->tag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case left_resolution:
|
case left_resolution:
|
||||||
@@ -176,7 +176,7 @@ log_resolution (rule *r, symbol_number token,
|
|||||||
case shift_resolution:
|
case shift_resolution:
|
||||||
obstack_printf (&solved_conflicts_xml_obstack,
|
obstack_printf (&solved_conflicts_xml_obstack,
|
||||||
"%s < %s",
|
"%s < %s",
|
||||||
xml_escape_n (0, r->prec->tag),
|
xml_escape_n (0, r->prec->symbol->tag),
|
||||||
xml_escape_n (1, symbols[token]->tag));
|
xml_escape_n (1, symbols[token]->tag));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ log_resolution (rule *r, symbol_number token,
|
|||||||
obstack_printf (&solved_conflicts_xml_obstack,
|
obstack_printf (&solved_conflicts_xml_obstack,
|
||||||
"%s < %s",
|
"%s < %s",
|
||||||
xml_escape_n (0, symbols[token]->tag),
|
xml_escape_n (0, symbols[token]->tag),
|
||||||
xml_escape_n (1, r->prec->tag));
|
xml_escape_n (1, r->prec->symbol->tag));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case left_resolution:
|
case left_resolution:
|
||||||
@@ -269,18 +269,18 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
|||||||
for (i = 0; i < ntokens; i++)
|
for (i = 0; i < ntokens; i++)
|
||||||
if (bitset_test (lookahead_tokens, i)
|
if (bitset_test (lookahead_tokens, i)
|
||||||
&& bitset_test (lookahead_set, i)
|
&& bitset_test (lookahead_set, i)
|
||||||
&& symbols[i]->prec)
|
&& symbols[i]->content->prec)
|
||||||
{
|
{
|
||||||
/* Shift-reduce conflict occurs for token number i
|
/* Shift-reduce conflict occurs for token number i
|
||||||
and it has a precedence.
|
and it has a precedence.
|
||||||
The precedence of shifting is that of token i. */
|
The precedence of shifting is that of token i. */
|
||||||
if (symbols[i]->prec < redprec)
|
if (symbols[i]->content->prec < redprec)
|
||||||
{
|
{
|
||||||
register_precedence (redrule->prec->number, i);
|
register_precedence (redrule->prec->number, i);
|
||||||
log_resolution (redrule, i, reduce_resolution);
|
log_resolution (redrule, i, reduce_resolution);
|
||||||
flush_shift (s, i);
|
flush_shift (s, i);
|
||||||
}
|
}
|
||||||
else if (symbols[i]->prec > redprec)
|
else if (symbols[i]->content->prec > redprec)
|
||||||
{
|
{
|
||||||
register_precedence (i, redrule->prec->number);
|
register_precedence (i, redrule->prec->number);
|
||||||
log_resolution (redrule, i, shift_resolution);
|
log_resolution (redrule, i, shift_resolution);
|
||||||
@@ -294,7 +294,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
|||||||
For right associativity, keep only the shift.
|
For right associativity, keep only the shift.
|
||||||
For nonassociativity, keep neither. */
|
For nonassociativity, keep neither. */
|
||||||
|
|
||||||
switch (symbols[i]->assoc)
|
switch (symbols[i]->content->assoc)
|
||||||
{
|
{
|
||||||
case undef_assoc:
|
case undef_assoc:
|
||||||
abort ();
|
abort ();
|
||||||
|
|||||||
+12
-9
@@ -65,19 +65,19 @@ rule_useless_in_parser_p (rule const *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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);
|
fprintf (out, " %3d ", r->number);
|
||||||
if (previous_lhs != r->lhs)
|
if (previous_lhs != r->lhs)
|
||||||
fprintf (out, "%s:", r->lhs->tag);
|
fprintf (out, "%s:", r->lhs->symbol->tag);
|
||||||
else
|
else
|
||||||
fprintf (out, "%*s|", (int) strlen (previous_lhs->tag), "");
|
fprintf (out, "%*s|", (int) strlen (previous_lhs->symbol->tag), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rule_lhs_print_xml (rule const *r, FILE *out, int level)
|
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
|
size_t
|
||||||
@@ -158,7 +158,7 @@ grammar_rules_partial_print (FILE *out, const char *title,
|
|||||||
{
|
{
|
||||||
rule_number r;
|
rule_number r;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
symbol *previous_lhs = NULL;
|
sym_content *previous_lhs = NULL;
|
||||||
|
|
||||||
/* rule # : LHS -> RHS */
|
/* rule # : LHS -> RHS */
|
||||||
for (r = 0; r < nrules + nuseless_productions; r++)
|
for (r = 0; r < nrules + nuseless_productions; r++)
|
||||||
@@ -209,7 +209,7 @@ grammar_rules_print_xml (FILE *out, int level)
|
|||||||
rules[r].number, usefulness);
|
rules[r].number, usefulness);
|
||||||
if (rules[r].precsym)
|
if (rules[r].precsym)
|
||||||
fprintf (out, " percent_prec=\"%s\"",
|
fprintf (out, " percent_prec=\"%s\"",
|
||||||
xml_escape (rules[r].precsym->tag));
|
xml_escape (rules[r].precsym->symbol->tag));
|
||||||
fputs (">\n", out);
|
fputs (">\n", out);
|
||||||
}
|
}
|
||||||
rule_lhs_print_xml (&rules[r], out, level + 3);
|
rule_lhs_print_xml (&rules[r], out, level + 3);
|
||||||
@@ -239,7 +239,7 @@ grammar_dump (FILE *out, const char *title)
|
|||||||
for (i = ntokens; i < nsyms; i++)
|
for (i = ntokens; i < nsyms; i++)
|
||||||
fprintf (out, "%5d %5d %5d %s\n",
|
fprintf (out, "%5d %5d %5d %s\n",
|
||||||
i,
|
i,
|
||||||
symbols[i]->prec, symbols[i]->assoc,
|
symbols[i]->content->prec, symbols[i]->content->assoc,
|
||||||
symbols[i]->tag);
|
symbols[i]->tag);
|
||||||
fprintf (out, "\n\n");
|
fprintf (out, "\n\n");
|
||||||
}
|
}
|
||||||
@@ -280,7 +280,7 @@ grammar_dump (FILE *out, const char *title)
|
|||||||
rule_number r;
|
rule_number r;
|
||||||
for (r = 0; r < nrules + nuseless_productions; 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);
|
rule_rhs_print (&rules[r], out);
|
||||||
fprintf (out, "\n");
|
fprintf (out, "\n");
|
||||||
}
|
}
|
||||||
@@ -293,7 +293,10 @@ grammar_rules_useless_report (const char *message)
|
|||||||
{
|
{
|
||||||
rule_number r;
|
rule_number r;
|
||||||
for (r = 0; r < nrules ; ++r)
|
for (r = 0; r < nrules ; ++r)
|
||||||
if (!rules[r].useful)
|
/* Don't complain about rules whose LHS is useless, we already
|
||||||
|
complained about it. */
|
||||||
|
if (!reduce_nonterminal_useless_in_grammar (rules[r].lhs)
|
||||||
|
&& !rules[r].useful)
|
||||||
complain (&rules[r].location, Wother, "%s", message);
|
complain (&rules[r].location, Wother, "%s", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -180,17 +180,17 @@ typedef struct
|
|||||||
except if some rules are useless. */
|
except if some rules are useless. */
|
||||||
rule_number number;
|
rule_number number;
|
||||||
|
|
||||||
symbol *lhs;
|
sym_content *lhs;
|
||||||
item_number *rhs;
|
item_number *rhs;
|
||||||
|
|
||||||
/* This symbol provides both the associativity, and the precedence. */
|
/* This symbol provides both the associativity, and the precedence. */
|
||||||
symbol *prec;
|
sym_content *prec;
|
||||||
|
|
||||||
int dprec;
|
int dprec;
|
||||||
int merger;
|
int merger;
|
||||||
|
|
||||||
/* This symbol was attached to the rule via %prec. */
|
/* This symbol was attached to the rule via %prec. */
|
||||||
symbol *precsym;
|
sym_content *precsym;
|
||||||
|
|
||||||
location location;
|
location location;
|
||||||
bool useful;
|
bool useful;
|
||||||
@@ -220,7 +220,8 @@ bool rule_useless_in_parser_p (rule const *r);
|
|||||||
/* Print this rule's number and lhs on OUT. If a PREVIOUS_LHS was
|
/* Print this rule's number and lhs on OUT. If a PREVIOUS_LHS was
|
||||||
already displayed (by a previous call for another rule), avoid
|
already displayed (by a previous call for another rule), avoid
|
||||||
useless repetitions. */
|
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);
|
void rule_lhs_print_xml (rule const *r, FILE *out, int level);
|
||||||
|
|
||||||
/* Return the length of the RHS. */
|
/* 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));
|
bitset_set (*no_reduce_set, TRANSITION_SYMBOL (s->transitions, n));
|
||||||
for (n = 0; n < s->errs->num; ++n)
|
for (n = 0; n < s->errs->num; ++n)
|
||||||
if (s->errs->symbols[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
|
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]))
|
if (item_number_is_rule_number (ritem[s->items[item] - 2]))
|
||||||
{
|
{
|
||||||
state **predecessor;
|
state **predecessor;
|
||||||
aver (lhs != accept->number);
|
aver (lhs != accept->content->number);
|
||||||
for (predecessor = predecessors[s->number];
|
for (predecessor = predecessors[s->number];
|
||||||
*predecessor;
|
*predecessor;
|
||||||
++predecessor)
|
++predecessor)
|
||||||
@@ -580,7 +580,7 @@ typedef struct state_list {
|
|||||||
static void
|
static void
|
||||||
ielr_compute_goto_follow_set (bitsetv follow_kernel_items,
|
ielr_compute_goto_follow_set (bitsetv follow_kernel_items,
|
||||||
bitsetv always_follows, state_list *s,
|
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);
|
goto_number n_goto = map_goto (s->lr0Isocore->state->number, n->number);
|
||||||
bitset_copy (follow_set, always_follows[n_goto]);
|
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 ("tokens_number", ntokens);
|
||||||
MUSCLE_INSERT_INT ("nterms_number", nvars);
|
MUSCLE_INSERT_INT ("nterms_number", nvars);
|
||||||
MUSCLE_INSERT_INT ("symbols_number", nsyms);
|
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_INT ("user_token_number_max", max_user_token_number);
|
||||||
|
|
||||||
muscle_insert_symbol_number_table ("translate",
|
muscle_insert_symbol_number_table ("translate",
|
||||||
@@ -197,7 +197,7 @@ prepare_symbols (void)
|
|||||||
int i;
|
int i;
|
||||||
int *values = xnmalloc (ntokens, sizeof *values);
|
int *values = xnmalloc (ntokens, sizeof *values);
|
||||||
for (i = 0; i < ntokens; ++i)
|
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,
|
muscle_insert_int_table ("toknum", values,
|
||||||
values[0], 1, ntokens);
|
values[0], 1, ntokens);
|
||||||
free (values);
|
free (values);
|
||||||
@@ -283,9 +283,9 @@ prepare_states (void)
|
|||||||
static int
|
static int
|
||||||
symbol_type_name_cmp (const symbol **lhs, const symbol **rhs)
|
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)
|
if (!res)
|
||||||
res = (*lhs)->number - (*rhs)->number;
|
res = (*lhs)->content->number - (*rhs)->content->number;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,8 +320,9 @@ type_names_output (FILE *out)
|
|||||||
/* The index of the first symbol of the current type-name. */
|
/* The index of the first symbol of the current type-name. */
|
||||||
int i0 = i;
|
int i0 = i;
|
||||||
fputs (i ? ",\n[" : "[", out);
|
fputs (i ? ",\n[" : "[", out);
|
||||||
for (; i < nsyms && syms[i]->type_name == syms[i0]->type_name; ++i)
|
for (; i < nsyms
|
||||||
fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->number);
|
&& syms[i]->content->type_name == syms[i0]->content->type_name; ++i)
|
||||||
|
fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->content->number);
|
||||||
fputs ("]", out);
|
fputs ("]", out);
|
||||||
}
|
}
|
||||||
fputs ("])\n\n", out);
|
fputs ("])\n\n", out);
|
||||||
@@ -428,20 +429,21 @@ prepare_symbol_definitions (void)
|
|||||||
MUSCLE_INSERT_STRING (key, sym->tag);
|
MUSCLE_INSERT_STRING (key, sym->tag);
|
||||||
|
|
||||||
SET_KEY ("user_number");
|
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");
|
SET_KEY ("is_token");
|
||||||
MUSCLE_INSERT_INT (key,
|
MUSCLE_INSERT_INT (key,
|
||||||
i < ntokens && sym != errtoken && sym != undeftoken);
|
i < ntokens && sym != errtoken && sym != undeftoken);
|
||||||
|
|
||||||
SET_KEY ("number");
|
SET_KEY ("number");
|
||||||
MUSCLE_INSERT_INT (key, sym->number);
|
MUSCLE_INSERT_INT (key, sym->content->number);
|
||||||
|
|
||||||
SET_KEY ("has_type");
|
SET_KEY ("has_type");
|
||||||
MUSCLE_INSERT_INT (key, !!sym->type_name);
|
MUSCLE_INSERT_INT (key, !!sym->content->type_name);
|
||||||
|
|
||||||
SET_KEY ("type");
|
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;
|
int j;
|
||||||
|
|||||||
+4
-2
@@ -1,4 +1,4 @@
|
|||||||
/* A Bison parser, made by GNU Bison 3.0.2.13-975bb-dirty. */
|
/* A Bison parser, made by GNU Bison 3.0.2.29-9a91e. */
|
||||||
|
|
||||||
/* Bison implementation for Yacc-like parsers in C
|
/* Bison implementation for Yacc-like parsers in C
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
#define YYBISON 1
|
#define YYBISON 1
|
||||||
|
|
||||||
/* Bison version. */
|
/* Bison version. */
|
||||||
#define YYBISON_VERSION "3.0.2.13-975bb-dirty"
|
#define YYBISON_VERSION "3.0.2.29-9a91e"
|
||||||
|
|
||||||
/* Skeleton name. */
|
/* Skeleton name. */
|
||||||
#define YYSKELETON_NAME "yacc.c"
|
#define YYSKELETON_NAME "yacc.c"
|
||||||
@@ -3118,6 +3118,8 @@ current_lhs (symbol *sym, location loc, named_ref *ref)
|
|||||||
{
|
{
|
||||||
current_lhs_symbol = sym;
|
current_lhs_symbol = sym;
|
||||||
current_lhs_location = loc;
|
current_lhs_location = loc;
|
||||||
|
if (sym)
|
||||||
|
symbol_location_as_lhs_set (sym, loc);
|
||||||
/* In order to simplify memory management, named references for lhs
|
/* In order to simplify memory management, named references for lhs
|
||||||
are always assigned by deep copy into the current symbol_list
|
are always assigned by deep copy into the current symbol_list
|
||||||
node. This is because a single named-ref in the grammar may
|
node. This is because a single named-ref in the grammar may
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* A Bison parser, made by GNU Bison 3.0.2.13-975bb-dirty. */
|
/* A Bison parser, made by GNU Bison 3.0.2.29-9a91e. */
|
||||||
|
|
||||||
/* Bison interface for Yacc-like parsers in C
|
/* Bison interface for Yacc-like parsers in C
|
||||||
|
|
||||||
|
|||||||
@@ -865,6 +865,8 @@ current_lhs (symbol *sym, location loc, named_ref *ref)
|
|||||||
{
|
{
|
||||||
current_lhs_symbol = sym;
|
current_lhs_symbol = sym;
|
||||||
current_lhs_location = loc;
|
current_lhs_location = loc;
|
||||||
|
if (sym)
|
||||||
|
symbol_location_as_lhs_set (sym, loc);
|
||||||
/* In order to simplify memory management, named references for lhs
|
/* In order to simplify memory management, named references for lhs
|
||||||
are always assigned by deep copy into the current symbol_list
|
are always assigned by deep copy into the current symbol_list
|
||||||
node. This is because a single named-ref in the grammar may
|
node. This is because a single named-ref in the grammar may
|
||||||
|
|||||||
+5
-5
@@ -259,7 +259,7 @@ print_reductions (FILE *out, int level, state *s)
|
|||||||
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
|
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
|
||||||
for (i = 0; i < s->errs->num; ++i)
|
for (i = 0; i < s->errs->num; ++i)
|
||||||
if (s->errs->symbols[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)
|
if (default_reduction)
|
||||||
report = true;
|
report = true;
|
||||||
@@ -388,11 +388,11 @@ print_grammar (FILE *out, int level)
|
|||||||
/* Terminals */
|
/* Terminals */
|
||||||
xml_puts (out, level + 1, "<terminals>");
|
xml_puts (out, level + 1, "<terminals>");
|
||||||
for (i = 0; i < max_user_token_number + 1; i++)
|
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;
|
char const *tag = symbols[token_translations[i]]->tag;
|
||||||
int precedence = symbols[token_translations[i]]->prec;
|
int precedence = symbols[token_translations[i]]->content->prec;
|
||||||
assoc associativity = symbols[token_translations[i]]->assoc;
|
assoc associativity = symbols[token_translations[i]]->content->assoc;
|
||||||
xml_indent (out, level + 2);
|
xml_indent (out, level + 2);
|
||||||
fprintf (out,
|
fprintf (out,
|
||||||
"<terminal symbol-number=\"%d\" token-number=\"%d\""
|
"<terminal symbol-number=\"%d\" token-number=\"%d\""
|
||||||
@@ -417,7 +417,7 @@ print_grammar (FILE *out, int level)
|
|||||||
"<nonterminal symbol-number=\"%d\" name=\"%s\""
|
"<nonterminal symbol-number=\"%d\" name=\"%s\""
|
||||||
" usefulness=\"%s\"/>",
|
" usefulness=\"%s\"/>",
|
||||||
i, xml_escape (tag),
|
i, xml_escape (tag),
|
||||||
reduce_nonterminal_useless_in_grammar (i)
|
reduce_nonterminal_useless_in_grammar (symbols[i]->content)
|
||||||
? "useless-in-grammar" : "useful");
|
? "useless-in-grammar" : "useful");
|
||||||
}
|
}
|
||||||
xml_puts (out, level + 1, "</nonterminals>");
|
xml_puts (out, level + 1, "</nonterminals>");
|
||||||
|
|||||||
+5
-4
@@ -72,7 +72,7 @@ print_core (FILE *out, state *s)
|
|||||||
size_t i;
|
size_t i;
|
||||||
item_number *sitems = s->items;
|
item_number *sitems = s->items;
|
||||||
size_t snritems = s->nitems;
|
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. */
|
/* Output all the items of a state, not only its kernel. */
|
||||||
if (report_flag & report_itemsets)
|
if (report_flag & report_itemsets)
|
||||||
@@ -226,7 +226,8 @@ print_reduction (FILE *out, size_t width,
|
|||||||
if (!enabled)
|
if (!enabled)
|
||||||
fputc ('[', out);
|
fputc ('[', out);
|
||||||
if (r->number)
|
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
|
else
|
||||||
fprintf (out, _("accept"));
|
fprintf (out, _("accept"));
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
@@ -260,7 +261,7 @@ print_reductions (FILE *out, state *s)
|
|||||||
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
|
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
|
||||||
for (i = 0; i < s->errs->num; ++i)
|
for (i = 0; i < s->errs->num; ++i)
|
||||||
if (s->errs->symbols[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. */
|
/* Compute the width of the lookahead token column. */
|
||||||
if (default_reduction)
|
if (default_reduction)
|
||||||
@@ -412,7 +413,7 @@ print_grammar (FILE *out)
|
|||||||
/* TERMINAL (type #) : rule #s terminal is on RHS */
|
/* TERMINAL (type #) : rule #s terminal is on RHS */
|
||||||
fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
|
fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
|
||||||
for (i = 0; i < max_user_token_number + 1; i++)
|
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;
|
const char *tag = symbols[token_translations[i]]->tag;
|
||||||
rule_number r;
|
rule_number r;
|
||||||
|
|||||||
+5
-4
@@ -46,7 +46,7 @@ static void
|
|||||||
print_core (struct obstack *oout, state *s)
|
print_core (struct obstack *oout, state *s)
|
||||||
{
|
{
|
||||||
item_number const *sitems = s->items;
|
item_number const *sitems = s->items;
|
||||||
symbol *previous_lhs = NULL;
|
sym_content *previous_lhs = NULL;
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t snritems = s->nitems;
|
size_t snritems = s->nitems;
|
||||||
|
|
||||||
@@ -72,11 +72,12 @@ print_core (struct obstack *oout, state *s)
|
|||||||
r = &rules[item_number_as_rule_number (*sp)];
|
r = &rules[item_number_as_rule_number (*sp)];
|
||||||
|
|
||||||
obstack_printf (oout, "%3d ", r->number);
|
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| ",
|
obstack_printf (oout, "%*s| ",
|
||||||
(int) strlen (previous_lhs->tag), "");
|
(int) strlen (previous_lhs->symbol->tag), "");
|
||||||
else
|
else
|
||||||
obstack_printf (oout, "%s: ", escape (r->lhs->tag));
|
obstack_printf (oout, "%s: ", escape (r->lhs->symbol->tag));
|
||||||
previous_lhs = r->lhs;
|
previous_lhs = r->lhs;
|
||||||
|
|
||||||
for (sp = r->rhs; sp < sp1; sp++)
|
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;
|
current_rule = grammar_end;
|
||||||
|
|
||||||
/* Mark the rule's lhs as a nonterminal if not already so. */
|
/* 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->content->class = nterm_sym;
|
||||||
lhs->number = nvars;
|
lhs->content->number = nvars;
|
||||||
++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"),
|
complain (&loc, complaint, _("rule given for %s, which is a token"),
|
||||||
lhs->tag);
|
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
|
Don't worry about the default action if $$ is untyped, since $$'s
|
||||||
value can't be used. */
|
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;
|
symbol *first_rhs = r->next->content.sym;
|
||||||
/* If $$ is being set in default way, report if any type mismatch. */
|
/* If $$ is being set in default way, report if any type mismatch. */
|
||||||
if (first_rhs)
|
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 =
|
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))
|
if (!UNIQSTR_EQ (lhs_type, rhs_type))
|
||||||
complain (&r->location, Wother,
|
complain (&r->location, Wother,
|
||||||
_("type clash on default action: <%s> != <%s>"),
|
_("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. */
|
it for char literals and strings, which are always tokens. */
|
||||||
if (r->ruleprec
|
if (r->ruleprec
|
||||||
&& r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"'
|
&& 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,
|
complain (&r->location, Wother,
|
||||||
_("token for %%prec is not defined: %s"), r->ruleprec->tag);
|
_("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);
|
p = grammar_symbol_append (sym, loc);
|
||||||
if (name)
|
if (name)
|
||||||
assign_named_ref (p, name);
|
assign_named_ref (p, name);
|
||||||
if (sym->status == undeclared || sym->status == used)
|
if (sym->content->status == undeclared || sym->content->status == used)
|
||||||
sym->status = needed;
|
sym->content->status = needed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attach an ACTION to the current rule. */
|
/* Attach an ACTION to the current rule. */
|
||||||
@@ -558,11 +559,11 @@ packgram (void)
|
|||||||
for (p = grammar; p; p = p->next)
|
for (p = grammar; p; p = p->next)
|
||||||
{
|
{
|
||||||
symbol *ruleprec = p->ruleprec;
|
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);
|
p->merger_declaration_location);
|
||||||
rules[ruleno].user_number = ruleno;
|
rules[ruleno].user_number = ruleno;
|
||||||
rules[ruleno].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].rhs = ritem + itemno;
|
||||||
rules[ruleno].prec = NULL;
|
rules[ruleno].prec = NULL;
|
||||||
rules[ruleno].dprec = p->dprec;
|
rules[ruleno].dprec = p->dprec;
|
||||||
@@ -604,11 +605,11 @@ packgram (void)
|
|||||||
/* item_number = symbol_number.
|
/* item_number = symbol_number.
|
||||||
But the former needs to contain more: negative rule numbers. */
|
But the former needs to contain more: negative rule numbers. */
|
||||||
ritem[itemno++] =
|
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
|
/* A rule gets by default the precedence and associativity
|
||||||
of its last token. */
|
of its last token. */
|
||||||
if (p->content.sym->class == token_sym && default_prec)
|
if (p->content.sym->content->class == token_sym && default_prec)
|
||||||
rules[ruleno].prec = p->content.sym;
|
rules[ruleno].prec = p->content.sym->content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,8 +617,8 @@ packgram (void)
|
|||||||
the specified symbol's precedence replaces the default. */
|
the specified symbol's precedence replaces the default. */
|
||||||
if (ruleprec)
|
if (ruleprec)
|
||||||
{
|
{
|
||||||
rules[ruleno].precsym = ruleprec;
|
rules[ruleno].precsym = ruleprec->content;
|
||||||
rules[ruleno].prec = ruleprec;
|
rules[ruleno].prec = ruleprec->content;
|
||||||
}
|
}
|
||||||
/* An item ends by the rule number (negated). */
|
/* An item ends by the rule number (negated). */
|
||||||
ritem[itemno++] = rule_number_as_item_number (ruleno);
|
ritem[itemno++] = rule_number_as_item_number (ruleno);
|
||||||
@@ -647,19 +648,19 @@ reader (void)
|
|||||||
|
|
||||||
/* Construct the accept symbol. */
|
/* Construct the accept symbol. */
|
||||||
accept = symbol_get ("$accept", empty_location);
|
accept = symbol_get ("$accept", empty_location);
|
||||||
accept->class = nterm_sym;
|
accept->content->class = nterm_sym;
|
||||||
accept->number = nvars++;
|
accept->content->number = nvars++;
|
||||||
|
|
||||||
/* Construct the error token */
|
/* Construct the error token */
|
||||||
errtoken = symbol_get ("error", empty_location);
|
errtoken = symbol_get ("error", empty_location);
|
||||||
errtoken->class = token_sym;
|
errtoken->content->class = token_sym;
|
||||||
errtoken->number = ntokens++;
|
errtoken->content->number = ntokens++;
|
||||||
|
|
||||||
/* Construct a token that represents all undefined literal tokens.
|
/* Construct a token that represents all undefined literal tokens.
|
||||||
It is always token number 2. */
|
It is always token number 2. */
|
||||||
undeftoken = symbol_get ("$undefined", empty_location);
|
undeftoken = symbol_get ("$undefined", empty_location);
|
||||||
undeftoken->class = token_sym;
|
undeftoken->content->class = token_sym;
|
||||||
undeftoken->number = ntokens++;
|
undeftoken->content->number = ntokens++;
|
||||||
|
|
||||||
gram_in = xfopen (grammar_file, "r");
|
gram_in = xfopen (grammar_file, "r");
|
||||||
|
|
||||||
@@ -721,10 +722,10 @@ check_and_convert_grammar (void)
|
|||||||
if (!endtoken)
|
if (!endtoken)
|
||||||
{
|
{
|
||||||
endtoken = symbol_get ("$end", empty_location);
|
endtoken = symbol_get ("$end", empty_location);
|
||||||
endtoken->class = token_sym;
|
endtoken->content->class = token_sym;
|
||||||
endtoken->number = 0;
|
endtoken->content->number = 0;
|
||||||
/* Value specified by POSIX. */
|
/* Value specified by POSIX. */
|
||||||
endtoken->user_token_number = 0;
|
endtoken->content->user_token_number = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Report any undefined symbols and consider them nonterminals. */
|
/* Report any undefined symbols and consider them nonterminals. */
|
||||||
|
|||||||
+79
-82
@@ -39,7 +39,7 @@
|
|||||||
#include "reduce.h"
|
#include "reduce.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
|
|
||||||
/* Set of all nonterminals which are not useless. */
|
/* Set of all nonterminals whose language is not empty. */
|
||||||
static bitset N;
|
static bitset N;
|
||||||
|
|
||||||
/* Set of all rules which have no useless nonterminals in their RHS. */
|
/* Set of all rules which have no useless nonterminals in their RHS. */
|
||||||
@@ -52,11 +52,18 @@ static bitset V;
|
|||||||
'useless', but no warning should be issued). */
|
'useless', but no warning should be issued). */
|
||||||
static bitset V1;
|
static bitset V1;
|
||||||
|
|
||||||
static rule_number nuseful_productions;
|
static unsigned nuseful_productions;
|
||||||
rule_number nuseless_productions;
|
unsigned nuseless_productions;
|
||||||
static int nuseful_nonterminals;
|
static unsigned nuseful_nonterminals;
|
||||||
symbol_number nuseless_nonterminals;
|
unsigned nuseless_nonterminals;
|
||||||
|
|
||||||
|
#define bitset_swap(Lhs, Rhs) \
|
||||||
|
do { \
|
||||||
|
bitset lhs__ = Lhs; \
|
||||||
|
Lhs = Rhs; \
|
||||||
|
Rhs = lhs__; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/*-------------------------------------------------------------------.
|
/*-------------------------------------------------------------------.
|
||||||
| Another way to do this would be with a set for each production and |
|
| Another way to do this would be with a set for each production and |
|
||||||
| then do subset tests against N0, but even for the C grammar the |
|
| then do subset tests against N0, but even for the C grammar the |
|
||||||
@@ -71,7 +78,7 @@ useful_production (rule_number r, bitset N0)
|
|||||||
/* A production is useful if all of the nonterminals in its appear
|
/* A production is useful if all of the nonterminals in its appear
|
||||||
in the set of useful nonterminals. */
|
in the set of useful nonterminals. */
|
||||||
|
|
||||||
for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
|
for (rhsp = rules[r].rhs; 0 <= *rhsp; ++rhsp)
|
||||||
if (ISVAR (*rhsp) && !bitset_test (N0, *rhsp - ntokens))
|
if (ISVAR (*rhsp) && !bitset_test (N0, *rhsp - ntokens))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
@@ -85,14 +92,10 @@ useful_production (rule_number r, bitset N0)
|
|||||||
static void
|
static void
|
||||||
useless_nonterminals (void)
|
useless_nonterminals (void)
|
||||||
{
|
{
|
||||||
bitset Np, Ns;
|
|
||||||
rule_number r;
|
|
||||||
|
|
||||||
/* N is set as built. Np is set being built this iteration. P is
|
/* N is set as built. Np is set being built this iteration. P is
|
||||||
set of all productions which have a RHS all in N. */
|
set of all productions which have a RHS all in N. */
|
||||||
|
|
||||||
Np = bitset_create (nvars, BITSET_FIXED);
|
bitset Np = bitset_create (nvars, BITSET_FIXED);
|
||||||
|
|
||||||
|
|
||||||
/* The set being computed is a set of nonterminals which can derive
|
/* The set being computed is a set of nonterminals which can derive
|
||||||
the empty string or strings consisting of all terminals. At each
|
the empty string or strings consisting of all terminals. At each
|
||||||
@@ -112,8 +115,9 @@ useless_nonterminals (void)
|
|||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
rule_number r;
|
||||||
bitset_copy (Np, N);
|
bitset_copy (Np, N);
|
||||||
for (r = 0; r < nrules; r++)
|
for (r = 0; r < nrules; ++r)
|
||||||
if (!bitset_test (P, r)
|
if (!bitset_test (P, r)
|
||||||
&& useful_production (r, N))
|
&& useful_production (r, N))
|
||||||
{
|
{
|
||||||
@@ -122,9 +126,7 @@ useless_nonterminals (void)
|
|||||||
}
|
}
|
||||||
if (bitset_equal_p (N, Np))
|
if (bitset_equal_p (N, Np))
|
||||||
break;
|
break;
|
||||||
Ns = Np;
|
bitset_swap (N, Np);
|
||||||
Np = N;
|
|
||||||
N = Ns;
|
|
||||||
}
|
}
|
||||||
bitset_free (N);
|
bitset_free (N);
|
||||||
N = Np;
|
N = Np;
|
||||||
@@ -134,8 +136,6 @@ useless_nonterminals (void)
|
|||||||
static void
|
static void
|
||||||
inaccessable_symbols (void)
|
inaccessable_symbols (void)
|
||||||
{
|
{
|
||||||
bitset Vp, Vs, Pp;
|
|
||||||
|
|
||||||
/* Find out which productions are reachable and which symbols are
|
/* Find out which productions are reachable and which symbols are
|
||||||
used. Starting with an empty set of productions and a set of
|
used. Starting with an empty set of productions and a set of
|
||||||
symbols which only has the start symbol in it, iterate over all
|
symbols which only has the start symbol in it, iterate over all
|
||||||
@@ -159,46 +159,43 @@ inaccessable_symbols (void)
|
|||||||
terminals are printed (if running in verbose mode) so that the
|
terminals are printed (if running in verbose mode) so that the
|
||||||
user can know. */
|
user can know. */
|
||||||
|
|
||||||
Vp = bitset_create (nsyms, BITSET_FIXED);
|
bitset Vp = bitset_create (nsyms, BITSET_FIXED);
|
||||||
Pp = bitset_create (nrules, BITSET_FIXED);
|
bitset Pp = bitset_create (nrules, BITSET_FIXED);
|
||||||
|
|
||||||
/* If the start symbol isn't useful, then nothing will be useful. */
|
/* 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)
|
while (1)
|
||||||
{
|
{
|
||||||
rule_number r;
|
rule_number r;
|
||||||
bitset_copy (Vp, V);
|
bitset_copy (Vp, V);
|
||||||
for (r = 0; r < nrules; r++)
|
for (r = 0; r < nrules; ++r)
|
||||||
{
|
if (!bitset_test (Pp, r)
|
||||||
if (!bitset_test (Pp, r)
|
&& bitset_test (P, r)
|
||||||
&& bitset_test (P, r)
|
&& bitset_test (V, rules[r].lhs->number))
|
||||||
&& bitset_test (V, rules[r].lhs->number))
|
{
|
||||||
{
|
item_number *rhsp;
|
||||||
item_number *rhsp;
|
for (rhsp = rules[r].rhs; 0 <= *rhsp; ++rhsp)
|
||||||
for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
|
if (ISTOKEN (*rhsp) || bitset_test (N, *rhsp - ntokens))
|
||||||
if (ISTOKEN (*rhsp) || bitset_test (N, *rhsp - ntokens))
|
bitset_set (Vp, *rhsp);
|
||||||
bitset_set (Vp, *rhsp);
|
bitset_set (Pp, r);
|
||||||
bitset_set (Pp, r);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bitset_equal_p (V, Vp))
|
if (bitset_equal_p (V, Vp))
|
||||||
break;
|
break;
|
||||||
Vs = Vp;
|
bitset_swap (V, Vp);
|
||||||
Vp = V;
|
|
||||||
V = Vs;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bitset_free (V);
|
bitset_free (V);
|
||||||
V = Vp;
|
V = Vp;
|
||||||
|
|
||||||
/* Tokens 0, 1, and 2 are internal to Bison. Consider them useful. */
|
/* These tokens (numbered 0, 1, and 2) are internal to Bison.
|
||||||
bitset_set (V, endtoken->number); /* end-of-input token */
|
Consider them useful. */
|
||||||
bitset_set (V, errtoken->number); /* error token */
|
bitset_set (V, endtoken->content->number); /* end-of-input token */
|
||||||
bitset_set (V, undeftoken->number); /* some undefined token */
|
bitset_set (V, errtoken->content->number); /* error token */
|
||||||
|
bitset_set (V, undeftoken->content->number); /* some undefined token */
|
||||||
|
|
||||||
bitset_free (P);
|
bitset_free (P);
|
||||||
P = Pp;
|
P = Pp;
|
||||||
@@ -209,9 +206,8 @@ inaccessable_symbols (void)
|
|||||||
nuseful_nonterminals = 0;
|
nuseful_nonterminals = 0;
|
||||||
{
|
{
|
||||||
symbol_number i;
|
symbol_number i;
|
||||||
for (i = ntokens; i < nsyms; i++)
|
for (i = ntokens; i < nsyms; ++i)
|
||||||
if (bitset_test (V, i))
|
nuseful_nonterminals += bitset_test (V, i);
|
||||||
nuseful_nonterminals++;
|
|
||||||
}
|
}
|
||||||
nuseless_nonterminals = nvars - nuseful_nonterminals;
|
nuseless_nonterminals = nvars - nuseful_nonterminals;
|
||||||
|
|
||||||
@@ -236,7 +232,7 @@ reduce_grammar_tables (void)
|
|||||||
/* Report and flag useless productions. */
|
/* Report and flag useless productions. */
|
||||||
{
|
{
|
||||||
rule_number r;
|
rule_number r;
|
||||||
for (r = 0; r < nrules; r++)
|
for (r = 0; r < nrules; ++r)
|
||||||
rules[r].useful = bitset_test (P, r);
|
rules[r].useful = bitset_test (P, r);
|
||||||
grammar_rules_useless_report (_("rule useless in grammar"));
|
grammar_rules_useless_report (_("rule useless in grammar"));
|
||||||
}
|
}
|
||||||
@@ -257,8 +253,8 @@ reduce_grammar_tables (void)
|
|||||||
for (r = 0; r < nrules; ++r)
|
for (r = 0; r < nrules; ++r)
|
||||||
{
|
{
|
||||||
item_number *rhsp = rules[r].rhs;
|
item_number *rhsp = rules[r].rhs;
|
||||||
for (/* Nothing. */; *rhsp >= 0; ++rhsp)
|
for (/* Nothing. */; 0 <= *rhsp; ++rhsp)
|
||||||
/* Nothing. */;
|
continue;
|
||||||
*rhsp = rule_number_as_item_number (r);
|
*rhsp = rule_number_as_item_number (r);
|
||||||
rules[r].number = r;
|
rules[r].number = r;
|
||||||
}
|
}
|
||||||
@@ -289,31 +285,33 @@ nonterminals_reduce (void)
|
|||||||
afterwards. Kept for later report. */
|
afterwards. Kept for later report. */
|
||||||
|
|
||||||
symbol_number *nontermmap = xnmalloc (nvars, sizeof *nontermmap);
|
symbol_number *nontermmap = xnmalloc (nvars, sizeof *nontermmap);
|
||||||
symbol_number n = ntokens;
|
{
|
||||||
symbol_number i;
|
symbol_number n = ntokens;
|
||||||
for (i = ntokens; i < nsyms; i++)
|
symbol_number i;
|
||||||
if (bitset_test (V, i))
|
for (i = ntokens; i < nsyms; ++i)
|
||||||
nontermmap[i - ntokens] = n++;
|
if (bitset_test (V, i))
|
||||||
for (i = ntokens; i < nsyms; i++)
|
|
||||||
if (!bitset_test (V, i))
|
|
||||||
{
|
|
||||||
nontermmap[i - ntokens] = n++;
|
nontermmap[i - ntokens] = n++;
|
||||||
if (symbols[i]->status != used)
|
for (i = ntokens; i < nsyms; ++i)
|
||||||
complain (&symbols[i]->location, Wother,
|
if (!bitset_test (V, i))
|
||||||
_("nonterminal useless in grammar: %s"),
|
{
|
||||||
symbols[i]->tag);
|
nontermmap[i - ntokens] = n++;
|
||||||
}
|
if (symbols[i]->content->status != used)
|
||||||
|
complain (&symbols[i]->location, Wother,
|
||||||
|
_("nonterminal useless in grammar: %s"),
|
||||||
|
symbols[i]->tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Shuffle elements of tables indexed by symbol number. */
|
/* Shuffle elements of tables indexed by symbol number. */
|
||||||
{
|
{
|
||||||
symbol **symbols_sorted = xnmalloc (nvars, sizeof *symbols_sorted);
|
symbol **symbols_sorted = xnmalloc (nvars, sizeof *symbols_sorted);
|
||||||
|
symbol_number i;
|
||||||
for (i = ntokens; i < nsyms; i++)
|
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++)
|
for (i = ntokens; i < nsyms; ++i)
|
||||||
symbols_sorted[nontermmap[i - ntokens] - ntokens] = symbols[i];
|
symbols_sorted[nontermmap[i - ntokens] - ntokens] = symbols[i];
|
||||||
for (i = ntokens; i < nsyms; i++)
|
for (i = ntokens; i < nsyms; ++i)
|
||||||
symbols[i] = symbols_sorted[i - ntokens];
|
symbols[i] = symbols_sorted[i - ntokens];
|
||||||
free (symbols_sorted);
|
free (symbols_sorted);
|
||||||
}
|
}
|
||||||
@@ -323,12 +321,12 @@ nonterminals_reduce (void)
|
|||||||
for (r = 0; r < nrules; ++r)
|
for (r = 0; r < nrules; ++r)
|
||||||
{
|
{
|
||||||
item_number *rhsp;
|
item_number *rhsp;
|
||||||
for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
|
for (rhsp = rules[r].rhs; 0 <= *rhsp; ++rhsp)
|
||||||
if (ISVAR (*rhsp))
|
if (ISVAR (*rhsp))
|
||||||
*rhsp = symbol_number_as_item_number (nontermmap[*rhsp
|
*rhsp = symbol_number_as_item_number (nontermmap[*rhsp
|
||||||
- ntokens]);
|
- ntokens]);
|
||||||
}
|
}
|
||||||
accept->number = nontermmap[accept->number - ntokens];
|
accept->content->number = nontermmap[accept->content->number - ntokens];
|
||||||
}
|
}
|
||||||
|
|
||||||
nsyms -= nuseless_nonterminals;
|
nsyms -= nuseless_nonterminals;
|
||||||
@@ -345,7 +343,7 @@ nonterminals_reduce (void)
|
|||||||
void
|
void
|
||||||
reduce_output (FILE *out)
|
reduce_output (FILE *out)
|
||||||
{
|
{
|
||||||
if (nuseless_nonterminals > 0)
|
if (nuseless_nonterminals)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
fprintf (out, "%s\n\n", _("Nonterminals useless in grammar"));
|
fprintf (out, "%s\n\n", _("Nonterminals useless in grammar"));
|
||||||
@@ -357,7 +355,7 @@ reduce_output (FILE *out)
|
|||||||
{
|
{
|
||||||
bool b = false;
|
bool b = false;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < ntokens; i++)
|
for (i = 0; i < ntokens; ++i)
|
||||||
if (reduce_token_unused_in_grammar (i))
|
if (reduce_token_unused_in_grammar (i))
|
||||||
{
|
{
|
||||||
if (!b)
|
if (!b)
|
||||||
@@ -369,7 +367,7 @@ reduce_output (FILE *out)
|
|||||||
fputs ("\n\n", out);
|
fputs ("\n\n", out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nuseless_productions > 0)
|
if (nuseless_productions)
|
||||||
grammar_rules_partial_print (out, _("Rules useless in grammar"),
|
grammar_rules_partial_print (out, _("Rules useless in grammar"),
|
||||||
rule_useless_in_grammar_p);
|
rule_useless_in_grammar_p);
|
||||||
}
|
}
|
||||||
@@ -382,12 +380,12 @@ reduce_output (FILE *out)
|
|||||||
static void
|
static void
|
||||||
reduce_print (void)
|
reduce_print (void)
|
||||||
{
|
{
|
||||||
if (nuseless_nonterminals > 0)
|
if (nuseless_nonterminals)
|
||||||
complain (NULL, Wother, ngettext ("%d nonterminal useless in grammar",
|
complain (NULL, Wother, ngettext ("%d nonterminal useless in grammar",
|
||||||
"%d nonterminals useless in grammar",
|
"%d nonterminals useless in grammar",
|
||||||
nuseless_nonterminals),
|
nuseless_nonterminals),
|
||||||
nuseless_nonterminals);
|
nuseless_nonterminals);
|
||||||
if (nuseless_productions > 0)
|
if (nuseless_productions)
|
||||||
complain (NULL, Wother, ngettext ("%d rule useless in grammar",
|
complain (NULL, Wother, ngettext ("%d rule useless in grammar",
|
||||||
"%d rules useless in grammar",
|
"%d rules useless in grammar",
|
||||||
nuseless_productions),
|
nuseless_productions),
|
||||||
@@ -397,8 +395,6 @@ reduce_print (void)
|
|||||||
void
|
void
|
||||||
reduce_grammar (void)
|
reduce_grammar (void)
|
||||||
{
|
{
|
||||||
bool reduced;
|
|
||||||
|
|
||||||
/* Allocate the global sets used to compute the reduced grammar */
|
/* Allocate the global sets used to compute the reduced grammar */
|
||||||
|
|
||||||
N = bitset_create (nvars, BITSET_FIXED);
|
N = bitset_create (nvars, BITSET_FIXED);
|
||||||
@@ -409,13 +405,13 @@ reduce_grammar (void)
|
|||||||
useless_nonterminals ();
|
useless_nonterminals ();
|
||||||
inaccessable_symbols ();
|
inaccessable_symbols ();
|
||||||
|
|
||||||
reduced = (nuseless_nonterminals + nuseless_productions > 0);
|
/* Did we reduce something? */
|
||||||
if (!reduced)
|
if (!nuseless_nonterminals && !nuseless_productions)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
reduce_print ();
|
reduce_print ();
|
||||||
|
|
||||||
if (!bitset_test (N, accept->number - ntokens))
|
if (!bitset_test (N, accept->content->number - ntokens))
|
||||||
complain (&startsymbol_location, fatal,
|
complain (&startsymbol_location, fatal,
|
||||||
_("start symbol %s does not derive any sentence"),
|
_("start symbol %s does not derive any sentence"),
|
||||||
startsymbol->tag);
|
startsymbol->tag);
|
||||||
@@ -423,9 +419,9 @@ reduce_grammar (void)
|
|||||||
/* First reduce the nonterminals, as they renumber themselves in the
|
/* First reduce the nonterminals, as they renumber themselves in the
|
||||||
whole grammar. If you change the order, nonterms would be
|
whole grammar. If you change the order, nonterms would be
|
||||||
renumbered only in the reduced grammar. */
|
renumbered only in the reduced grammar. */
|
||||||
if (nuseless_nonterminals > 0)
|
if (nuseless_nonterminals)
|
||||||
nonterminals_reduce ();
|
nonterminals_reduce ();
|
||||||
if (nuseless_productions > 0)
|
if (nuseless_productions)
|
||||||
reduce_grammar_tables ();
|
reduce_grammar_tables ();
|
||||||
|
|
||||||
if (trace_flag & trace_grammar)
|
if (trace_flag & trace_grammar)
|
||||||
@@ -446,10 +442,11 @@ reduce_token_unused_in_grammar (symbol_number i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
reduce_nonterminal_useless_in_grammar (symbol_number i)
|
reduce_nonterminal_useless_in_grammar (const sym_content *sym)
|
||||||
{
|
{
|
||||||
aver (ntokens <= i && i < nsyms + nuseless_nonterminals);
|
symbol_number n = sym->number;
|
||||||
return nsyms <= i;
|
aver (ntokens <= n && n < nsyms + nuseless_nonterminals);
|
||||||
|
return nsyms <= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------.
|
/*-----------------------------------------------------------.
|
||||||
|
|||||||
+8
-3
@@ -24,9 +24,14 @@
|
|||||||
void reduce_grammar (void);
|
void reduce_grammar (void);
|
||||||
void reduce_output (FILE *out);
|
void reduce_output (FILE *out);
|
||||||
bool reduce_token_unused_in_grammar (symbol_number i);
|
bool reduce_token_unused_in_grammar (symbol_number i);
|
||||||
bool reduce_nonterminal_useless_in_grammar (symbol_number i);
|
|
||||||
|
/** Whether symbol \a i is useless in the grammar.
|
||||||
|
* \pre reduce_grammar was called before.
|
||||||
|
*/
|
||||||
|
bool reduce_nonterminal_useless_in_grammar (const sym_content *sym);
|
||||||
|
|
||||||
void reduce_free (void);
|
void reduce_free (void);
|
||||||
|
|
||||||
extern symbol_number nuseless_nonterminals;
|
extern unsigned nuseless_nonterminals;
|
||||||
extern rule_number nuseless_productions;
|
extern unsigned nuseless_productions;
|
||||||
#endif /* !REDUCE_H_ */
|
#endif /* !REDUCE_H_ */
|
||||||
|
|||||||
+1
-1
@@ -135,7 +135,7 @@ typedef struct
|
|||||||
/* Is the TRANSITIONS->states[Num] labelled by the error token? */
|
/* Is the TRANSITIONS->states[Num] labelled by the error token? */
|
||||||
|
|
||||||
# define TRANSITION_IS_ERROR(Transitions, Num) \
|
# 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
|
/* When resolving a SR conflicts, if the reduction wins, the shift is
|
||||||
disabled. */
|
disabled. */
|
||||||
|
|||||||
+3
-3
@@ -192,7 +192,7 @@ symbol_list_n_get (symbol_list *l, int n)
|
|||||||
uniqstr
|
uniqstr
|
||||||
symbol_list_n_type_name_get (symbol_list *l, int n)
|
symbol_list_n_type_name_get (symbol_list *l, int n)
|
||||||
{
|
{
|
||||||
return symbol_list_n_get (l, n)->content.sym->type_name;
|
return symbol_list_n_get (l, n)->content.sym->content->type_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -210,8 +210,8 @@ symbol_list_code_props_set (symbol_list *node, code_props_type kind,
|
|||||||
{
|
{
|
||||||
case SYMLIST_SYMBOL:
|
case SYMLIST_SYMBOL:
|
||||||
symbol_code_props_set (node->content.sym, kind, cprops);
|
symbol_code_props_set (node->content.sym, kind, cprops);
|
||||||
if (node->content.sym->status == undeclared)
|
if (node->content.sym->content->status == undeclared)
|
||||||
node->content.sym->status = used;
|
node->content.sym->content->status = used;
|
||||||
break;
|
break;
|
||||||
case SYMLIST_TYPE:
|
case SYMLIST_TYPE:
|
||||||
semantic_type_code_props_set
|
semantic_type_code_props_set
|
||||||
|
|||||||
+185
-159
@@ -58,6 +58,35 @@ static symgraph **prec_nodes;
|
|||||||
|
|
||||||
bool *used_assoc = NULL;
|
bool *used_assoc = NULL;
|
||||||
|
|
||||||
|
/*--------------------------.
|
||||||
|
| Create a new sym_content. |
|
||||||
|
`--------------------------*/
|
||||||
|
|
||||||
|
static sym_content *
|
||||||
|
sym_content_new (symbol *s)
|
||||||
|
{
|
||||||
|
sym_content *res = xmalloc (sizeof *res);
|
||||||
|
|
||||||
|
res->symbol = s;
|
||||||
|
|
||||||
|
res->type_name = NULL;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < CODE_PROPS_SIZE; ++i)
|
||||||
|
code_props_none_init (&res->props[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
res->number = NUMBER_UNDEFINED;
|
||||||
|
res->prec = 0;
|
||||||
|
res->assoc = undef_assoc;
|
||||||
|
res->user_token_number = USER_NUMBER_UNDEFINED;
|
||||||
|
|
||||||
|
res->class = unknown_sym;
|
||||||
|
res->status = undeclared;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------.
|
/*---------------------------------.
|
||||||
| Create a new symbol, named TAG. |
|
| Create a new symbol, named TAG. |
|
||||||
`---------------------------------*/
|
`---------------------------------*/
|
||||||
@@ -76,22 +105,10 @@ symbol_new (uniqstr tag, location loc)
|
|||||||
|
|
||||||
res->tag = tag;
|
res->tag = tag;
|
||||||
res->location = loc;
|
res->location = loc;
|
||||||
|
res->location_of_lhs = false;
|
||||||
res->type_name = NULL;
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < CODE_PROPS_SIZE; ++i)
|
|
||||||
code_props_none_init (&res->props[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
res->number = NUMBER_UNDEFINED;
|
|
||||||
res->prec = 0;
|
|
||||||
res->assoc = undef_assoc;
|
|
||||||
res->user_token_number = USER_NUMBER_UNDEFINED;
|
|
||||||
|
|
||||||
res->alias = NULL;
|
res->alias = NULL;
|
||||||
res->class = unknown_sym;
|
res->content = sym_content_new (res);
|
||||||
res->status = undeclared;
|
res->is_alias = false;
|
||||||
|
|
||||||
if (nsyms == SYMBOL_NUMBER_MAXIMUM)
|
if (nsyms == SYMBOL_NUMBER_MAXIMUM)
|
||||||
complain (NULL, fatal, _("too many symbols in input grammar (limit is %d)"),
|
complain (NULL, fatal, _("too many symbols in input grammar (limit is %d)"),
|
||||||
@@ -100,6 +117,31 @@ symbol_new (uniqstr tag, location loc)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*--------------------.
|
||||||
|
| Free a sym_content. |
|
||||||
|
`--------------------*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
sym_content_free (sym_content *sym)
|
||||||
|
{
|
||||||
|
free (sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------.
|
||||||
|
| Free a symbol and its associated content if appropriate. |
|
||||||
|
`---------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
symbol_free (void *ptr)
|
||||||
|
{
|
||||||
|
symbol *sym = (symbol *)ptr;
|
||||||
|
if (!sym->is_alias)
|
||||||
|
sym_content_free (sym->content);
|
||||||
|
free (sym);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* If needed, swap first and second so that first has the earliest
|
/* If needed, swap first and second so that first has the earliest
|
||||||
location (according to location_cmp).
|
location (according to location_cmp).
|
||||||
|
|
||||||
@@ -148,6 +190,7 @@ code_props_type_string (code_props_type kind)
|
|||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------.
|
/*----------------------------------------.
|
||||||
| Create a new semantic type, named TAG. |
|
| Create a new semantic type, named TAG. |
|
||||||
`----------------------------------------*/
|
`----------------------------------------*/
|
||||||
@@ -176,12 +219,12 @@ semantic_type_new (uniqstr tag, const location *loc)
|
|||||||
`-----------------*/
|
`-----------------*/
|
||||||
|
|
||||||
#define SYMBOL_ATTR_PRINT(Attr) \
|
#define SYMBOL_ATTR_PRINT(Attr) \
|
||||||
if (s->Attr) \
|
if (s->content->Attr) \
|
||||||
fprintf (f, " %s { %s }", #Attr, s->Attr)
|
fprintf (f, " %s { %s }", #Attr, s->content->Attr)
|
||||||
|
|
||||||
#define SYMBOL_CODE_PRINT(Attr) \
|
#define SYMBOL_CODE_PRINT(Attr) \
|
||||||
if (s->props[Attr].code) \
|
if (s->content->props[Attr].code) \
|
||||||
fprintf (f, " %s { %s }", #Attr, s->props[Attr].code)
|
fprintf (f, " %s { %s }", #Attr, s->content->props[Attr].code)
|
||||||
|
|
||||||
void
|
void
|
||||||
symbol_print (symbol const *s, FILE *f)
|
symbol_print (symbol const *s, FILE *f)
|
||||||
@@ -228,7 +271,6 @@ is_identifier (uniqstr s)
|
|||||||
uniqstr
|
uniqstr
|
||||||
symbol_id_get (symbol const *sym)
|
symbol_id_get (symbol const *sym)
|
||||||
{
|
{
|
||||||
aver (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS);
|
|
||||||
if (sym->alias)
|
if (sym->alias)
|
||||||
sym = sym->alias;
|
sym = sym->alias;
|
||||||
return is_identifier (sym->tag) ? sym->tag : 0;
|
return is_identifier (sym->tag) ? sym->tag : 0;
|
||||||
@@ -267,6 +309,13 @@ semantic_type_redeclaration (semantic_type *s, const char *what, location first,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
symbol_location_as_lhs_set (symbol *sym, location loc)
|
||||||
|
{
|
||||||
|
if (!sym->location_of_lhs)
|
||||||
|
sym->location = loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------.
|
/*-----------------------------------------------------------------.
|
||||||
| Set the TYPE_NAME associated with SYM. Does nothing if passed 0 |
|
| Set the TYPE_NAME associated with SYM. Does nothing if passed 0 |
|
||||||
@@ -278,13 +327,13 @@ symbol_type_set (symbol *sym, uniqstr type_name, location loc)
|
|||||||
{
|
{
|
||||||
if (type_name)
|
if (type_name)
|
||||||
{
|
{
|
||||||
if (sym->type_name)
|
if (sym->content->type_name)
|
||||||
symbol_redeclaration (sym, "%type", sym->type_location, loc);
|
symbol_redeclaration (sym, "%type", sym->content->type_location, loc);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uniqstr_assert (type_name);
|
uniqstr_assert (type_name);
|
||||||
sym->type_name = type_name;
|
sym->content->type_name = type_name;
|
||||||
sym->type_location = loc;
|
sym->content->type_location = loc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -297,12 +346,12 @@ void
|
|||||||
symbol_code_props_set (symbol *sym, code_props_type kind,
|
symbol_code_props_set (symbol *sym, code_props_type kind,
|
||||||
code_props const *code)
|
code_props const *code)
|
||||||
{
|
{
|
||||||
if (sym->props[kind].code)
|
if (sym->content->props[kind].code)
|
||||||
symbol_redeclaration (sym, code_props_type_string (kind),
|
symbol_redeclaration (sym, code_props_type_string (kind),
|
||||||
sym->props[kind].location,
|
sym->content->props[kind].location,
|
||||||
code->location);
|
code->location);
|
||||||
else
|
else
|
||||||
sym->props[kind] = *code;
|
sym->content->props[kind] = *code;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------.
|
/*-----------------------------------------------------.
|
||||||
@@ -330,14 +379,14 @@ code_props *
|
|||||||
symbol_code_props_get (symbol *sym, code_props_type kind)
|
symbol_code_props_get (symbol *sym, code_props_type kind)
|
||||||
{
|
{
|
||||||
/* Per-symbol code props. */
|
/* Per-symbol code props. */
|
||||||
if (sym->props[kind].code)
|
if (sym->content->props[kind].code)
|
||||||
return &sym->props[kind];
|
return &sym->content->props[kind];
|
||||||
|
|
||||||
/* Per-type code props. */
|
/* Per-type code props. */
|
||||||
if (sym->type_name)
|
if (sym->content->type_name)
|
||||||
{
|
{
|
||||||
code_props *code =
|
code_props *code =
|
||||||
&semantic_type_get (sym->type_name, NULL)->props[kind];
|
&semantic_type_get (sym->content->type_name, NULL)->props[kind];
|
||||||
if (code->code)
|
if (code->code)
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
@@ -345,8 +394,8 @@ symbol_code_props_get (symbol *sym, code_props_type kind)
|
|||||||
/* Apply default code props's only to user-defined symbols. */
|
/* Apply default code props's only to user-defined symbols. */
|
||||||
if (sym->tag[0] != '$' && sym != errtoken)
|
if (sym->tag[0] != '$' && sym != errtoken)
|
||||||
{
|
{
|
||||||
code_props *code =
|
code_props *code = &semantic_type_get (sym->content->type_name ? "*" : "",
|
||||||
&semantic_type_get (sym->type_name ? "*" : "", NULL)->props[kind];
|
NULL)->props[kind];
|
||||||
if (code->code)
|
if (code->code)
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
@@ -361,16 +410,17 @@ symbol_code_props_get (symbol *sym, code_props_type kind)
|
|||||||
void
|
void
|
||||||
symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
|
symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
|
||||||
{
|
{
|
||||||
|
sym_content *s = sym->content;
|
||||||
if (a != undef_assoc)
|
if (a != undef_assoc)
|
||||||
{
|
{
|
||||||
if (sym->prec)
|
if (s->prec)
|
||||||
symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
|
symbol_redeclaration (sym, assoc_to_string (a),
|
||||||
loc);
|
s->prec_location, loc);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sym->prec = prec;
|
s->prec = prec;
|
||||||
sym->assoc = a;
|
s->assoc = a;
|
||||||
sym->prec_location = loc;
|
s->prec_location = loc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,26 +437,26 @@ void
|
|||||||
symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
|
symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
|
||||||
{
|
{
|
||||||
bool warned = false;
|
bool warned = false;
|
||||||
if (sym->class != unknown_sym && sym->class != class)
|
if (sym->content->class != unknown_sym && sym->content->class != class)
|
||||||
{
|
{
|
||||||
complain (&loc, complaint, _("symbol %s redefined"), sym->tag);
|
complain (&loc, complaint, _("symbol %s redefined"), sym->tag);
|
||||||
/* Don't report both "redefined" and "redeclared". */
|
/* Don't report both "redefined" and "redeclared". */
|
||||||
warned = true;
|
warned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (class == nterm_sym && sym->class != nterm_sym)
|
if (class == nterm_sym && sym->content->class != nterm_sym)
|
||||||
sym->number = nvars++;
|
sym->content->number = nvars++;
|
||||||
else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
|
else if (class == token_sym && sym->content->number == NUMBER_UNDEFINED)
|
||||||
sym->number = ntokens++;
|
sym->content->number = ntokens++;
|
||||||
|
|
||||||
sym->class = class;
|
sym->content->class = class;
|
||||||
|
|
||||||
if (declaring)
|
if (declaring)
|
||||||
{
|
{
|
||||||
if (sym->status == declared && !warned)
|
if (sym->content->status == declared && !warned)
|
||||||
complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
|
complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
|
||||||
else
|
else
|
||||||
sym->status = declared;
|
sym->content->status = declared;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,10 +470,7 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
|
|||||||
{
|
{
|
||||||
int *user_token_numberp;
|
int *user_token_numberp;
|
||||||
|
|
||||||
if (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
|
user_token_numberp = &sym->content->user_token_number;
|
||||||
user_token_numberp = &sym->user_token_number;
|
|
||||||
else
|
|
||||||
user_token_numberp = &sym->alias->user_token_number;
|
|
||||||
if (*user_token_numberp != USER_NUMBER_UNDEFINED
|
if (*user_token_numberp != USER_NUMBER_UNDEFINED
|
||||||
&& *user_token_numberp != user_token_number)
|
&& *user_token_numberp != user_token_number)
|
||||||
complain (&loc, complaint, _("redefining user token number of %s"),
|
complain (&loc, complaint, _("redefining user token number of %s"),
|
||||||
@@ -433,12 +480,12 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
|
|||||||
/* User defined $end token? */
|
/* User defined $end token? */
|
||||||
if (user_token_number == 0)
|
if (user_token_number == 0)
|
||||||
{
|
{
|
||||||
endtoken = sym;
|
endtoken = sym->content->symbol;
|
||||||
/* It is always mapped to 0, so it was already counted in
|
/* It is always mapped to 0, so it was already counted in
|
||||||
NTOKENS. */
|
NTOKENS. */
|
||||||
if (endtoken->number != NUMBER_UNDEFINED)
|
if (endtoken->content->number != NUMBER_UNDEFINED)
|
||||||
--ntokens;
|
--ntokens;
|
||||||
endtoken->number = 0;
|
endtoken->content->number = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,16 +498,17 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
|
|||||||
static inline bool
|
static inline bool
|
||||||
symbol_check_defined (symbol *sym)
|
symbol_check_defined (symbol *sym)
|
||||||
{
|
{
|
||||||
if (sym->class == unknown_sym)
|
sym_content *s = sym->content;
|
||||||
|
if (s->class == unknown_sym)
|
||||||
{
|
{
|
||||||
assert (sym->status != declared);
|
assert (s->status != declared);
|
||||||
complain (&sym->location,
|
complain (&sym->location,
|
||||||
sym->status == needed ? complaint : Wother,
|
s->status == needed ? complaint : Wother,
|
||||||
_("symbol %s is used, but is not defined as a token"
|
_("symbol %s is used, but is not defined as a token"
|
||||||
" and has no rules"),
|
" and has no rules"),
|
||||||
sym->tag);
|
sym->tag);
|
||||||
sym->class = nterm_sym;
|
s->class = nterm_sym;
|
||||||
sym->number = nvars++;
|
s->number = nvars++;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -471,9 +519,9 @@ symbol_check_defined (symbol *sym)
|
|||||||
|
|
||||||
/* Set the semantic type status associated to the current symbol to
|
/* Set the semantic type status associated to the current symbol to
|
||||||
'declared' so that we could check semantic types unnecessary uses. */
|
'declared' so that we could check semantic types unnecessary uses. */
|
||||||
if (sym->type_name)
|
if (s->type_name)
|
||||||
{
|
{
|
||||||
semantic_type *sem_type = semantic_type_get (sym->type_name, NULL);
|
semantic_type *sem_type = semantic_type_get (s->type_name, NULL);
|
||||||
if (sem_type)
|
if (sem_type)
|
||||||
sem_type->status = declared;
|
sem_type->status = declared;
|
||||||
}
|
}
|
||||||
@@ -519,6 +567,45 @@ semantic_type_check_defined_processor (void *sem_type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------.
|
||||||
|
| Merge the properties (precedence, associativity, etc.) of SYM, and |
|
||||||
|
| its string-named alias STR; check consistency. |
|
||||||
|
`-------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
symbol_merge_properties (symbol *sym, symbol *str)
|
||||||
|
{
|
||||||
|
if (str->content->type_name != sym->content->type_name)
|
||||||
|
{
|
||||||
|
if (str->content->type_name)
|
||||||
|
symbol_type_set (sym,
|
||||||
|
str->content->type_name, str->content->type_location);
|
||||||
|
else
|
||||||
|
symbol_type_set (str,
|
||||||
|
sym->content->type_name, sym->content->type_location);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < CODE_PROPS_SIZE; ++i)
|
||||||
|
if (str->content->props[i].code)
|
||||||
|
symbol_code_props_set (sym, i, &str->content->props[i]);
|
||||||
|
else if (sym->content->props[i].code)
|
||||||
|
symbol_code_props_set (str, i, &sym->content->props[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sym->content->prec || str->content->prec)
|
||||||
|
{
|
||||||
|
if (str->content->prec)
|
||||||
|
symbol_precedence_set (sym, str->content->prec, str->content->assoc,
|
||||||
|
str->content->prec_location);
|
||||||
|
else
|
||||||
|
symbol_precedence_set (str, sym->content->prec, sym->content->assoc,
|
||||||
|
sym->content->prec_location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
symbol_make_alias (symbol *sym, symbol *str, location loc)
|
symbol_make_alias (symbol *sym, symbol *str, location loc)
|
||||||
{
|
{
|
||||||
@@ -530,71 +617,17 @@ symbol_make_alias (symbol *sym, symbol *str, location loc)
|
|||||||
_("symbol %s given more than one literal string"), sym->tag);
|
_("symbol %s given more than one literal string"), sym->tag);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
str->class = token_sym;
|
symbol_merge_properties (sym, str);
|
||||||
str->user_token_number = sym->user_token_number;
|
sym_content_free (str->content);
|
||||||
sym->user_token_number = USER_NUMBER_HAS_STRING_ALIAS;
|
str->content = sym->content;
|
||||||
|
str->content->symbol = str;
|
||||||
|
str->is_alias = true;
|
||||||
str->alias = sym;
|
str->alias = sym;
|
||||||
sym->alias = str;
|
sym->alias = str;
|
||||||
str->number = sym->number;
|
|
||||||
symbol_type_set (str, sym->type_name, loc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------.
|
|
||||||
| Check that THIS, and its alias, have same precedence and |
|
|
||||||
| associativity. |
|
|
||||||
`---------------------------------------------------------*/
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
symbol_check_alias_consistency (symbol *this)
|
|
||||||
{
|
|
||||||
symbol *sym = this;
|
|
||||||
symbol *str = this->alias;
|
|
||||||
|
|
||||||
/* Check only the symbol in the symbol-string pair. */
|
|
||||||
if (!(this->alias
|
|
||||||
&& this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (str->type_name != sym->type_name)
|
|
||||||
{
|
|
||||||
if (str->type_name)
|
|
||||||
symbol_type_set (sym, str->type_name, str->type_location);
|
|
||||||
else
|
|
||||||
symbol_type_set (str, sym->type_name, sym->type_location);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < CODE_PROPS_SIZE; ++i)
|
|
||||||
if (str->props[i].code)
|
|
||||||
symbol_code_props_set (sym, i, &str->props[i]);
|
|
||||||
else if (sym->props[i].code)
|
|
||||||
symbol_code_props_set (str, i, &sym->props[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sym->prec || str->prec)
|
|
||||||
{
|
|
||||||
if (str->prec)
|
|
||||||
symbol_precedence_set (sym, str->prec, str->assoc,
|
|
||||||
str->prec_location);
|
|
||||||
else
|
|
||||||
symbol_precedence_set (str, sym->prec, sym->assoc,
|
|
||||||
sym->prec_location);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
symbol_check_alias_consistency_processor (void *this,
|
|
||||||
void *null ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
symbol_check_alias_consistency (this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------.
|
/*-------------------------------------------------------------------.
|
||||||
| Assign a symbol number, and write the definition of the token name |
|
| Assign a symbol number, and write the definition of the token name |
|
||||||
| into FDEFINES. Put in SYMBOLS. |
|
| into FDEFINES. Put in SYMBOLS. |
|
||||||
@@ -603,13 +636,11 @@ symbol_check_alias_consistency_processor (void *this,
|
|||||||
static inline bool
|
static inline bool
|
||||||
symbol_pack (symbol *this)
|
symbol_pack (symbol *this)
|
||||||
{
|
{
|
||||||
aver (this->number != NUMBER_UNDEFINED);
|
aver (this->content->number != NUMBER_UNDEFINED);
|
||||||
if (this->class == nterm_sym)
|
if (this->content->class == nterm_sym)
|
||||||
this->number += ntokens;
|
this->content->number += ntokens;
|
||||||
else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
symbols[this->number] = this;
|
symbols[this->content->number] = this->content->symbol;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,7 +650,6 @@ symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
|
|||||||
return symbol_pack (this);
|
return symbol_pack (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
user_token_number_redeclaration (int num, symbol *first, symbol *second)
|
user_token_number_redeclaration (int num, symbol *first, symbol *second)
|
||||||
{
|
{
|
||||||
@@ -642,17 +672,18 @@ static inline bool
|
|||||||
symbol_translation (symbol *this)
|
symbol_translation (symbol *this)
|
||||||
{
|
{
|
||||||
/* Non-terminal? */
|
/* Non-terminal? */
|
||||||
if (this->class == token_sym
|
if (this->content->class == token_sym
|
||||||
&& this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
|
&& !this->is_alias)
|
||||||
{
|
{
|
||||||
/* A token which translation has already been set? */
|
/* A token which translation has already been set?*/
|
||||||
if (token_translations[this->user_token_number] != undeftoken->number)
|
if (token_translations[this->content->user_token_number]
|
||||||
|
!= undeftoken->content->number)
|
||||||
user_token_number_redeclaration
|
user_token_number_redeclaration
|
||||||
(this->user_token_number,
|
(this->content->user_token_number,
|
||||||
symbols[token_translations[this->user_token_number]],
|
symbols[token_translations[this->content->user_token_number]], this);
|
||||||
this);
|
|
||||||
else
|
else
|
||||||
token_translations[this->user_token_number] = this->number;
|
token_translations[this->content->user_token_number]
|
||||||
|
= this->content->number;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -738,7 +769,7 @@ symbols_new (void)
|
|||||||
NULL,
|
NULL,
|
||||||
hash_symbol_hasher,
|
hash_symbol_hasher,
|
||||||
hash_symbol_comparator,
|
hash_symbol_comparator,
|
||||||
free);
|
symbol_free);
|
||||||
semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
|
semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
|
||||||
NULL,
|
NULL,
|
||||||
hash_semantic_type_hasher,
|
hash_semantic_type_hasher,
|
||||||
@@ -838,8 +869,8 @@ dummy_symbol_get (location loc)
|
|||||||
|
|
||||||
sprintf (buf, "$@%d", ++dummy_count);
|
sprintf (buf, "$@%d", ++dummy_count);
|
||||||
sym = symbol_get (buf, loc);
|
sym = symbol_get (buf, loc);
|
||||||
sym->class = nterm_sym;
|
sym->content->class = nterm_sym;
|
||||||
sym->number = nvars++;
|
sym->content->number = nvars++;
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -929,7 +960,7 @@ symbols_token_translations_init (void)
|
|||||||
max_user_token_number = 0;
|
max_user_token_number = 0;
|
||||||
for (i = 0; i < ntokens; ++i)
|
for (i = 0; i < ntokens; ++i)
|
||||||
{
|
{
|
||||||
symbol *this = symbols[i];
|
sym_content *this = symbols[i]->content;
|
||||||
if (this->user_token_number != USER_NUMBER_UNDEFINED)
|
if (this->user_token_number != USER_NUMBER_UNDEFINED)
|
||||||
{
|
{
|
||||||
if (this->user_token_number > max_user_token_number)
|
if (this->user_token_number > max_user_token_number)
|
||||||
@@ -941,8 +972,8 @@ symbols_token_translations_init (void)
|
|||||||
|
|
||||||
/* If 256 is not used, assign it to error, to follow POSIX. */
|
/* If 256 is not used, assign it to error, to follow POSIX. */
|
||||||
if (num_256_available_p
|
if (num_256_available_p
|
||||||
&& errtoken->user_token_number == USER_NUMBER_UNDEFINED)
|
&& errtoken->content->user_token_number == USER_NUMBER_UNDEFINED)
|
||||||
errtoken->user_token_number = 256;
|
errtoken->content->user_token_number = 256;
|
||||||
|
|
||||||
/* Set the missing user numbers. */
|
/* Set the missing user numbers. */
|
||||||
if (max_user_token_number < 256)
|
if (max_user_token_number < 256)
|
||||||
@@ -950,7 +981,7 @@ symbols_token_translations_init (void)
|
|||||||
|
|
||||||
for (i = 0; i < ntokens; ++i)
|
for (i = 0; i < ntokens; ++i)
|
||||||
{
|
{
|
||||||
symbol *this = symbols[i];
|
sym_content *this = symbols[i]->content;
|
||||||
if (this->user_token_number == USER_NUMBER_UNDEFINED)
|
if (this->user_token_number == USER_NUMBER_UNDEFINED)
|
||||||
this->user_token_number = ++max_user_token_number;
|
this->user_token_number = ++max_user_token_number;
|
||||||
if (this->user_token_number > max_user_token_number)
|
if (this->user_token_number > max_user_token_number)
|
||||||
@@ -963,7 +994,7 @@ symbols_token_translations_init (void)
|
|||||||
/* Initialize all entries for literal tokens to the internal token
|
/* Initialize all entries for literal tokens to the internal token
|
||||||
number for $undefined, which represents all invalid inputs. */
|
number for $undefined, which represents all invalid inputs. */
|
||||||
for (i = 0; i < max_user_token_number + 1; i++)
|
for (i = 0; i < max_user_token_number + 1; i++)
|
||||||
token_translations[i] = undeftoken->number;
|
token_translations[i] = undeftoken->content->number;
|
||||||
symbols_do (symbol_translation_processor, NULL,
|
symbols_do (symbol_translation_processor, NULL,
|
||||||
symbol_table, &symbols_sorted);
|
symbol_table, &symbols_sorted);
|
||||||
}
|
}
|
||||||
@@ -977,9 +1008,6 @@ symbols_token_translations_init (void)
|
|||||||
void
|
void
|
||||||
symbols_pack (void)
|
symbols_pack (void)
|
||||||
{
|
{
|
||||||
symbols_do (symbol_check_alias_consistency_processor, NULL,
|
|
||||||
symbol_table, &symbols_sorted);
|
|
||||||
|
|
||||||
symbols = xcalloc (nsyms, sizeof *symbols);
|
symbols = xcalloc (nsyms, sizeof *symbols);
|
||||||
symbols_do (symbol_pack_processor, NULL, symbol_table, &symbols_sorted);
|
symbols_do (symbol_pack_processor, NULL, symbol_table, &symbols_sorted);
|
||||||
|
|
||||||
@@ -998,9 +1026,7 @@ symbols_pack (void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
symbols[writei] = symbols[readi];
|
symbols[writei] = symbols[readi];
|
||||||
symbols[writei]->number = writei;
|
symbols[writei]->content->number = writei;
|
||||||
if (symbols[writei]->alias)
|
|
||||||
symbols[writei]->alias->number = writei;
|
|
||||||
writei += 1;
|
writei += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1009,11 +1035,11 @@ symbols_pack (void)
|
|||||||
|
|
||||||
symbols_token_translations_init ();
|
symbols_token_translations_init ();
|
||||||
|
|
||||||
if (startsymbol->class == unknown_sym)
|
if (startsymbol->content->class == unknown_sym)
|
||||||
complain (&startsymbol_location, fatal,
|
complain (&startsymbol_location, fatal,
|
||||||
_("the start symbol %s is undefined"),
|
_("the start symbol %s is undefined"),
|
||||||
startsymbol->tag);
|
startsymbol->tag);
|
||||||
else if (startsymbol->class == token_sym)
|
else if (startsymbol->content->class == token_sym)
|
||||||
complain (&startsymbol_location, fatal,
|
complain (&startsymbol_location, fatal,
|
||||||
_("the start symbol %s is a token"),
|
_("the start symbol %s is a token"),
|
||||||
startsymbol->tag);
|
startsymbol->tag);
|
||||||
@@ -1150,9 +1176,9 @@ static inline bool
|
|||||||
is_assoc_useless (symbol *s)
|
is_assoc_useless (symbol *s)
|
||||||
{
|
{
|
||||||
return s
|
return s
|
||||||
&& s->assoc != undef_assoc
|
&& s->content->assoc != undef_assoc
|
||||||
&& s->assoc != precedence_assoc
|
&& s->content->assoc != precedence_assoc
|
||||||
&& !used_assoc[s->number];
|
&& !used_assoc[s->content->number];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------.
|
/*-------------------------------.
|
||||||
@@ -1184,19 +1210,19 @@ print_precedence_warnings (void)
|
|||||||
{
|
{
|
||||||
symbol *s = symbols[i];
|
symbol *s = symbols[i];
|
||||||
if (s
|
if (s
|
||||||
&& s->prec != 0
|
&& s->content->prec != 0
|
||||||
&& !prec_nodes[i]->pred
|
&& !prec_nodes[i]->pred
|
||||||
&& !prec_nodes[i]->succ)
|
&& !prec_nodes[i]->succ)
|
||||||
{
|
{
|
||||||
if (is_assoc_useless (s))
|
if (is_assoc_useless (s))
|
||||||
complain (&s->prec_location, Wprecedence,
|
complain (&s->content->prec_location, Wprecedence,
|
||||||
_("useless precedence and associativity for %s"), s->tag);
|
_("useless precedence and associativity for %s"), s->tag);
|
||||||
else if (s->assoc == precedence_assoc)
|
else if (s->content->assoc == precedence_assoc)
|
||||||
complain (&s->prec_location, Wprecedence,
|
complain (&s->content->prec_location, Wprecedence,
|
||||||
_("useless precedence for %s"), s->tag);
|
_("useless precedence for %s"), s->tag);
|
||||||
}
|
}
|
||||||
else if (is_assoc_useless (s))
|
else if (is_assoc_useless (s))
|
||||||
complain (&s->prec_location, Wprecedence,
|
complain (&s->content->prec_location, Wprecedence,
|
||||||
_("useless associativity for %s, use %%precedence"), s->tag);
|
_("useless associativity for %s, use %%precedence"), s->tag);
|
||||||
}
|
}
|
||||||
free (used_assoc);
|
free (used_assoc);
|
||||||
|
|||||||
+31
-13
@@ -50,6 +50,7 @@ typedef int symbol_number;
|
|||||||
|
|
||||||
|
|
||||||
typedef struct symbol symbol;
|
typedef struct symbol symbol;
|
||||||
|
typedef struct sym_content sym_content;
|
||||||
|
|
||||||
/* Declaration status of a symbol.
|
/* Declaration status of a symbol.
|
||||||
|
|
||||||
@@ -82,15 +83,36 @@ typedef enum code_props_type code_props_type;
|
|||||||
|
|
||||||
enum { CODE_PROPS_SIZE = 2 };
|
enum { CODE_PROPS_SIZE = 2 };
|
||||||
|
|
||||||
/* When extending this structure, be sure to complete
|
|
||||||
symbol_check_alias_consistency. */
|
|
||||||
struct symbol
|
struct symbol
|
||||||
{
|
{
|
||||||
/** The key, name of the symbol. */
|
/** The key, name of the symbol. */
|
||||||
uniqstr tag;
|
uniqstr tag;
|
||||||
/** The location of its first occurrence. */
|
|
||||||
|
/** The "defining" location. */
|
||||||
location location;
|
location location;
|
||||||
|
|
||||||
|
/** Whether \a location is about the first uses as left-hand side
|
||||||
|
symbol of a rule (true), or simply the first occurrence (e.g.,
|
||||||
|
in a %type, or as a rhs symbol of a rule). The former type of
|
||||||
|
location is more natural in error messages. This Boolean helps
|
||||||
|
moving from location of the first occurrence to first use as
|
||||||
|
lhs. */
|
||||||
|
bool location_of_lhs;
|
||||||
|
|
||||||
|
/** 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.
|
/** Its \c \%type.
|
||||||
|
|
||||||
Beware that this is the type_name as was entered by the user,
|
Beware that this is the type_name as was entered by the user,
|
||||||
@@ -117,10 +139,6 @@ struct symbol
|
|||||||
assoc assoc;
|
assoc assoc;
|
||||||
int user_token_number;
|
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;
|
symbol_class class;
|
||||||
status status;
|
status status;
|
||||||
};
|
};
|
||||||
@@ -128,12 +146,6 @@ struct symbol
|
|||||||
/** Undefined user number. */
|
/** Undefined user number. */
|
||||||
# define USER_NUMBER_UNDEFINED -1
|
# define USER_NUMBER_UNDEFINED -1
|
||||||
|
|
||||||
/* 'symbol->user_token_number == USER_NUMBER_HAS_STRING_ALIAS' means
|
|
||||||
this symbol has a literal string alias. For instance, '%token foo
|
|
||||||
"foo"' has '"foo"' numbered regularly, and 'foo' numbered as
|
|
||||||
USER_NUMBER_HAS_STRING_ALIAS. */
|
|
||||||
# define USER_NUMBER_HAS_STRING_ALIAS -9991
|
|
||||||
|
|
||||||
/* Undefined internal token number. */
|
/* Undefined internal token number. */
|
||||||
# define NUMBER_UNDEFINED (-1)
|
# define NUMBER_UNDEFINED (-1)
|
||||||
|
|
||||||
@@ -174,6 +186,12 @@ uniqstr symbol_id_get (symbol const *sym);
|
|||||||
*/
|
*/
|
||||||
void symbol_make_alias (symbol *sym, symbol *str, location loc);
|
void symbol_make_alias (symbol *sym, symbol *str, location loc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This symbol is used as the lhs of a rule. Record this location
|
||||||
|
* as definition point, if not already done.
|
||||||
|
*/
|
||||||
|
void symbol_location_as_lhs_set (symbol *sym, location loc);
|
||||||
|
|
||||||
/** Set the \c type_name associated with \c sym.
|
/** Set the \c type_name associated with \c sym.
|
||||||
|
|
||||||
Do nothing if passed 0 as \c type_name. */
|
Do nothing if passed 0 as \c type_name. */
|
||||||
|
|||||||
+2
-2
@@ -290,7 +290,7 @@ action_row (state *s)
|
|||||||
|
|
||||||
/* Do not use any default reduction if there is a shift for
|
/* Do not use any default reduction if there is a shift for
|
||||||
error */
|
error */
|
||||||
if (sym == errtoken->number)
|
if (sym == errtoken->content->number)
|
||||||
nodefault = true;
|
nodefault = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,7 +300,7 @@ action_row (state *s)
|
|||||||
for (i = 0; i < errp->num; i++)
|
for (i = 0; i < errp->num; i++)
|
||||||
{
|
{
|
||||||
symbol *sym = errp->symbols[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
|
/* Turn off default reductions where requested by the user. See
|
||||||
|
|||||||
+12
-41
@@ -172,33 +172,6 @@ input.y:13.1-8: warning: nonterminal useless in grammar: useless8 [-Wother]
|
|||||||
input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
|
input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
|
||||||
useless9: '9';
|
useless9: '9';
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
input.y:6.11-13: warning: rule useless in grammar [-Wother]
|
|
||||||
useless1: '1';
|
|
||||||
^^^
|
|
||||||
input.y:7.11-13: warning: rule useless in grammar [-Wother]
|
|
||||||
useless2: '2';
|
|
||||||
^^^
|
|
||||||
input.y:8.11-13: warning: rule useless in grammar [-Wother]
|
|
||||||
useless3: '3';
|
|
||||||
^^^
|
|
||||||
input.y:9.11-13: warning: rule useless in grammar [-Wother]
|
|
||||||
useless4: '4';
|
|
||||||
^^^
|
|
||||||
input.y:10.11-13: warning: rule useless in grammar [-Wother]
|
|
||||||
useless5: '5';
|
|
||||||
^^^
|
|
||||||
input.y:11.11-13: warning: rule useless in grammar [-Wother]
|
|
||||||
useless6: '6';
|
|
||||||
^^^
|
|
||||||
input.y:12.11-13: warning: rule useless in grammar [-Wother]
|
|
||||||
useless7: '7';
|
|
||||||
^^^
|
|
||||||
input.y:13.11-13: warning: rule useless in grammar [-Wother]
|
|
||||||
useless8: '8';
|
|
||||||
^^^
|
|
||||||
input.y:14.11-13: warning: rule useless in grammar [-Wother]
|
|
||||||
useless9: '9';
|
|
||||||
^^^
|
|
||||||
]])
|
]])
|
||||||
|
|
||||||
|
|
||||||
@@ -281,18 +254,12 @@ not-reduced.y: warning: 3 rules useless in grammar [-Wother]
|
|||||||
not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
|
not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
|
||||||
not_reachable: useful { /* A not reachable action. */ }
|
not_reachable: useful { /* A not reachable action. */ }
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive [-Wother]
|
not-reduced.y:17.1-14: warning: nonterminal useless in grammar: non_productive [-Wother]
|
||||||
| non_productive { /* A non productive action. */ }
|
non_productive: non_productive useless_token
|
||||||
^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^
|
||||||
not-reduced.y:11.6-57: warning: rule useless in grammar [-Wother]
|
not-reduced.y:11.6-57: warning: rule useless in grammar [-Wother]
|
||||||
| non_productive { /* A non productive action. */ }
|
| non_productive { /* A non productive action. */ }
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
not-reduced.y:14.16-56: warning: rule useless in grammar [-Wother]
|
|
||||||
not_reachable: useful { /* A not reachable action. */ }
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
not-reduced.y:17.17-18.63: warning: rule useless in grammar [-Wother]
|
|
||||||
non_productive: non_productive useless_token
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
|
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
|
||||||
@@ -360,14 +327,18 @@ underivable: indirection;
|
|||||||
indirection: underivable;
|
indirection: underivable;
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_BISON_CHECK([[input.y]], 0, [],
|
AT_BISON_CHECK([[-fcaret input.y]], 0, [],
|
||||||
[[input.y: warning: 2 nonterminals useless in grammar [-Wother]
|
[[input.y: warning: 2 nonterminals useless in grammar [-Wother]
|
||||||
input.y: warning: 3 rules useless in grammar [-Wother]
|
input.y: warning: 3 rules useless in grammar [-Wother]
|
||||||
input.y:5.15-25: warning: nonterminal useless in grammar: underivable [-Wother]
|
input.y:6.1-11: warning: nonterminal useless in grammar: underivable [-Wother]
|
||||||
input.y:6.14-24: warning: nonterminal useless in grammar: indirection [-Wother]
|
underivable: indirection;
|
||||||
|
^^^^^^^^^^^
|
||||||
|
input.y:7.1-11: warning: nonterminal useless in grammar: indirection [-Wother]
|
||||||
|
indirection: underivable;
|
||||||
|
^^^^^^^^^^^
|
||||||
input.y:5.15-25: warning: rule useless in grammar [-Wother]
|
input.y:5.15-25: warning: rule useless in grammar [-Wother]
|
||||||
input.y:6.14-24: warning: rule useless in grammar [-Wother]
|
exp: useful | underivable;
|
||||||
input.y:7.14-24: warning: rule useless in grammar [-Wother]
|
^^^^^^^^^^^
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
|
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user