我正在尝试使用词法分析器状态来进行特定于上下文的解析,但似乎不同的词法分析器状态会交叉授粉。这是一个非常基本的例子
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_container.hpp>
#include <iostream>
#include <string>
using namespace boost::spirit;
template <typename Lexer>
struct strip_comments_tokens : lex::lexer<Lexer>
{
strip_comments_tokens()
: strip_comments_tokens::base_type(lex::match_flags::match_default)
{
ccomment = "\\/\\*";
endcomment = ".*\\*\\/";
hello = "hello";
this->self.add
(ccomment)
(hello);
this->self("COMMENT").add
(endcomment);
}
lex::token_def<> ccomment, endcomment;
lex::token_def<std::string> hello;
};
template <typename Iterator>
struct strip_comments_grammar : qi::grammar<Iterator>
{
template <typename TokenDef>
strip_comments_grammar(TokenDef const& tok)
: strip_comments_grammar::base_type(start)
{
start = *( tok.ccomment
>> qi::in_state("COMMENT")
[
tok.endcomment
]
| tok.hello [ std::cout << _1 ]
);
}
qi::rule<Iterator> start;
};
int main(int argc, char* argv[])
{
typedef std::string::iterator base_iterator_type;
typedef
lex::lexertl::lexer<lex::lexertl::token<base_iterator_type> >
lexer_type;
typedef strip_comments_tokens<lexer_type>::iterator_type iterator_type;
strip_comments_tokens<lexer_type> strip_comments; // Our lexer
strip_comments_grammar<iterator_type> g (strip_comments); // Our parser
std::string str("hello/*hello*/hello");
base_iterator_type first = str.begin();
bool r = lex::tokenize_and_parse(first, str.end(), strip_comments, g);
return 0;
}
我希望输入
"hello/*hello*/hello"
被标记为hello ccomment endcomment hello。但是发生的情况是输入被标记为hello ccomment hello,因此语法停止工作。如果您将输入更改为
"hello/*anything else*/hello"
一切都按预期工作。
有任何想法吗?