2016-08-27 2 views
3

부스트 스피리트 qi :: symbols는 키 - 값 쌍의 맵을 구현합니다. 문자열의 키를 지정하면 특정 값을 반환 할 수 있습니다. 내 질문은 다음과 같습니다.Boost Spirit Qi 기호 기본값 및 NULL 값

1) 빈 문자열의 경우 기본값을 반환 할 수 있습니까? (코드의 Q1)

2) 빈 문자열 이외의 문자열 또는 키 - 값 쌍의 맵에 나열된 키의 경우 키가 유효하지 않음을 나타내는 값을 반환 할 수 있습니까? (코드의 Q2)

** 다음 코드는 BOOST SPIRIT 문서를 기반으로합니다. ** 미리 제안 해 주셔서 감사합니다.

#include <boost/spirit/include/support_utree.hpp> 
#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix_core.hpp> 
#include <boost/spirit/include/phoenix_operator.hpp> 
#include <boost/fusion/include/adapt_struct.hpp> 
#include <boost/assert.hpp> 
#include <iostream> 
#include <string> 
#include <cstdlib> 

template <typename P, typename T> 
void test_parser_attr(
    char const* input, P const& p, T& attr, bool full_match = true) 
{ 
    using boost::spirit::qi::parse; 

    char const* f(input); 
    char const* l(f + strlen(f)); 
    if (parse(f, l, p, attr) && (!full_match || (f == l))) 
     std::cout << "ok" << std::endl; 
    else 
     std::cout << "fail" << std::endl; 
} 

int main() 
{ 
    using boost::spirit::qi::symbols; 

    symbols<char, int> sym; 
    sym.add 
     ("Apple", 1) 
     ("Banana", 2) 
     ("Orange", 3) 
    ; 

    int i; 
    test_parser_attr("Banana", sym, i); 
    std::cout << i << std::endl;  // 2 


    test_parser_attr("", sym, i);  // Q1: key is "", 
    std::cout << i << std::endl;  // would like it to be 1 as default 

    test_parser_attr("XXXX", sym, i); // Q2: key is other than "Apple"/"Banana"/"Orange", 
    std::cout << i << std::endl;  // would like it to be 4 

    return 0; 
} 

답변

2

qi::symbols을 사용하여 원하는 것을 달성 할 수 없습니다. 원하는 결과를 얻을 수있는 성령 말단/지시어를 만드는 것이 가능해야하지만 실제로는 복잡하고 qi::symbols의 내부 작동에 대한 지식이 필요하며 관련 수업이 필요하므로 가치있는 방법이라고 생각하지 않습니다. 다행히도 입력을 사용하지 않고 val을 속성으로 사용하고 항상 성공하는 파서 인 qi::attr(val)을 사용하는 정말 간단한 대안이 있습니다. 문자열이 문자열이 비어 반환 1 -> 경우 방금 attr(1)

  • 경우 사용 sym
  • 를 사용하여 관련 값 ->을 반환 심볼 테이블에있는 경우

    • :

      의이 세 가지 경우를 보자 문자열이 기호 테이블에 없습니다. attr(4)을 사용해야하는 여기에 4 ->을 반환하십시오.하지만 문자열을 소비해야하기 때문에 충분하지 않습니다. 문자열이 문자로만 구성된다고 가정하면 omit[+alpha]이 작동합니다 (omit은 텍스트를 삭제하고 +은 적어도 하나의 문자가 있음을 확인합니다).

      sym | omit[+alpha] >> attr(4) | attr(1) 
      

      가능한 문제 :

      는 실제로 각각의 경우에 사용하는 파서 성공하는 최초의 하나가 될 것을 염두에 alternative parser 유지에이 세 가지 파서를 둘 필요가

    • 심볼 테이블이 아닌 문자열이 더 복잡 할 수 있다면 +alpha을 적절하게 변경해야합니다.
    • 당신은 아마도 욕심 +을 중지 omit[lexeme[+alpha]] 사용해야합니다 선장을 사용하는 경우.

    전체 샘플 (Running on WandBox)

    #include <iostream> 
    #include <string> 
    
    #include <boost/spirit/include/qi.hpp> 
    
    
    template <typename P, typename T> 
    void test_parser_attr(
        char const* input, P const& p, T& attr, bool full_match = true) 
    { 
        using boost::spirit::qi::parse; 
    
        char const* f(input); 
        char const* l(f + strlen(f)); 
        if (parse(f, l, p, attr) && (!full_match || (f == l))) 
         std::cout << "ok" << std::endl; 
        else 
         std::cout << "fail" << std::endl; 
    } 
    
    int main() 
    { 
        using boost::spirit::qi::symbols; 
    
        symbols<char, int> sym; 
        sym.add 
         ("Apple", 1) 
         ("Banana", 2) 
         ("Orange", 3) 
        ; 
    
        using boost::spirit::qi::attr; 
        using boost::spirit::qi::alpha; 
        using boost::spirit::qi::omit; 
        using boost::spirit::qi::lexeme; 
    
        //if the text is in the symbol table return the associated value 
        //else if the text is formed by letters (you could change this using for example `alnum`) and contains at least one, discard the text and return 4 
        //else return 1 
        boost::spirit::qi::rule<char const*,int()> symbols_with_defaults = sym | omit[+alpha] >> attr (4) | attr(1); 
    
    
        int i; 
        test_parser_attr("Banana", symbols_with_defaults, i); 
        std::cout << i << std::endl;  // 2 
    
        test_parser_attr("", symbols_with_defaults, i);  // Q1: key is "", 
        std::cout << i << std::endl;  // would like it to be 1 as default 
    
        test_parser_attr("XXXX", symbols_with_defaults, i); // Q2: key is other than "Apple"/"Banana"/"Orange", 
        std::cout << i << std::endl;  // would like it to be 4 
    
        std::vector<int> values; 
        test_parser_attr("<Banana>,<>,<xxxx>", ('<' >> symbols_with_defaults >> '>')%',', values); 
        for(int val : values) 
         std::cout << val << " "; // should be '2 1 4' 
        std::cout << std::endl; 
    
        return 0; 
    } 
    
  • +0

    +1. 나는 정확히 80 %가 글을 쓰고 있었다. – sehe

    +0

    굉장! 완벽한 솔루션, 자세한 설명, 신속한 대응. 고맙습니다. – jianz

    관련 문제