две вещи:
no_case[]
требует, чтобы содержащиеся парсер выражений быть указаны в нижнем регистре
- это, кажется, не быть задокументированы в любом месте, но
no_case
директива делает не распространяться через Non-Terminal parsers ,
В этом смысле no_case
аналогичен, например, locals<>
или шкипер в том, что они являются частью контекста парсера; Только в этом случае зависящий от регистра регистр событий не контролируется из аргументов шаблона правила.
Я, кажется, помню, что Spirit X3 будет получать более общий объект здесь, который может устранить эти ограничения.
Пример программа, показывающее ограничение в действии:
Live On Coliru
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
template <typename It, typename Skipper>
struct Parser : qi::grammar<It, std::string(), Skipper> {
Parser() : Parser::base_type(start) {
using namespace qi;
a_symbol += "aap", "noot", "mies";
start = raw [ no_case [ a_symbol >> "literal" >> char_("qwerty") >> -subrule_lexeme ] ];
subrule_lexeme = "also works";
BOOST_SPIRIT_DEBUG_NODES((start)(subrule_lexeme))
}
private:
qi::symbols<char, qi::unused_type> a_symbol;
qi::rule<It, std::string(), Skipper> start;
qi::rule<It, std::string()> subrule_lexeme;
};
// test
using It = std::string::const_iterator;
template <typename S = qi::space_type> void test(S const& s = S()) {
Parser<It, S> g;
for (std::string const& input : {
"aap\t literal r",
"aAp\t liTeral R",
// hitting subrule_lexeme:
"aap\t literal r\talso works",
"aAp\t liTeral R\tALSO WoRkS",
})
{
It f = input.begin(), l = input.end();
std::string parsed;
bool ok = qi::phrase_parse(f, l, g, s, parsed);
if (ok)
std::cout << "Parsed successfully: '" << parsed << "'\n";
else
std::cout << "Not matched ('" << input << "')\n";
if (f!=l)
std::cout << " -- remaining unparsed input: '" << std::string(f,l) << "'\n";
}
}
int main()
{
test(qi::space);
}
Печати:
Parsed successfully: 'aap literal r'
Parsed successfully: 'aAp liTeral R'
Parsed successfully: 'aap literal r also works'
Parsed successfully: 'aAp liTeral R '
-- remaining unparsed input: 'ALSO WoRkS'
И с полной трассировкой:
<start>
<try>aap\t literal r</try>
<subrule_lexeme>
<try></try>
<fail/>
</subrule_lexeme>
<success></success>
<attributes>[[a, a, p, , , l, i, t, e, r, a, l, , r]]</attributes>
</start>
Parsed successfully: 'aap literal r'
<start>
<try>aAp\t liTeral R</try>
<subrule_lexeme>
<try></try>
<fail/>
</subrule_lexeme>
<success></success>
<attributes>[[a, A, p, , , l, i, T, e, r, a, l, , R]]</attributes>
</start>
Parsed successfully: 'aAp liTeral R'
<start>
<try>aap\t literal r\talso </try>
<subrule_lexeme>
<try>also works</try>
<success></success>
<attributes>[[a, l, s, o, , w, o, r, k, s]]</attributes>
</subrule_lexeme>
<success></success>
<attributes>[[a, a, p, , , l, i, t, e, r, a, l, , r, , a, l, s, o, , w, o, r, k, s]]</attributes>
</start>
Parsed successfully: 'aap literal r also works'
<start>
<try>aAp\t liTeral R\tALSO </try>
<subrule_lexeme>
<try>ALSO WoRkS</try>
<fail/>
</subrule_lexeme>
<success>ALSO WoRkS</success>
<attributes>[[a, A, p, , , l, i, T, e, r, a, l, , R, ]]</attributes>
</start>
Parsed successfully: 'aAp liTeral R '
-- remaining unparsed input: 'ALSO WoRkS'
Пожалуйста, обновите boost :) – sehe