2014-02-22 6 views
6

유효한 키워드 (기호)로 시작하면 부스트 스피릿 심볼 파서가 키워드 (심볼)를 허용하지 않도록하려면 어떻게해야합니까? 구문을 'ONEMORE'구문 분석에 실패하고 'ONE'구문 분석에 성공하지 못합니다. 올바른 키워드이므로 'MORE'에서 실패합니다.부스트 스피릿 방지 심볼 파서가 너무 일찍 키워드를 수락하지 못하도록

여기에 아래 코드의 실제 출력 :

Keyword as a number: 1 
Keyword as a number: 2 
Keyword as a number: 1 
Invalid keyword: MORETHREE 

그리고 이것은 내가이되고 싶은 것입니다 :

Keyword as a number: 1 
Keyword as a number: 2 
Invalid keyword: ONEMORE 
Keyword as a number: 3 

코드는 단지 지점을 통해 얻을 수있는 샘플입니다.

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

using namespace std; 
namespace qi = boost::spirit::qi; 
namespace ascii = boost::spirit::ascii; 

void printNumber(unsigned u) 
{ 
    cout << "Keyword as a number: " << u << endl; 
} 

void printInvalidKeyword(const string &s) 
{ 
    cout << "Invalid keyword: " << s << endl; 
} 

template <typename Iterator> 
struct keyword_parser : qi::grammar<Iterator, ascii::space_type> 
{ 
    struct mySymbols_ : qi::symbols<char, unsigned> 
    { 
     mySymbols_() 
     { 
      add 
      ("ONE" , 1) 
      ("TWO" , 2) 
      ("THREE" , 2) 
      ; 
     } 

    } mySymbols; 

    keyword_parser() : keyword_parser::base_type(start) 
    { 
     using qi::_1; 
     using qi::raw; 
     using ascii::char_; 

     start %= *(
        mySymbols[&printNumber] 
        | 
        invalid[&printInvalidKeyword] 
        ); 

     invalid = +char_; 

    } 

    qi::rule<Iterator, ascii::space_type> start; 
    qi::rule<Iterator, std::string(), ascii::space_type> invalid; 
}; 

int main() 
{ 
    using boost::spirit::ascii::space; 
    typedef std::string::const_iterator iterator_type; 
    typedef keyword_parser<iterator_type> keyword_parser; 

    std::string s = "ONE TWO ONEMORE THREE"; 
    iterator_type b = s.begin(); 
    iterator_type e = s.end(); 
    phrase_parse(b, e, keyword_parser(), space); 

    return 0; 
} 

답변

6

qi::repository::distinct에서 또는 어떤 조치를 직접 취할 :

qi::rule<Iterator, ascii::space_type> start; 

// lexemes do not ignore embedded skippables 
qi::rule<Iterator, int()> keyword; 
qi::rule<Iterator, std::string()> invalid; 

Live On Coliru

인쇄를 참조로

start %= *(
      keyword [cout << val("Keyword as a number: ") << _1 << endl] 
     | invalid [cout << val("Invalid keyword: ")  << _1 << endl] 
     ); 

keyword = mySymbols >> !(char_("a-zA-Z0-9_")); 

invalid = +ascii::graph; 

규칙이 선언되고 :

,451,515,
Keyword as a number: 1 
Keyword as a number: 2 
Invalid keyword: ONEMORE 
Keyword as a number: 2 

전체 소스 : 당신이 들으 :-) 그것을 볼 수없는 경우가 아니라면

#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix.hpp> 
#include <iostream> 
#include <string> 

using namespace std; 
namespace qi = boost::spirit::qi; 
namespace phx = boost::phoenix; 
namespace ascii = boost::spirit::ascii; 

template <typename Iterator> 
struct keyword_parser : qi::grammar<Iterator, ascii::space_type> 
{ 
    struct mySymbols_ : qi::symbols<char, unsigned> 
    { 
     mySymbols_() 
     { 
      add 
      ("ONE" , 1) 
      ("TWO" , 2) 
      ("THREE" , 2) 
      ; 
     } 

    } mySymbols; 

    keyword_parser() : keyword_parser::base_type(start) 
    { 
     using qi::_1; 
     using ascii::char_; 
     using phx::val; 

     start %= *(
        keyword [cout << val("Keyword as a number: ") << _1 << endl] 
       | invalid [cout << val("Invalid keyword: ")  << _1 << endl] 
       ); 

     keyword = mySymbols >> !(char_("a-zA-Z0-9_")); 

     invalid = +ascii::graph; 

    } 

    qi::rule<Iterator, ascii::space_type> start; 
    // lexemes do not ignore embedded skippables 
    qi::rule<Iterator, int()> keyword; 
    qi::rule<Iterator, std::string()/*IMPLICIT LEXEME:, ascii::space_type*/> invalid; 
}; 

int main() 
{ 
    using boost::spirit::ascii::space; 
    typedef std::string::const_iterator iterator_type; 
    typedef keyword_parser<iterator_type> keyword_parser; 

    std::string s = "ONE TWO ONEMORE THREE"; 
    iterator_type b = s.begin(); 
    iterator_type e = s.end(); 
    phrase_parse(b, e, keyword_parser(), space); 

    return 0; 
} 
+0

어떤 일이 간단합니다. – Halt