【问题标题】:C++ boost::spirit lexer regexC++ boost::spirit 词法分析器正则表达式
【发布时间】:2014-12-12 13:42:36
【问题描述】:

我正在使用 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.word 替换为 tok.name_content 则不起作用。但是 tok.word == tok.name_content.

这段代码有什么问题?

PS:我想解析的是:.name "this is my name"

【问题讨论】:

    标签: c++ regex boost boost-spirit-qi boost-spirit-lex


    【解决方案1】:

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


    我的建议是直接使用 Qi:

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

    我对 Lexer 令牌模式的回忆是非常令人困惑的转义要求之一。

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

    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'
    

    【讨论】:

    • “只有一个令牌匹配”是什么意思?如果我希望我的正则表达式直接带有 qi 怎么办?我的正则表达式是“[a-z]+”,可以吗?
    • @ThibaultMartinez 你不能(有用地)有两个相同的模式,因为一个永远不会匹配。相反,您不能合法地将相同的标记添加到多个状态,因此当使用多个状态时,这将不再正确。随意浏览boost-spirit-lex 答案以了解如何执行此操作。但它不会很漂亮,它不会很快,如果你需要源位置信息来报告错误等,祝你好运。
    • 我不知道,Thibault。那你为什么会有这些图案……?也许这个示意图可以帮助i.imgur.com/cA8BaR5.png
    • 感谢您的图片。确实这只是一个实验,但我很想知道这个问题,现在很清楚了。
    • 好的,我不能定义两个相同的模式。但是现在,我对两种不同的模式有同样的问题。 “[a-zA-Z0-9_,.!?@#]+”和“[a-z0-9_]+”
    猜你喜欢
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-20
    • 1970-01-01
    相关资源
    最近更新 更多