C++ 提升::精神词法器正则表达式

C++ boost::spirit lexer regex

本文关键字:正则表达式 词法 提升 C++      更新时间:2023-10-16

我正在使用boost::spirit做一个简单的词法分析器/解析器。

这是词法分析器:

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"

更新哦,顺便说一下,问题是你只能有一个令牌匹配 - 它们按顺序匹配。您/可以/通过使用词法分析器状态来解决此问题。但我不建议这样做,而不是首先在这里使用词法分析器


我的建议是直接使用 Qi:

    qi::lexeme[".name"] >> qi::lexeme['"' >> *~qi::char_('"') >> '"']

我对 Lexer 代币模式的回忆是极其混乱的转义要求之一。

我可能会稍后尝试弄清楚 - 只是出于好奇

住在科里鲁

#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 failedn";
    }
    if (f!=l)
        std::cout << "Remaining unparsed input: '" << std::string(f,l) << "'n";
}

指纹

Parsed: 'this is my name'