Skip to content

Commit d873d7e

Browse files
committed
Provide failover empty symbol table tries for use inside of skippers, since
nothing prevents using a symbol_parser in a skipper, and the previous commit introduced nullptr skipper data tables in some cases. Related to #245
1 parent 1f5303c commit d873d7e

File tree

2 files changed

+92
-3
lines changed

2 files changed

+92
-3
lines changed

doc/tables.qbk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ the input they match unless otherwise stated in the table below.]
330330
[[ _symbols_t_ ]
331331
[ _symbols_ is an associative container of key, value pairs. Each key is a _std_str_ and each value has type `T`. In the Unicode parsing path, the strings are considered to be UTF-8 encoded; in the non-Unicode path, no encoding is assumed. _symbols_ matches the longest prefix `pre` of the input that is equal to one of the keys `k`. If the length `len` of `pre` is zero, and there is no zero-length key, it does not match the input. If `len` is positive, the generated attribute is the value associated with `k`.]
332332
[ `T` ]
333-
[ Unlike the other entries in this table, _symbols_ is a type, not an object. ]]
333+
[ Unlike the other entries in this table, _symbols_ is a type, not an object. Inside of skippers, all _symbols_ will appear empty. ]]
334334

335335
[[ _quot_str_ ]
336336
[ Matches `'"'`, followed by zero or more characters, followed by `'"'`. ]

include/boost/parser/parser.hpp

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,37 @@ namespace boost { namespace parser {
472472
nope_or_pointer_t<Where, true> where_{};
473473
int no_case_depth_ = 0;
474474

475+
// These exist in order to provide an address, if requested, for
476+
// either kind of symbol table struct. The nonstatic member
477+
// pointers for these will be null if this context was created
478+
// inside of detail::skip(), but nothing prevents the user from
479+
// trying to use a symbol_parser anyway. So, we have these.
480+
static std::optional<symbol_table_tries_t>
481+
empty_symbol_table_tries_;
482+
static std::optional<pending_symbol_table_operations_t>
483+
empty_pending_symbol_table_operations_;
484+
485+
symbol_table_tries_t & get_symbol_table_tries() const
486+
{
487+
if (symbol_table_tries_)
488+
return *symbol_table_tries_;
489+
if (!empty_symbol_table_tries_)
490+
empty_symbol_table_tries_ = symbol_table_tries_t();
491+
return *empty_symbol_table_tries_;
492+
}
493+
494+
pending_symbol_table_operations_t &
495+
get_pending_symbol_table_operations() const
496+
{
497+
if (pending_symbol_table_operations_)
498+
return *pending_symbol_table_operations_;
499+
if (!empty_pending_symbol_table_operations_) {
500+
empty_pending_symbol_table_operations_ =
501+
pending_symbol_table_operations_t();
502+
}
503+
return *empty_pending_symbol_table_operations_;
504+
}
505+
475506
template<typename T>
476507
static auto nope_or_address(T & x)
477508
{
@@ -648,6 +679,64 @@ namespace boost { namespace parser {
648679
{}
649680
};
650681

682+
template<
683+
bool DoTrace,
684+
bool UseCallbacks,
685+
typename I,
686+
typename S,
687+
typename ErrorHandler,
688+
typename GlobalState,
689+
typename Callbacks,
690+
typename Attr,
691+
typename Val,
692+
typename RuleTag,
693+
typename RuleLocals,
694+
typename RuleParams,
695+
typename Where>
696+
std::optional<symbol_table_tries_t> parse_context<
697+
DoTrace,
698+
UseCallbacks,
699+
I,
700+
S,
701+
ErrorHandler,
702+
GlobalState,
703+
Callbacks,
704+
Attr,
705+
Val,
706+
RuleTag,
707+
RuleLocals,
708+
RuleParams,
709+
Where>::empty_symbol_table_tries_;
710+
711+
template<
712+
bool DoTrace,
713+
bool UseCallbacks,
714+
typename I,
715+
typename S,
716+
typename ErrorHandler,
717+
typename GlobalState,
718+
typename Callbacks,
719+
typename Attr,
720+
typename Val,
721+
typename RuleTag,
722+
typename RuleLocals,
723+
typename RuleParams,
724+
typename Where>
725+
std::optional<pending_symbol_table_operations_t> parse_context<
726+
DoTrace,
727+
UseCallbacks,
728+
I,
729+
S,
730+
ErrorHandler,
731+
GlobalState,
732+
Callbacks,
733+
Attr,
734+
Val,
735+
RuleTag,
736+
RuleLocals,
737+
RuleParams,
738+
Where>::empty_pending_symbol_table_operations_;
739+
651740
template<
652741
bool DoTrace,
653742
bool UseCallbacks,
@@ -1734,7 +1823,7 @@ namespace boost { namespace parser {
17341823
using trie_t = text::trie_map<std::vector<char32_t>, T>;
17351824
using result_type = std::pair<trie_t &, bool>;
17361825
symbol_table_tries_t & symbol_table_tries =
1737-
*context.symbol_table_tries_;
1826+
context.get_symbol_table_tries();
17381827

17391828
auto & [any, has_case_folded] =
17401829
symbol_table_tries[(void *)&sym_parser.ref()];
@@ -1773,7 +1862,7 @@ namespace boost { namespace parser {
17731862
Context const & context, symbol_parser<T> const & sym_parser)
17741863
{
17751864
void const * ptr = static_cast<void const *>(&sym_parser);
1776-
auto & entry = (*context.pending_symbol_table_operations_)[ptr];
1865+
auto & entry = (context.get_pending_symbol_table_operations())[ptr];
17771866
std::vector<detail::symbol_table_operation<T>> * retval = nullptr;
17781867
if (entry.visit_) {
17791868
retval = std::any_cast<

0 commit comments

Comments
 (0)