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_状态码”在内的所有内容。我能做的就是
我不认为这真的有问题,因为令牌是按照它们添加到令牌定义中的顺序“贪婪地”匹配的(对于特定的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在回答中所说的那样,在原因短语之前添加状态代码,这应该是可行的。