mirror of
https://github.com/boostorg/parser.git
synced 2026-01-19 04:22:13 +00:00
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
This commit is contained in:
@@ -330,7 +330,7 @@ the input they match unless otherwise stated in the table below.]
|
||||
[[ _symbols_t_ ]
|
||||
[ _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`.]
|
||||
[ `T` ]
|
||||
[ Unlike the other entries in this table, _symbols_ is a type, not an object. ]]
|
||||
[ Unlike the other entries in this table, _symbols_ is a type, not an object. Inside of skippers, all _symbols_ will appear empty. ]]
|
||||
|
||||
[[ _quot_str_ ]
|
||||
[ Matches `'"'`, followed by zero or more characters, followed by `'"'`. ]
|
||||
|
||||
@@ -472,6 +472,37 @@ namespace boost { namespace parser {
|
||||
nope_or_pointer_t<Where, true> where_{};
|
||||
int no_case_depth_ = 0;
|
||||
|
||||
// These exist in order to provide an address, if requested, for
|
||||
// either kind of symbol table struct. The nonstatic member
|
||||
// pointers for these will be null if this context was created
|
||||
// inside of detail::skip(), but nothing prevents the user from
|
||||
// trying to use a symbol_parser anyway. So, we have these.
|
||||
static std::optional<symbol_table_tries_t>
|
||||
empty_symbol_table_tries_;
|
||||
static std::optional<pending_symbol_table_operations_t>
|
||||
empty_pending_symbol_table_operations_;
|
||||
|
||||
symbol_table_tries_t & get_symbol_table_tries() const
|
||||
{
|
||||
if (symbol_table_tries_)
|
||||
return *symbol_table_tries_;
|
||||
if (!empty_symbol_table_tries_)
|
||||
empty_symbol_table_tries_ = symbol_table_tries_t();
|
||||
return *empty_symbol_table_tries_;
|
||||
}
|
||||
|
||||
pending_symbol_table_operations_t &
|
||||
get_pending_symbol_table_operations() const
|
||||
{
|
||||
if (pending_symbol_table_operations_)
|
||||
return *pending_symbol_table_operations_;
|
||||
if (!empty_pending_symbol_table_operations_) {
|
||||
empty_pending_symbol_table_operations_ =
|
||||
pending_symbol_table_operations_t();
|
||||
}
|
||||
return *empty_pending_symbol_table_operations_;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static auto nope_or_address(T & x)
|
||||
{
|
||||
@@ -648,6 +679,64 @@ namespace boost { namespace parser {
|
||||
{}
|
||||
};
|
||||
|
||||
template<
|
||||
bool DoTrace,
|
||||
bool UseCallbacks,
|
||||
typename I,
|
||||
typename S,
|
||||
typename ErrorHandler,
|
||||
typename GlobalState,
|
||||
typename Callbacks,
|
||||
typename Attr,
|
||||
typename Val,
|
||||
typename RuleTag,
|
||||
typename RuleLocals,
|
||||
typename RuleParams,
|
||||
typename Where>
|
||||
std::optional<symbol_table_tries_t> parse_context<
|
||||
DoTrace,
|
||||
UseCallbacks,
|
||||
I,
|
||||
S,
|
||||
ErrorHandler,
|
||||
GlobalState,
|
||||
Callbacks,
|
||||
Attr,
|
||||
Val,
|
||||
RuleTag,
|
||||
RuleLocals,
|
||||
RuleParams,
|
||||
Where>::empty_symbol_table_tries_;
|
||||
|
||||
template<
|
||||
bool DoTrace,
|
||||
bool UseCallbacks,
|
||||
typename I,
|
||||
typename S,
|
||||
typename ErrorHandler,
|
||||
typename GlobalState,
|
||||
typename Callbacks,
|
||||
typename Attr,
|
||||
typename Val,
|
||||
typename RuleTag,
|
||||
typename RuleLocals,
|
||||
typename RuleParams,
|
||||
typename Where>
|
||||
std::optional<pending_symbol_table_operations_t> parse_context<
|
||||
DoTrace,
|
||||
UseCallbacks,
|
||||
I,
|
||||
S,
|
||||
ErrorHandler,
|
||||
GlobalState,
|
||||
Callbacks,
|
||||
Attr,
|
||||
Val,
|
||||
RuleTag,
|
||||
RuleLocals,
|
||||
RuleParams,
|
||||
Where>::empty_pending_symbol_table_operations_;
|
||||
|
||||
template<
|
||||
bool DoTrace,
|
||||
bool UseCallbacks,
|
||||
@@ -1734,7 +1823,7 @@ namespace boost { namespace parser {
|
||||
using trie_t = text::trie_map<std::vector<char32_t>, T>;
|
||||
using result_type = std::pair<trie_t &, bool>;
|
||||
symbol_table_tries_t & symbol_table_tries =
|
||||
*context.symbol_table_tries_;
|
||||
context.get_symbol_table_tries();
|
||||
|
||||
auto & [any, has_case_folded] =
|
||||
symbol_table_tries[(void *)&sym_parser.ref()];
|
||||
@@ -1773,7 +1862,7 @@ namespace boost { namespace parser {
|
||||
Context const & context, symbol_parser<T> const & sym_parser)
|
||||
{
|
||||
void const * ptr = static_cast<void const *>(&sym_parser);
|
||||
auto & entry = (*context.pending_symbol_table_operations_)[ptr];
|
||||
auto & entry = (context.get_pending_symbol_table_operations())[ptr];
|
||||
std::vector<detail::symbol_table_operation<T>> * retval = nullptr;
|
||||
if (entry.visit_) {
|
||||
retval = std::any_cast<
|
||||
|
||||
Reference in New Issue
Block a user