Spirit qi no_case指令应用于语法

spirit qi no_case directive applied to grammar

本文关键字:指令 应用于 语法 case qi no Spirit      更新时间:2023-10-16

我有一个正常工作的语法,现在我想用它来解析一个不区分大小写的字符串。

我在Ubuntu 12.04 Linux上运行Boost 1.46。

我尝试了以下代码:

bool parseSuccess = qi::phrase_parse(begin, end,
                    qi::no_case[grammar], ascii::space, result);

但是no_case指令不起作用。

我做错了什么,或者指令不能与非终结符一起使用?

两件事:

  • no_case[]要求包含以小写
  • 指定的解析器表达式
  • 它似乎没有在任何地方记录,但是no_case指令不在非终端解析器中传播。

在这个意义上,no_case类似于例如locals<>,或Skipper,因为它们是解析器上下文的一部分;只有在这种情况下,大小写敏感才不受规则模板参数的控制。

我似乎记得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 : { 
            "aapt literal r",
            "aApt liTeral R",
            // hitting subrule_lexeme:
            "aapt literal rtalso works",
            "aApt liTeral RtALSO 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>aapt 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>aApt 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>aapt literal rtalso </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>aApt liTeral RtALSO </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'