| /*============================================================================= |
| Copyright (c) 2004 Angus Leeming |
| http://spirit.sourceforge.net/ |
| |
| Use, modification and distribution is subject to 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) |
| =============================================================================*/ |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // The switch_p parser was broken sometime during the boost 1.32 development |
| // cycle. This little program tests it, the for_p parser and the limit_d |
| // directive. |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| #include <boost/spirit/include/classic_core.hpp> |
| #include <boost/spirit/include/classic_for.hpp> |
| #include <boost/spirit/include/classic_switch.hpp> |
| #include <boost/spirit/include/classic_position_iterator.hpp> |
| #include <boost/spirit/include/classic_confix.hpp> |
| |
| #include <boost/spirit/include/phoenix1.hpp> |
| |
| #include <iostream> |
| #include <string> |
| |
| namespace spirit = BOOST_SPIRIT_CLASSIC_NS; |
| |
| typedef unsigned int uint; |
| |
| struct switch_grammar : public spirit::grammar<switch_grammar> { |
| template <typename ScannerT> |
| struct definition { |
| definition(switch_grammar const & self); |
| |
| typedef spirit::rule<ScannerT> rule_t; |
| rule_t const & start() const { return expression; } |
| |
| private: |
| rule_t expression; |
| uint index; |
| uint nnodes; |
| }; |
| }; |
| |
| |
| template <typename ScannerT> |
| switch_grammar::definition<ScannerT>::definition(switch_grammar const & self) |
| { |
| using boost::cref; |
| |
| using phoenix::arg1; |
| using phoenix::var; |
| |
| using spirit::case_p; |
| using spirit::for_p; |
| using spirit::limit_d; |
| using spirit::str_p; |
| using spirit::switch_p; |
| using spirit::uint_p; |
| |
| expression = |
| str_p("NNODES") >> |
| uint_p[var(nnodes) = arg1] >> |
| |
| for_p(var(index) = 1, |
| var(index) <= var(nnodes), |
| var(index)++) |
| [ |
| limit_d(cref(index), cref(index))[uint_p] >> |
| |
| switch_p[ |
| case_p<'s'>(uint_p), |
| case_p<'d'>(uint_p), |
| case_p<'n'>(uint_p) |
| ] |
| ]; |
| } |
| |
| |
| int main() |
| { |
| std::string const data("NNODES 3\n" |
| "1 s 1\n" |
| "2 d 2\n" |
| "3 n 3"); // JDG 10-18-2005 removed trailing \n to |
| // avoid post skip problems |
| |
| typedef spirit::position_iterator<std::string::const_iterator> |
| iterator_t; |
| |
| spirit::parse_info<iterator_t> const info = |
| parse(iterator_t(data.begin(), data.end(), "switch test"), |
| iterator_t(), |
| switch_grammar(), |
| spirit::space_p); |
| |
| if (!info.full) { |
| spirit::file_position const fp = info.stop.get_position(); |
| std::cerr << "Parsing failed at line " << fp.line |
| << ", column " << fp.column << ".\n"; |
| } |
| |
| return info.full ? 0 : 1; |
| } |