2017-11-08 2 views
1

포스트 스키핑을하는 가장 관용적 인 방법은 무엇입니까? 더 구체적으로 내 상위 규칙과 일치 한 후 입력에 "건너 뛸 수없는"(쓰레기) 문자가 없는지 확인하고자합니다.포스트 스키핑과 관용적 인 완전 매칭

auto const blankOrComment 
    = ascii::space 
    | x3::lexeme ['#' >> *(x3::char_ - x3::eol) >> -x3::eol ] 
    ; 

auto const program = rule<AstProgram>("program") 
    = *(as<AstDefinition> (definition > ";")) 
    ; 

auto const programEntry = x3::skip(blankOrComment) [program]; 

하나 개의 아이디어, 나는 아주 못생긴 고려하면 주요 반복자 위치가 끝 반복자가 아닌 경우, 나중에 blankOrComment에 대한 별도의 구문 분석 호출을 할 수 있었다. 내가 가진 현재의 더 좋은 아이디어는 루트 규칙을 변경하는 것입니다.

auto const programEntry = x3::skip(blankOrComment) [program >> x3::omit[*blankOrComment]]; 

더 관용적 인 방법이 있습니까?

답변

1

간단한 해킹 >> eps에 압정하는 것입니다

auto const skipper 
    = space 
    | '#' >> *(char_ - eol) >> (eol|eoi) 
    ; 

는 마찬가지로 당신이 postskip 해킹을 할 수 있습니다 : Live On Coliru

주 내가 선장보다 자기 설명하기 위해 노력 것 더 자기 설명 적 :

auto const post_skip = eps; 
    auto const program = "program" >> post_skip; 

Live On Coliru

#include <iostream> 
#define BOOST_SPIRIT_X3_DEBUG 
#include <boost/spirit/home/x3.hpp> 

namespace Parser { 
    namespace x3 = boost::spirit::x3; 

    namespace rules { 
     using namespace x3; 

     auto const skipper 
      = space 
      | '#' >> *(char_ - eol) >> (eol|eoi) 
      ; 

     auto const post_skip = eps; 
     auto const program = "program" >> post_skip; 

    } 

    auto const programEntry = x3::skip(rules::skipper) [rules::program]; 
} 

int main() { 
    using It = std::string::const_iterator; 
    for (std::string const input : { 
      "", 
      " program ", 
      "#hello\n program # comment\n", 
    }) { 
     It f = input.begin(), l = input.end(); 

     if(parse(f, l, Parser::programEntry)) { 
      std::cout << "Parse success\n"; 
     } else { 
      std::cout << "Parse failed\n"; 
     } 

     std::cout << "Remaining: '" << std::string(f,l) << "'\n"; 
    } 
} 

인쇄

Parse failed 
Remaining: '' 
Parse success 
Remaining: '' 
Parse success 
Remaining: '' 
관련 문제