2013-09-05 4 views
1

если в ци :: грамматике Я использую эту базу правилологический оператор не не работает в наддува :: дух :: ци

expression = (boost::spirit::ascii::string("aaa")); 

он будет разбирать «ааа» и ничего

когда Я использую этот (обратите внимание!) не разбирает вообще ничего, пока я ожидаю, что это, чтобы быть успешным на все, кроме «ааа»

expression = !(boost::spirit::ascii::string("aaa")); 

Могу ли я отсутствовать в некоторых из них? Я использую boost 1.54.0.

EDIT:

К сожалению, это немного сквозняке я изменил пример калькулятора для моих первых испытаний ...

#include <boost/config/warning_disable.hpp> 
#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix_operator.hpp> 

#include <iostream> 
#include <string> 
#include <boost/spirit/include/qi_lit.hpp> 
#include <boost/spirit/include/qi_not_predicate.hpp> 
/* 
* \ 
    __grammar_calculator.cpp 

HEADERS += \ 
    __grammar_calculator.h 
*/ 
namespace client 
{ 
    namespace qi = boost::spirit::qi; 
    namespace ascii = boost::spirit::ascii; 

    /////////////////////////////////////////////////////////////////////////// 
    // Our calculator grammar 
    /////////////////////////////////////////////////////////////////////////// 
    template <typename Iterator> 
    struct calculator : qi::grammar<Iterator, int(), ascii::space_type> 
    { 
     calculator() : calculator::base_type(expression) 
     { 
      using qi::_val; 
      using qi::_1; 
      using qi::uint_; 
      using boost::spirit::qi::lit; 
      using boost::spirit::ascii::string; 

      expression = !(boost::spirit::ascii::string("aaa")); 
     } 

     qi::rule<Iterator, int(), ascii::space_type> expression, term, factor; 
    }; 
} 

/////////////////////////////////////////////////////////////////////////////// 
// Main program 
/////////////////////////////////////////////////////////////////////////////// 
int 
main() 
{ 
    std::cout << "/////////////////////////////////////////////////////////\n\n"; 
    std::cout << "Expression parser...\n\n"; 
    std::cout << "/////////////////////////////////////////////////////////\n\n"; 
    std::cout << "Type an expression...or [q or Q] to quit\n\n"; 

    using boost::spirit::ascii::space; 
    typedef std::string::const_iterator iterator_type; 
    typedef client::calculator<iterator_type> calculator; 

    calculator calc; // Our grammar 

    std::string str; 
    int result; 
    while (std::getline(std::cin, str)) 
    { 
     if (str.empty() || str[0] == 'q' || str[0] == 'Q') 
      break; 

     std::string::const_iterator iter = str.begin(); 
     std::string::const_iterator end = str.end(); 
     bool r = phrase_parse(iter, end, calc, space, result); 

     if (r && iter == end) 
     { 
      std::cout << "-------------------------\n"; 
      std::cout << "Parsing succeeded\n"; 
      //std::cout << "result = " << result << std::endl; 
      std::cout << "-------------------------\n"; 
     } 
     else 
     { 
      std::string rest(iter, end); 
      std::cout << "-------------------------\n"; 
      std::cout << "Parsing failed\n"; 
      //std::cout << "stopped at: \": " << rest << "\"\n"; 
      std::cout << "-------------------------\n"; 
     } 
    } 

    std::cout << "Bye... :-) \n\n"; 
    return 0; 
} 

EDIT 2:

же один немного чище:

#include <boost/config/warning_disable.hpp> 
#include <boost/spirit/include/qi.hpp> 

#include <iostream> 
#include <string> 
#include <boost/spirit/include/qi_not_predicate.hpp> 

namespace client 
{ 
    namespace qi = boost::spirit::qi; 
    namespace ascii = boost::spirit::ascii; 

    template <typename Iterator> 
    struct test : qi::grammar<Iterator> 
    { 
     test() : test::base_type(expression) 
     { 
      using boost::spirit::ascii::string; 

      expression = (boost::spirit::ascii::string("aaa")); 
     } 

     qi::rule<Iterator> expression; 
    }; 
} 

int main() 
{ 
    std::cout << "/////////////////////////////////////////////////////////\n\n"; 
    std::cout << "Expression parser...\n\n"; 
    std::cout << "/////////////////////////////////////////////////////////\n\n"; 
    std::cout << "Type an expression...or [q or Q] to quit\n\n"; 

    using boost::spirit::ascii::space; 
    typedef std::string::const_iterator iterator_type; 
    typedef client::test<iterator_type> test; 

    test tester; // Our grammar 

    std::string str; 
    while (std::getline(std::cin, str)) 
    { 
     if (str.empty() || str[0] == 'q' || str[0] == 'Q') 
      break; 

     std::string::const_iterator iter = str.begin(); 
     std::string::const_iterator end = str.end(); 
     bool r = phrase_parse(iter, end, tester, space); 

     if (r && iter == end) 
     { 
      std::cout << "-------------------------\n"; 
      std::cout << "Parsing succeeded\n"; 
      std::cout << "-------------------------\n"; 
     } 
     else 
     { 
      std::string rest(iter, end); 
      std::cout << "-------------------------\n"; 
      std::cout << "Parsing failed\n"; 
      std::cout << "-------------------------\n"; 
     } 
    } 

    std::cout << "Bye... :-) \n\n"; 
    return 0; 
} 

ОТВЕТ:

проблема возникла из теста:

if (r && iter == end) 

как указывает оператор не потребляли ничего так ИТЭР = конец

в ниже, sehe при условии, некоторые альтернативы!.

+1

'' оператор будет [* должен *] (HTTP: // www.boost.org/doc/libs/1_54_0/libs/spirit/doc/html/spirit/qi/reference/operator/not_predicate.html), чтобы ничего не потреблять и действительно быть успешным во всем, кроме 'aaa'. Как вы определились иначе? Прошу показать [SSCCE] (http://sscce.org/). – GManNickG

+0

хорошо я использовал функцию синтаксического анализа. Он вернул true или false. Я тестировал оба выражения. Второй всегда возвращает false. –

+0

Покажите этот код в своем вопросе. – GManNickG

ответ

1

Для чего это стоит:

  • Как уже отмечалось operator& и operator! являются нулевой ширины LOOKAHEAD утверждения (они не совпадают, а «заглядывать» и либо успех или неудачу в матче).

Вы хотите знать о

  • отрицающие символьные наборы:

    qi::char_("a-z") // matches lowercase letters 
    

    ~ ци :: символ _ ("аз") // соответствует ничего но в нижнем регистре письма

  • «вычитание парсера» - подумайте об исключениях:

    qi::char_ - qi::char_("a-z") // equivalent to ~qi::char_("a-z") 
    qi::char_("a-z") - "keyword" // any lowercase letters, but not if it spells "keyword" 
    

Edit так, чтобы отсканировать вперед к следующему "% {" вы могли бы сделать что-то вроде

qi::omit [ qi::char_ - "{%" ] >> "{%" 

Обратите внимание, что вы не всегда нужно «обертка 'литералов в qi::lit, если выражение не включает в себя уже прото-выражения в Qi-домене.


Edit 2 Пример того, как использовать ! и &:

&qi::int_ >> +qi::char_ // parse a string, **iff** it starts with an integer 

или

!keyword_list >> identifier // parse any identifier that's not a known keyword 
+0

thanks: expression = * (qi: : char_ - "{%"); был тем, что я искал. даже если я все еще не уверен, что! предполагается делать! –

+0

@ user2346536 См. Мой «** Редактировать 2 **» (и всегда есть [документация] (http://www.boost.org/doc/libs/1_54_0/libs/spirit/doc/html/spirit/qi/ reference/operator/not_predicate.html), который содержит [примеры] (http://www.boost.org/doc/libs/1_54_0/libs/spirit/doc/html/spirit/qi/reference/operator/not_predicate.html# spirit.qi.reference.operator.not_predicate.example)) – sehe

+1

Я понял !!!!!! if (r && iter == end) терпит неудачу, но если (r) преуспевает , то оператор! выполняет свою работу, но нулевая длина совпадения ==> iter! = end, поскольку ничто не потреблялось «!» –