| // Copyright (c) 2001-2010 Hartmut Kaiser |
| // Copyright (c) 2010 Sergey "GooRoo" Olendarenko |
| // |
| // Distributed under the Boost Software License, Version 1.0. (See accompanying |
| // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| |
| #include <boost/detail/lightweight_test.hpp> |
| #include <boost/config/warning_disable.hpp> |
| |
| #include <cstdlib> |
| #include <iostream> |
| #include <locale> |
| #include <string> |
| |
| #include <boost/spirit/include/lex_lexertl.hpp> |
| #include <boost/spirit/include/phoenix_object.hpp> |
| #include <boost/spirit/include/phoenix_operator.hpp> |
| #include <boost/spirit/include/phoenix_statement.hpp> |
| #include <boost/spirit/include/phoenix_container.hpp> |
| |
| namespace lex = boost::spirit::lex; |
| namespace phoenix = boost::phoenix; |
| |
| typedef std::basic_string<wchar_t> wstring_type; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| enum tokenids |
| { |
| ID_IDENT = 1, |
| ID_CONSTANT, |
| ID_OPERATION, |
| ID_BRACKET |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| struct test_data |
| { |
| int tokenid; |
| wstring_type value; |
| }; |
| |
| // alpha+x1*(2.836-x2[i]) |
| test_data data[] = |
| { |
| { ID_IDENT, L"alpha" }, |
| { ID_OPERATION, L"+" }, |
| { ID_IDENT, L"x1" }, |
| { ID_OPERATION, L"*" }, |
| { ID_BRACKET, L"(" }, |
| { ID_CONSTANT, L"2.836" }, |
| { ID_OPERATION, L"-" }, |
| { ID_IDENT, L"x2" }, |
| { ID_BRACKET, L"[" }, |
| { ID_IDENT, L"i" }, |
| { ID_BRACKET, L"]" }, |
| { ID_BRACKET, L")" } |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| struct test_impl |
| { |
| typedef void result_type; |
| template <typename TokenId, typename Value> |
| struct result { typedef void type; }; |
| |
| template <typename TokenId, typename Value> |
| void operator()(TokenId const& tokenid, Value const& val) const |
| { |
| BOOST_TEST(sequence_counter < sizeof(data)/sizeof(data[0])); |
| BOOST_TEST(data[sequence_counter].tokenid == tokenid); |
| BOOST_TEST(0 == val.which()); |
| |
| typedef boost::iterator_range<wstring_type::iterator> iterator_range; |
| iterator_range r = boost::get<iterator_range>(val); |
| BOOST_TEST(data[sequence_counter].value == |
| wstring_type(r.begin(), r.end())); |
| |
| ++sequence_counter; |
| } |
| |
| static int sequence_counter; |
| }; |
| int test_impl::sequence_counter = 0; |
| |
| phoenix::function<test_impl> const test = test_impl(); |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| template <typename Lexer> |
| struct mega_tokens : lex::lexer<Lexer> |
| { |
| mega_tokens() |
| : identifier(L"[a-zA-Z_][a-zA-Z0-9_]*", ID_IDENT) |
| , constant (L"[0-9]+(\\.[0-9]+)?", ID_CONSTANT) |
| , operation (L"[\\+\\-\\*/]", ID_OPERATION) |
| , bracket (L"[\\(\\)\\[\\]]", ID_BRACKET) |
| { |
| using lex::_tokenid; |
| using lex::_val; |
| |
| this->self |
| = operation [ test(_tokenid, _val) ] |
| | identifier [ test(_tokenid, _val) ] |
| | constant [ test(_tokenid, _val) ] |
| | bracket [ test(_tokenid, _val) ] |
| ; |
| } |
| |
| lex::token_def<wchar_t, wchar_t> operation; |
| lex::token_def<wstring_type, wchar_t> identifier; |
| lex::token_def<double, wchar_t> constant; |
| lex::token_def<wchar_t, wchar_t> bracket; |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| int main() |
| { |
| typedef wstring_type::iterator base_iterator; |
| typedef lex::lexertl::token< |
| base_iterator, boost::mpl::vector<wchar_t, wstring_type, double> |
| > token_type; |
| typedef lex::lexertl::actor_lexer<token_type> lexer_type; |
| typedef mega_tokens<lexer_type>::iterator_type iterator_type; |
| |
| mega_tokens<lexer_type> mega_lexer; |
| |
| wstring_type exampleStr = L"alpha+x1*(2.836-x2[i])"; |
| base_iterator first = exampleStr.begin(); |
| |
| BOOST_TEST(lex::tokenize(first, exampleStr.end(), mega_lexer)); |
| BOOST_TEST(test_impl::sequence_counter == sizeof(data)/sizeof(data[0])); |
| |
| return boost::report_errors(); |
| } |