[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
PATCH: parser subclass
From: |
Anthony Heading |
Subject: |
PATCH: parser subclass |
Date: |
Sun, 03 Jul 2022 17:46:19 -0400 |
User-agent: |
Cyrus-JMAP/3.7.0-alpha0-713-g1f035dc716-fm-20220617.001-g1f035dc7 |
Another patch I've had for ages and use a lot, this one possibly more
contentious because I recall Akim having reservations on the concept, but that
was maybe 15 years ago and my memory could be wrong.
The idea anyway, is that in a C++ parser it is nice if users can make
unqualified calls in their actions, e.g.
secret-key: "top-secret" { set_lex_flag(ROT13); } key
and have these resolve to a method in the user's parser class.
This isn't possible by default because all the semantic action code is inserted
into the parse() function in the closed bison-generated parser class.
Attached patch invents the 'api.parser.subclass' parameter. If this is
defined, bison generates a parse() member function body for this existing user
class instead. The user's class should inherit the default class, then can
create any additional functions they would like for direct use in actions.
Thoughts welcomed.
Anthony
commit c49947ff0a9ded3f97d19dda2738be18a9a94828
Author: Anthony Heading <anthony.heading@localhost>
Date: Sun Apr 3 16:33:24 2022 -0400
Change 'private' to 'protected' to enable inheritance from the parser
class. Define 'api.parser.subclass' variable to have the generated
parse() function be defined in this class.
diff --git data/skeletons/c++.m4 data/skeletons/c++.m4
index 8b30524b..10ab80ef 100644
--- data/skeletons/c++.m4
+++ data/skeletons/c++.m4
@@ -28,6 +28,7 @@ m4_include(b4_skeletonsdir/[c.m4])
b4_percent_define_check_kind([api.namespace], [code], [deprecated])
b4_percent_define_check_kind([api.parser.class], [code], [deprecated])
+b4_percent_define_check_kind([api.parser.subclass], [code], [deprecated])
## ----- ##
@@ -113,6 +114,8 @@ b4_percent_define_default([[define_location_comparison]],
[m4_if(b4_percent_define_get([[filename_type]]),
[std::string], [[true]], [[false]])])
+b4_percent_define_default([[api.parser.subclass]],
+
[b4_percent_define_get([[api.namespace]])[::]][b4_percent_define_get([[api.parser.class]])])
## ----------- ##
diff --git data/skeletons/lalr1.cc data/skeletons/lalr1.cc
index 7cb69d3d..dcbfc2e2 100644
--- data/skeletons/lalr1.cc
+++ data/skeletons/lalr1.cc
@@ -163,6 +163,8 @@ m4_pushdef([b4_copyright_years],
m4_define([b4_parser_class],
[b4_percent_define_get([[api.parser.class]])])
+m4_define([b4_parser_subclass],
+ [b4_percent_define_get([[api.parser.subclass]])])
b4_bison_locations_if([# Backward compatibility.
m4_define([b4_location_constructors])
@@ -284,13 +286,14 @@ m4_define([b4_shared_declarations],
const symbol_type& yyla_;
};
]])[
- private:
#if YY_CPLUSPLUS < 201103L
+ private:
/// Non copyable.
]b4_parser_class[ (const ]b4_parser_class[&);
/// Non copyable.
]b4_parser_class[& operator= (const ]b4_parser_class[&);
#endif
+ protected:
]b4_lac_if([[
/// Check the lookahead yytoken.
/// \returns true iff the token will be eventually shifted.
@@ -384,7 +387,6 @@ m4_define([b4_shared_declarations],
template <typename Base>
void yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const;
- private:
/// Type access provider for state based symbols.
struct by_state
{
@@ -833,14 +835,16 @@ m4_if(b4_prefix, [yy], [],
return yyvalue == yytable_ninf_;
}
+]b4_namespace_close[
+
int
- ]b4_parser_class[::operator() ()
+ ]b4_parser_subclass[::operator() ()
{
return parse ();
}
int
- ]b4_parser_class[::parse ()
+ ]b4_parser_subclass[::parse ()
{
int yyn;
/// Length of the RHS of the rule being reduced.
@@ -1198,6 +1202,8 @@ b4_dollar_popdef])[]dnl
#endif // YY_EXCEPTIONS
}
+]b4_namespace_open[
+
void
]b4_parser_class[::error (const syntax_error& yyexc)
{
diff --git src/muscle-tab.c src/muscle-tab.c
index 3d3baf13..4bfd4200 100644
--- src/muscle-tab.c
+++ src/muscle-tab.c
@@ -455,6 +455,7 @@ muscle_percent_variable_update (char const *variable,
{ "namespace", "api.namespace", muscle_code },
{ "package", "api.package", muscle_code },
{ "parser_class_name", "api.parser.class", muscle_code },
+ { "parser_subclass_name", "api.parser.subclass", muscle_code },
{ "public", "api.parser.public",
muscle_keyword },
{ "strictfp", "api.parser.strictfp",
muscle_keyword },
{ "stype", "api.value.type", -1 },
subclass.patch
Description: Text Data
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- PATCH: parser subclass,
Anthony Heading <=