2015-07-09 7 views
1

У меня есть грамматика, которая работает правильно, теперь я хочу использовать ее для синтаксического анализа строки без чувствительности к регистру.spirit qi no_case директива применяется к грамматике

Я запускаю Boost 1.46 на Ubuntu 12.04 Linux.

Я попытался следующий код:

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

Однако директива no_case не имеет никакого эффекта.

Я делаю что-то неправильно или директива не может использоваться с не-терминалами?

+0

Пожалуйста, обновите boost :) – sehe

ответ

1

две вещи:

  • 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' 
+0

Спасибо. К сожалению, сейчас я не могу обновиться. Есть ли способ, которым я могу обойти эту проблему? – giulatona

+0

Это не проблема, за исключением, может быть, отсутствия документации. Модернизация не изменит его. Это предложение не было частью моего ответа по этой причине. – sehe

+0

это ограничение, как вы сказали, и я хотел бы разобрать строку, не беспокоясь о случае. Является ли добавление no_case для определения всех моих правил единственным решением? – giulatona