123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- /*=============================================================================
- Copyright (c) 2016 Frank Hein, maxence business consulting gmbh
- 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)
- ==============================================================================*/
- #include <iostream>
- #include <map>
- #include <boost/spirit/home/qi.hpp>
- #include <boost/spirit/home/qi/nonterminal/grammar.hpp>
- #include <boost/spirit/include/phoenix.hpp>
- #include <boost/foreach.hpp>
- namespace qi = boost::spirit::qi;
- typedef std::string::const_iterator iterator_type;
- typedef std::string result_type;
- template<typename Parser>
- void parse(const std::string message, const std::string& input, const std::string& rule, const Parser& parser) {
- iterator_type iter = input.begin(), end = input.end();
- std::vector<result_type> parsed_result;
- std::cout << "-------------------------\n";
- std::cout << message << "\n";
- std::cout << "Rule: " << rule << std::endl;
- std::cout << "Parsing: \"" << input << "\"\n";
- bool result = qi::phrase_parse(iter, end, parser, qi::space, parsed_result);
- if (result)
- {
- std::cout << "Parser succeeded.\n";
- std::cout << "Parsed " << parsed_result.size() << " elements:";
- BOOST_FOREACH(result_type const& str, parsed_result)
- {
- std::cout << "[" << str << "]";
- }
- std::cout << std::endl;
- }
- else
- {
- std::cout << "Parser failed" << std::endl;
- }
- if (iter == end) {
- std::cout << "EOI reached." << std::endl;
- }
- else {
- std::cout << "EOI not reached. Unparsed: \"" << std::string(iter, end) << "\"" << std::endl;
- }
- std::cout << "-------------------------\n";
- }
- namespace grammars {
- namespace phx = boost::phoenix;
- template <typename Iterator>
- struct ident : qi::grammar < Iterator, std::string(), qi::space_type>
- {
- ident();
- qi::rule <iterator_type, std::string(), qi::space_type>
- id, id_list, qualified_id;
- };
- template <typename Iterator>
- ident<Iterator>::ident() : ident::base_type(id_list) {
- using qi::on_error;
- using qi::fail;
- using qi::expect;
- id = (qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_'));
- id_list = expect[id >> qi::lit(';')];
- on_error<fail>(id_list,
- phx::ref(std::cout)
- << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl
- << "Error! Expecting "
- << qi::_4
- << " here: "
- << phx::construct<std::string>(qi::_3, qi::_2) << std::endl
- << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl
- );
- }
- }
- int main() {
- grammars::ident<iterator_type> id;
- parse("expect directive, fail on first"
- , "1234; id2;"
- , "qi::expect[ id >> qi::lit(';') ]"
- , id);
- parse("expect directive, fail on second"
- , "id1, id2"
- , "qi::expect[ id >> qi::lit(';') ]"
- , id);
- parse("expect directive, success"
- , "id1;"
- , "qi::expect[ id >> qi::lit(';') ]"
- , id);
- return 0;
- }
|