2013-01-24 2 views
2

일부 입력에 일치 시켜서 복잡한 객체를 구성한 다음 일부 소품에 따라 나머지 입력을 두 가지 방법으로 일치시켜야합니다. 생성 된 객체의 나는 qi를 시도했다 :/eps (/ 조건 /) >> p1 | p2하지만 결과는 분명합니다. 단순화 된 코드 내가 입력에서 int_과 일치하는 코드에서 $ (6)boost spirit qi - 조건부 파싱

http://liveworkspace.org/code/1NzThA 값 == 0 시도 '는'중 하나와 일치하는 경우 - 'B' 을하지만 '0B'입력 OK있어! 나는 중괄호를 가지고 놀려고했지만 운이 없다. 나에게 말한다에

qi::rule<char const*> r = 
    qi::int_ [phoenix::ref(p) = qi::_1] 
    >> (qi::eps(phoenix::ref(p) == 0) 
     >> qi::char_('a') | qi::char_('b')) 

그건 : 'B'로 끝나는 '0A'또는 아무것도를 허용

+0

가능한 해결 방법 : 게으른 http://liveworkspace.org/code/2B4VCK$8 – user2008982

+0

나 '는

가 출력 http://liveworkspace.org/code/1T9h5에 살고 참조 시맨틱 액션없이 답변을 추가했습니다. ([부스트 스피릿 : "시맨틱 액션은 악"입니까?] (http://stackoverflow.com/questions/8259440/boost-spirit-semantic-actions-are-evil/8259585#8259585)) – sehe

+0

@sehe : 의미 론적 행동은 악합니다. 게시물의 좋은 부분은 실제 상황 일뿐입니다. 필수 :)하지만, IMHO는 파서의 컨텍스트 감도와 관련된 질문을 실제 구문 분석 문제로 만들기보다는 취해 보았습니다. 예제는 그 간단한 표현이었습니다. 내 2c. 그래도 우리 중 한 명이 받아 들여지면 좋을 것입니다 ... – FatalFlaw

답변

1

여기 규칙입니다. 이는 코드 스 니펫에서 얻은 결과와 일치합니다.

나는 완전히 당신의 질문을 이해하지 못한다. 그러나 당신이 일종의 '독점적 인'일을하려고한다면 (코드 스 니펫의 주석에 의해 표시됨),이 규칙은 불완전하다. 피닉스 기반의 Qi 지역 주민들이 이미 게으르다는 이유로 qi::lazy을 필요로하지는 않지만 해결 방법 (실제로는 '해결 방법'보다 '해결 방법'이 더 많습니다)은 귀하의 의견에 제시된 하나의 해결책입니다. 그러나 당신은 오른쪽에 있습니다. 선로. 여기에 또 다른 (더 읽기 쉬운?) 해결책이 있습니다. 당신은 지역 주민 <를 사용하려는 경우

qi::rule<char const*> r = 
    qi::int_ [phoenix::ref(p) = qi::_1] 
    >> ((qi::eps(phoenix::ref(p) == 0) >> qi::char_('a')) | 
     (qi::eps(phoenix::ref(p) == 1) >> qi::char_('b'))) 
; 

> 당신의 코멘트를 추가, 그것도 괜찮지 만 p에 대한 참조를 사용하는만큼 당신이 p 다른 곳에서는 설정하지 기억하는 코드에 적은 오버 헤드를 추가 귀하의 문법에, 그리고 당신은 그 규칙을 되풀이하는 문법을 구축 결국 안 : :)

3

나는 개인적으로 의미 론적 행동 (또는 피닉스) 이것을 가볍게 사용하지 않을 것이다. 이것은 제나라의 "성령"이 아닙니다.

이 내 걸릴 수 있습니다 :

rule<char const*, char()> r = 
    (omit [ int_(0) ] >> char_('a')) | 
    (omit [ int_(1) ] >> char_('b')) 
    ; 

보기? 훨씬 더 청결한. 또한 : 자동 속성 전파.

ok: a 
fail 
fail 
ok: b 

전체 샘플 코드 : 제나라를 통해

//#define BOOST_SPIRIT_DEBUG 
#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix.hpp> 

namespace qi = boost::spirit::qi; 
namespace phoenix = boost::phoenix; 

template <typename P> 
inline 
void test_parser(char const* input, P const& p, bool full_match = true) 
{ 
    char const* f(input); 
    char const* l(f + strlen(f)); 
    char result; 
    if (qi::parse(f, l, p, result) && (!full_match || (f == l))) 
     std::cout << "ok: " << result << std::endl; 
    else 
     std::cout << "fail" << std::endl; 
} 

int main() 
{ 
    int p; 
    using namespace qi; 
    rule<char const*, char()> r = 
     (omit [ int_(0) ] >> char_('a')) | 
     (omit [ int_(1) ] >> char_('b')) 
     ; 

    BOOST_SPIRIT_DEBUG_NODE(r); 

    test_parser("0a", r); //should match 
    test_parser("0b", r); //should not match 
    test_parser("1a", r); //should not match 
    test_parser("1b", r); //should match 
} 
관련 문제