[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 10/17] multistart: equip yacc.c
From: |
Akim Demaille |
Subject: |
[PATCH 10/17] multistart: equip yacc.c |
Date: |
Sun, 20 Sep 2020 10:37:42 +0200 |
* data/skeletons/yacc.c: Add support for multiple start symbols.
---
TODO | 4 +++
data/skeletons/yacc.c | 65 +++++++++++++++++++++++++++++++++++++------
2 files changed, 60 insertions(+), 9 deletions(-)
diff --git a/TODO b/TODO
index b8641a97..018247c4 100644
--- a/TODO
+++ b/TODO
@@ -675,6 +675,10 @@ input.y:2.8-10: error: start symbol exp does not derive
any sentence]])
We should say "1 nonterminal": the other one is $accept, which should not
participate in the count.
+*** Tokens
+Do we want to disallow terminal start symbols? The limitation is not
+technical. Can it be useful to someone to "parse" a token?
+
** %include
This is a popular demand. We already made many changes in the parser that
should make this reasonably easy to implement.
diff --git a/data/skeletons/yacc.c b/data/skeletons/yacc.c
index 5e9d7345..5ccd1207 100644
--- a/data/skeletons/yacc.c
+++ b/data/skeletons/yacc.c
@@ -22,6 +22,7 @@ m4_pushdef([b4_copyright_years],
m4_include(b4_skeletonsdir/[c.m4])
+
## ---------- ##
## api.pure. ##
## ---------- ##
@@ -154,13 +155,31 @@ m4_define([b4_rhs_location],
## Declarations. ##
## -------------- ##
+# _b4_declare_sub_yyparse(START-SYMBOL-NUM)
+# -----------------------------------
+m4_define([_b4_declare_sub_yyparse],
+[[int ]b4_prefix[parse_]_b4_symbol($1, id)[ (]m4_ifset([b4_parse_param],
[b4_formals(b4_parse_param)], [void])[);]])
+
+
+# _b4_define_sub_yyparse(START-SYMBOL-NUM, SWITCHING-TOKEN-SYMBOL-NUM)
+# --------------------------------------------------------------------
+m4_define([_b4_define_sub_yyparse],
+[[int
+yyparse_]_b4_symbol($1, id)[ (]m4_ifset([b4_parse_param],
[b4_formals(b4_parse_param)], [void])[)
+{
+ return yyparse_impl (]b4_symbol($2, id)[]m4_ifset([b4_parse_param],
+ [[,
]b4_args(b4_parse_param)])[);
+}]])
+
+
# b4_declare_scanner_communication_variables
# ------------------------------------------
# Declare the variables that are global, or local to YYPARSE if
# pure-parser.
m4_define([b4_declare_scanner_communication_variables], [[
-/* Lookahead token kind. */
-int yychar;
+]m4_ifdef([b4_start_symbols], [],
+[[/* Lookahead token kind. */
+int yychar;]])[
]b4_pure_if([[
/* The semantic value of the lookahead symbol. */
@@ -276,11 +295,14 @@ int ]b4_prefix[push_parse (]b4_prefix[pstate
*ps]b4_pure_if([[,
void ]b4_prefix[pstate_delete (]b4_prefix[pstate *ps);
]])
+
# _b4_declare_yyparse
# -------------------
# When not the push parser.
m4_define([_b4_declare_yyparse],
-[[int ]b4_prefix[parse (]m4_ifset([b4_parse_param],
[b4_formals(b4_parse_param)], [void])[);]])
+[[int ]b4_prefix[parse (]m4_ifset([b4_parse_param],
[b4_formals(b4_parse_param)], [void])[);
+]m4_ifdef([b4_start_symbols],
+ [m4_map([_b4_declare_sub_yyparse], m4_defn([b4_start_symbols]))])])
# b4_declare_yyparse
@@ -291,6 +313,7 @@ m4_define([b4_declare_yyparse],
])
+
# b4_shared_declarations
# ----------------------
# Declaration that might either go into the header (if --header)
@@ -1534,8 +1557,25 @@ yypush_parse (yypstate *yyps]b4_pure_if([[,
| yyparse. |
`----------*/
+]m4_ifdef([b4_start_symbols],
+[[
+static int
+yyparse_impl (int yychar]m4_ifset([b4_parse_param], [,
b4_formals(b4_parse_param)])[);
+
+]m4_map([_b4_define_sub_yyparse], m4_defn([b4_start_symbols]))[
+
int
-yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)],
[void])[)]])[
+yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)], [void])[)
+{
+ /* ]b4_symbol(-2, id)[ causes a token to be read. */
+ return yyparse_impl (]b4_symbol(-2, id)[]m4_ifset([b4_parse_param],
+ [[,
]b4_args(b4_parse_param)])[);
+}
+
+static int
+yyparse_impl (int yychar]m4_ifset([b4_parse_param], [,
b4_formals(b4_parse_param)])[)]],
+[[int
+yyparse (]m4_ifset([b4_parse_param], [b4_formals(b4_parse_param)],
[void])[)]])])[
{]b4_pure_if([b4_declare_scanner_communication_variables
])b4_push_if([b4_pure_if([], [[
int yypushed_char = yychar;
@@ -1585,7 +1625,9 @@ yyparse (]m4_ifset([b4_parse_param],
[b4_formals(b4_parse_param)], [void])[)]])[
YYDPRINTF ((stderr, "Starting parse\n"));
- yychar = ]b4_symbol(-2, id)[; /* Cause a token to be read. */
+]m4_ifdef([b4_start_symbols], [],
+[[ yychar = ]b4_symbol(-2, id)[; /* Cause a token to be read. */
+]])[
]m4_ifdef([b4_initial_action], [
b4_dollar_pushdef([m4_define([b4_dollar_dollar_used])yylval], [], [],
[b4_push_if([b4_pure_if([*])yypushed_loc], [yylloc])])dnl
@@ -1686,8 +1728,9 @@ yysetstate:
}
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
+]m4_ifdef([b4_start_symbols], [], [[
if (yystate == YYFINAL)
- YYACCEPT;
+ YYACCEPT;]])[
goto yybackup;
@@ -1768,9 +1811,11 @@ yyread_pushed_token:]])[
if (yyn <= 0)
{
if (yytable_value_is_error (yyn))
- goto yyerrlab;]b4_lac_if([[
+ goto yyerrlab;
+ yyn = -yyn;]m4_ifdef([b4_start_symbols], [[
+ if (yyr1[yyn] == YYNTOKENS)
+ YYACCEPT;]])[]b4_lac_if([[
YY_LAC_ESTABLISH;]])[
- yyn = -yyn;
goto yyreduce;
}
@@ -1799,7 +1844,9 @@ yyread_pushed_token:]])[
yydefault:
yyn = yydefact[yystate];
if (yyn == 0)
- goto yyerrlab;
+ goto yyerrlab;]m4_ifdef([b4_start_symbols], [[
+ else if (yyr1[yyn] == YYNTOKENS)
+ YYACCEPT;]])[
goto yyreduce;
--
2.28.0
- [PATCH 00/17] RFC: multiple start symbols, Akim Demaille, 2020/09/20
- [PATCH 01/17] gram: more debugging information, Akim Demaille, 2020/09/20
- [PATCH 02/17] reader: get ready to create several initial rules, Akim Demaille, 2020/09/20
- [PATCH 03/17] parser: expose a list of symbols, Akim Demaille, 2020/09/20
- [PATCH 04/17] regen, Akim Demaille, 2020/09/20
- [PATCH 05/17] multistart: turn start symbols into rules on $accept, Akim Demaille, 2020/09/20
- [PATCH 06/17] regen, Akim Demaille, 2020/09/20
- [PATCH 07/17] multistart: adjust computation of initial core and adjust reports, Akim Demaille, 2020/09/20
- [PATCH 08/17] multistart: also check the HTML report, Akim Demaille, 2020/09/20
- [PATCH 09/17] multistart: pass the list of start symbols to the backend, Akim Demaille, 2020/09/20
- [PATCH 10/17] multistart: equip yacc.c,
Akim Demaille <=
- [PATCH 11/17] multistart: toy with it in lexcalc, Akim Demaille, 2020/09/20
- [PATCH 12/17] todo: more, Akim Demaille, 2020/09/20
- [PATCH 13/17] multistart: adjust reader checks for generated rules, Akim Demaille, 2020/09/20
- [PATCH 14/17] multistart: use b4_accept instead of action post-processing, Akim Demaille, 2020/09/20
- [PATCH 15/17] multistart: allow tokens as start symbols, Akim Demaille, 2020/09/20
- [PATCH 16/17] yacc.c: also count calls to YYERROR in yynerrs, Akim Demaille, 2020/09/20
- [PATCH 17/17] multistart: also give access to yynerrs, Akim Demaille, 2020/09/20
- Re: [PATCH 00/17] RFC: multiple start symbols, Paul Eggert, 2020/09/20