123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- /*=============================================================================
- 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;
- }
|