108 lines
3.0 KiB
C++
108 lines
3.0 KiB
C++
/*=============================================================================
|
|
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;
|
|
}
|