0

我正在用 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"

4

1 回答 1

3

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


我的建议是直接使用 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'
于 2014-12-12T13:51:27.783 回答