Bạn đã tạo ra một trạng thái lexer thứ hai, nhưng không bao giờ gọi nó.
Đơn giản hóa và lợi nhuận:
Đối với hầu hết các trường hợp, cách dễ nhất để có hiệu quả mong muốn sẽ được sử dụng đơn nhà nước Lexing với một lá cờ pass_ignore
trên tokens thể bỏ qua:
this->self += identifier
| white_space [ lex::_pass = lex::pass_flags::pass_ignore ];
Lưu ý rằng điều này yêu cầu một số actor_lexer
để cho phép hành động ngữ nghĩa:
typedef lex::lexertl::actor_lexer<token_type> lexer_type;
.210
Full mẫu:
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
namespace lex = boost::spirit::lex;
template <typename Lexer>
struct lexer_identifier : lex::lexer<Lexer>
{
lexer_identifier()
: identifier("[a-zA-Z_][a-zA-Z0-9_]*")
, white_space("[ \\t\\n]+")
{
using boost::spirit::lex::_start;
using boost::spirit::lex::_end;
this->self += identifier
| white_space [ lex::_pass = lex::pass_flags::pass_ignore ];
}
lex::token_def<> identifier;
lex::token_def<> white_space;
std::string identifier_name;
};
int main(int argc, const char *argv[])
{
typedef lex::lexertl::token<char const*,lex::omit, boost::mpl::false_> token_type;
typedef lex::lexertl::actor_lexer<token_type> lexer_type;
typedef lexer_identifier<lexer_type>::iterator_type iterator_type;
lexer_identifier<lexer_type> my_lexer;
std::string test("adedvied das934adf dfklj_03245");
char const* first = test.c_str();
char const* last = &first[test.size()];
lexer_type::iterator_type iter = my_lexer.begin(first, last);
lexer_type::iterator_type end = my_lexer.end();
while (iter != end && token_is_valid(*iter))
{
++iter;
}
bool r = (iter == end);
std::cout << std::boolalpha << r << "\n";
}
Prints
true
"WS" như một trạng thái Skipper
Cũng có thể bạn đã xem qua một mẫu sử dụng trạng thái phân tích cú pháp thứ hai cho người đội trưởng (lex::tokenize_and_phrase_parse
). Hãy để tôi mất một phút hoặc 10 để tạo ra một mẫu làm việc cho điều đó.
Cập nhật Đã cho tôi một chút hơn 10 phút (waaaah) :) Dưới đây là một thử nghiệm so sánh, cho thấy cách các bang lexer tương tác, và làm thế nào để sử dụng Spirit Skipper phân tích cú pháp để gọi trạng thái phân tích cú pháp thứ hai:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
namespace lex = boost::spirit::lex;
namespace qi = boost::spirit::qi;
template <typename Lexer>
struct lexer_identifier : lex::lexer<Lexer>
{
lexer_identifier()
: identifier("[a-zA-Z_][a-zA-Z0-9_]*")
, white_space("[ \\t\\n]+")
{
this->self = identifier;
this->self("WS") = white_space;
}
lex::token_def<> identifier;
lex::token_def<lex::omit> white_space;
};
int main()
{
typedef lex::lexertl::token<char const*, lex::omit, boost::mpl::true_> token_type;
typedef lex::lexertl::lexer<token_type> lexer_type;
typedef lexer_identifier<lexer_type>::iterator_type iterator_type;
lexer_identifier<lexer_type> my_lexer;
std::string test("adedvied das934adf dfklj_03245");
{
char const* first = test.c_str();
char const* last = &first[test.size()];
// cannot lex in just default WS state:
bool ok = lex::tokenize(first, last, my_lexer, "WS");
std::cout << "Starting state WS:\t" << std::boolalpha << ok << "\n";
}
{
char const* first = test.c_str();
char const* last = &first[test.size()];
// cannot lex in just default state either:
bool ok = lex::tokenize(first, last, my_lexer, "INITIAL");
std::cout << "Starting state INITIAL:\t" << std::boolalpha << ok << "\n";
}
{
char const* first = test.c_str();
char const* last = &first[test.size()];
bool ok = lex::tokenize_and_phrase_parse(first, last, my_lexer, *my_lexer.self, qi::in_state("WS")[my_lexer.self]);
ok = ok && (first == last); // verify full input consumed
std::cout << std::boolalpha << ok << "\n";
}
}
Đầu ra là
Starting state WS: false
Starting state INITIAL: false
true
gia tăng các "WS" cách tiếp cận nhà nước với bản demo dưới ** ' "WS" như một state' Skipper **. Chúc mừng – sehe
Rất tiếc. Tôi đã sao chép khai báo token_type sai. Nó cần 'mpl :: true_' cho [' HasState'] (http://www.boost.org/doc/libs/1_49_0/libs/spirit/doc/html/spirit/lex/abstracts/lexer_primitives/lexer_token_values.html # spirit.lex.abstracts.lexer_primitives.lexer_token_values.the_anatomy_of_a_token), khi giao dịch với những người đứng đầu nhà nước - rõ ràng! *** Cố định *** – sehe
trước hết - cảm ơn bạn vì ví dụ mở rộng của bạn. Tôi vẫn có một số câu hỏi mặc dù: những gì hiện lex :: bỏ qua làm gì? Và liên quan đến lời gọi tokenize_and_parse: my_lexer.self & qi :: in_state ("WS") [my_lexer.self] là gì? –