6bea365c51
[SVN r58589]
99 lines
2.9 KiB
C++
99 lines
2.9 KiB
C++
// Copyright (c) 2001-2010 Hartmut Kaiser
|
|
//
|
|
// 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)
|
|
|
|
// The purpose of this example is to demonstrate a simple use case for the
|
|
// flush_multi_pass parser.
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <string>
|
|
|
|
//[qi_flush_multi_pass_includes
|
|
#include <boost/spirit/include/qi.hpp>
|
|
#include <boost/spirit/repository/include/qi_flush_multi_pass.hpp>
|
|
//]
|
|
|
|
//[qi_flush_multi_pass_namespace
|
|
namespace spirit = boost::spirit;
|
|
using boost::spirit::repository::flush_multi_pass;
|
|
//]
|
|
|
|
namespace client
|
|
{
|
|
//[qi_flush_multi_pass_clear_buffer
|
|
template <typename Iterator, typename Skipper>
|
|
struct preprocessor : spirit::qi::grammar<Iterator, Skipper>
|
|
{
|
|
// This is a simplified preprocessor grammar recognizing
|
|
//
|
|
// #define MACRONAME something
|
|
// #undef MACRONAME
|
|
//
|
|
// Its sole purpose is to show an example how to use the
|
|
// flush_multi_pass parser. At the end of each line no backtracking can
|
|
// occur anymore so that it's safe to clear all internal buffers in the
|
|
// multi_pass.
|
|
preprocessor() : preprocessor::base_type(file)
|
|
{
|
|
using spirit::ascii::char_;
|
|
using spirit::qi::eol;
|
|
using spirit::qi::lit;
|
|
|
|
file =
|
|
*line
|
|
;
|
|
|
|
line = ( command | *(char_ - eol) )
|
|
>> eol
|
|
>> flush_multi_pass
|
|
;
|
|
|
|
command =
|
|
"#define" >> *lit(' ') >> *(char_ - ' ') >> *lit(' ') >> *(char_ - eol)
|
|
| "#undef" >> *lit(' ') >> *(char_ - eol)
|
|
;
|
|
}
|
|
|
|
spirit::qi::rule<Iterator, Skipper> file, line, command;
|
|
};
|
|
//]
|
|
}
|
|
|
|
template <typename Iterator, typename Skipper>
|
|
bool parse(Iterator& first, Iterator end, Skipper const& skipper)
|
|
{
|
|
client::preprocessor<Iterator, Skipper> g;
|
|
return boost::spirit::qi::phrase_parse(first, end, g, skipper);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
namespace spirit = boost::spirit;
|
|
using spirit::ascii::char_;
|
|
using spirit::qi::eol;
|
|
|
|
std::ifstream in("flush_multi_pass.txt"); // we get our input from this file
|
|
if (!in.is_open()) {
|
|
std::cout << "Could not open input file: 'flush_multi_pass.txt'" << std::endl;
|
|
return -1;
|
|
}
|
|
|
|
typedef std::istreambuf_iterator<char> base_iterator_type;
|
|
spirit::multi_pass<base_iterator_type> first =
|
|
spirit::make_default_multi_pass(base_iterator_type(in));
|
|
spirit::multi_pass<base_iterator_type> end =
|
|
spirit::make_default_multi_pass(base_iterator_type());
|
|
|
|
bool result = parse(first, end, '#' >> *(char_ - eol) >> eol);
|
|
if (!result) {
|
|
std::cout << "Failed parsing input file!" << std::endl;
|
|
return -2;
|
|
}
|
|
|
|
std::cout << "Successfully parsed input file!" << std::endl;
|
|
return 0;
|
|
}
|
|
|