2014-12-12 1 views
0

나는 간단한 lexer/parser와 boost :: spirit을하고있다. C++ boost :: spirit lexer regex

template <typename Lexer> 
struct word_count_tokens : lex::lexer<Lexer> 
{ 
    word_count_tokens() 
    {                                                  
     this->self.add_pattern 
      ("WORD", "[a-z]+") 
      ("NAME_CONTENT", "[a-z]+") 
      ; 

     word = "{WORD}"; 
     name = ".name"; 
     name_content = "{NAME_CONTENT}"; 

     this->self.add 
      (word)                                       
      (name)                                        
      (name_content)                                      
      ('\n')                                      
      (' ') 
      ('"') 
      (".", IDANY)                                 
      ; 
    }                                  
    lex::token_def<std::string> word; 
    lex::token_def<std::string> name; 
    lex::token_def<std::string> name_content; 
}; 

제가

개의 동일한 패턴을 정의 : WORD와 NAME_CONTENT

는 렉서이다.

은 문법이다 :

template <typename Iterator> 
struct word_count_grammar : qi::grammar<Iterator> 
{ 
    template <typename TokenDef> 
    word_count_grammar(TokenDef const& tok) 
    : word_count_grammar::base_type(start) 
{ 
using boost::phoenix::ref; 
using boost::phoenix::size; 

start = tok.name >> lit(' ') >> lit('"') >> tok.word >> lit('"'); 
} 

qi::rule<Iterator> start; 
}; 

이 코드는 문법 tok.word 작동하지만 내가 tok.name_content에 의해 tok.word 교체 할 경우는 일을하지 않습니다. 그러나 tok.word == tok.name_content.

이 코드의 문제점은 무엇입니까?

PS : 문제가 당신은 하나의 토큰 경기를 가질 수있는 방법으로 .name "this is my name"

답변

3

업데이트 오 - 그들은 순서로 일치하고 있습니다 : 제가 분석 할 것은 같은입니다./lexer 상태를 사용하여이 문제를 해결할 수 있습니다. 하지만 더 이상 처음에 여기 렉서를 사용하는 것보다이 사용하지 않는 것이 좋습니다


나의 제안은 직접 제나라를 사용하는 것입니다 :

렉서 토큰 패턴의 내 기억이 대단히 중 하나
qi::lexeme[".name"] >> qi::lexeme['"' >> *~qi::char_('"') >> '"'] 

입니다 혼란스러운 탈출 요구 사항.

나중에 그것을 알아 내려고 시도 할 수 있습니다 - 호기심 만

Live On Coliru

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

namespace qi = boost::spirit::qi; 

int main() { 
    std::string const input(".name \"this is my name\""); 

    auto f(input.begin()), l(input.end()); 


    std::string parsed_name; 
    if (qi::phrase_parse(f,l, 
       qi::lexeme[".name"] >> qi::lexeme['"' >> *~qi::char_('"') >> '"'], 
       qi::space, 
       parsed_name)) 
    { 
     std::cout << "Parsed: '" << parsed_name << "'\n"; 
    } 
    else 
    { 
     std::cout << "Parsed failed\n"; 
    } 

    if (f!=l) 
     std::cout << "Remaining unparsed input: '" << std::string(f,l) << "'\n"; 
} 

인쇄

Parsed: 'this is my name' 
+0

당신이 "하나의 토큰이 일치 무엇을 의미합니까 "? 정규식을 제나라와 직접 연결하려면 어떻게해야할까요? 내 정규식은 "[a-z] +"입니다. –

+0

@ThibaultMartinez 두 패턴이 일치하지 않으므로 (유용하게) 두 패턴을 가질 수 없습니다. 반대로 합법적으로 여러 토큰에 동일한 토큰을 추가 할 수 없으므로 여러 상태를 사용할 때 이것이 사실이 아닙니다. 이 작업을 수행하는 방법에 대한 답변은 [tag : boost-spirit-lex]에서 자유롭게 찾아 볼 수 있습니다. 그러나 그것은 예쁘지 않을 것입니다, 그것은 빠르지 않을 것입니다, 그리고 행운을 빌어 요 당신이 오류보고 등 소스 위치 정보가 필요하면 – sehe

+0

내가 그것을 사용하지 않더라도? 왜냐하면 나는이 중 하나만 사용하기 때문에 ... –