Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何避免在boost::spirit::lex中定义匹配所有内容的令牌_C++_Boost_Boost Spirit - Fatal编程技术网

C++ 如何避免在boost::spirit::lex中定义匹配所有内容的令牌

C++ 如何避免在boost::spirit::lex中定义匹配所有内容的令牌,c++,boost,boost-spirit,C++,Boost,Boost Spirit,我想创建一个语法和词法分析器来解析以下字符串: 100 reason phrase 正则表达式将为:“\d{3}[^\r\n]*” 令牌定义: template <typename Lexer> struct custom_tokens : lex::lexer<Lexer> { custom_tokens() { this->self.add_pattern ("STATUSCODE", "\\d{3}")

我想创建一个语法和词法分析器来解析以下字符串:

100 reason phrase
正则表达式将为:“\d{3}[^\r\n]*”

令牌定义:

template <typename Lexer>
struct custom_tokens : lex::lexer<Lexer>
{
    custom_tokens()
    {
        this->self.add_pattern
            ("STATUSCODE", "\\d{3}")                
            ("SP", " ")
            ("REASONPHRASE", "[^\r\n]*")
            ;                

        this->self.add                          
            ("{STATUSCODE}", T_STATUSCODE)
            ("{SP}", T_SP)
            ("{REASONPHRASE}", T_REASONPHRASE)
            ;
    }   
};
模板
结构自定义标记:lex::lexer
{
自定义令牌()
{
此->self.add\u模式
(“状态码”、“\\d{3}”)
(“SP”,“SP”)
(“原因短语”,“[^\r\n]*”)
;                
此->self.add
(“{STATUSCODE}”,T_STATUSCODE)
(“{SP}”,T_SP)
(“{REASONPHRASE}”,T_REASONPHRASE)
;
}   
};
语法:

template <typename Iterator>
struct custom_grammar : qi::grammar<Iterator >
{
    template <typename TokenDef>
    custom_grammar(TokenDef const& tok)
        : custom_grammar::base_type(start)            
    {            
        start = (qi::token(T_STATUSCODE) >> qi::token(T_SP) >> qi::token(T_REASONPHRASE));
    }

    qi::rule<Iterator> start;
};
模板
结构自定义语法:qi::grammar
{
模板
自定义语法(TokenDef const&tok)
:自定义语法::基本类型(开始)
{            
开始=(qi::token(T_状态码)>>qi::token(T_SP)>>qi::token(T_状态码));
}
qi::规则开始;
};
然而,我意识到我无法定义令牌“t_REASONPHRASE”,因为它将匹配包括“t_状态码”在内的所有内容。我能做的就是

  • 取消定义T_推理短语并使用qi::lexeme在自定义_语法中编写规则

  • 我可以用lex state来做吗?e、 g.在第二个状态中定义“T_REASONPHRASE”,如果它在第一个状态中看到T_状态码,那么将其余的解析为第二个状态?请举例说明


  • 我不认为这真的有问题,因为令牌是按照它们添加到令牌定义中的顺序“贪婪地”匹配的(对于特定的lexer状态)

    因此,考虑到

        this->self.add                          
            ("{STATUSCODE}", T_STATUSCODE)
            ("{SP}", T_SP)
            ("{REASONPHRASE}", T_REASONPHRASE)
            ;
    
    T_STATUSCODE将始终在T_REASONPHRASE之前匹配(如果存在任何歧义)


    关于使用单独的Lexer状态,这里是我曾经在一个玩具项目中使用过的标记器的摘录:

    this->self = fileheader     [ lex::_state = "GT" ];
    
    this->self("GT") =
        gametype_label |
        gametype_63000 | gametype_63001 | gametype_63002 |
        gametype_63003 | gametype_63004 | gametype_63005 |
        gametype_63006 |
        gametype_eol            [ lex::_state = "ML" ];
    
    this->self("ML") = mvnumber [ lex::_state = "MV" ];
    
    this->self("MV") = piece | field | op | check | CASTLEK | CASTLEQ 
             | promotion
             | Checkmate | Stalemate | EnPassant
             | eol              [ lex::_state = "ML" ]
             | space            [ lex::_pass = lex::pass_flags::pass_ignore ];
    

    (如果您将
    GT
    解读为gametype,
    ML
    :move line和
    MV
    :move;注意这里存在
    eol和
    gametype\u eol
    :Lex不允许将相同的令牌添加到不同的状态)

    添加了一个关于使用单独lexer语句的代码片段。我认为上面的示例不好。如果我想匹配字符串
    BYE REASON PHRASE
    ,正则表达式是
    BYE[^\r\n]*
    t_STATUSCODE=“BYE”
    t_REASONPHRASE=“[^\r\n]*”
    ,那么
    t_REASONPHRASE
    肯定会一直匹配。@sehe,我认为上面的例子不好。如果我想匹配字符串
    BYE REASON PHRASE
    ,正则表达式是
    BYE[^\r\n]*
    ,t_STATUSCODE=“BYE”,t_REASONPHRASE=“[^\r\n]*”,那么t_REASONPHRASE肯定会一直匹配。我不确定,但我认为sehe不会收到该消息的通知。如果你想让他得到通知,你应该在他的回答中作为评论。我对lex没有什么经验,但我认为你的新例子不会改变任何事情。如果你像sehe在回答中所说的那样,在原因短语之前添加状态代码,这应该是可行的。