1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- // 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;
- }
|