123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- /*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- http://spirit.sourceforge.net/
- 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 <boost/spirit/include/qi.hpp>
- #include <boost/spirit/include/karma.hpp>
- #include <boost/fusion/include/adapt_struct.hpp>
- #include <boost/spirit/repository/include/qi_kwd.hpp>
- #include <boost/spirit/repository/include/qi_keywords.hpp>
- #include <boost/optional.hpp>
- #include <boost/cstdint.hpp>
- #include <iostream>
- #include <string>
- #include <cstdlib>
- #include <iterator>
- #include <map>
- #include <vector>
- // Data structure definitions
- // preprocessor constants
- typedef std::pair<std::string, boost::int32_t> preprocessor_symbol;
- BOOST_FUSION_ADAPT_STRUCT( preprocessor_symbol,
- (std::string, first)
- (boost::int32_t, second)
- )
- // A data structure to store our program options
- struct program_options {
- std::vector<std::string> includes; // include paths
- typedef std::vector< preprocessor_symbol > preprocessor_symbols_container; // symbol container type definition
- preprocessor_symbols_container preprocessor_symbols; // preprocessor symbols
- boost::optional<std::string> output_filename; // output file name
- std::string source_filename; // source file name
-
- };
- // Make the program_options compatible with fusion sequences
- BOOST_FUSION_ADAPT_STRUCT( program_options,
- (std::vector<std::string>, includes)
- (program_options::preprocessor_symbols_container, preprocessor_symbols)
- (boost::optional<std::string>, output_filename)
- (std::string, source_filename)
- )
- // Output helper to check that the data parsed matches what we expect
- std::ostream &operator<<(std::ostream &os, const program_options &obj)
- {
- using boost::spirit::karma::string;
- using boost::spirit::karma::int_;
- using boost::spirit::karma::lit;
- using boost::spirit::karma::buffer;
- using boost::spirit::karma::eol;
- using boost::spirit::karma::format;
- return os<<format(
- lit("Includes:") << (string % ',') << eol
- << lit("Preprocessor symbols:") << ((string <<"="<< int_) % ',') << eol
- << buffer[-( lit("Output file:")<< string << eol)]
- << lit("Source file:")<< string << eol
- ,obj);
- return os;
- }
- int
- main()
- {
-
- {
- // Pull everything we need from qi into this scope
- using boost::spirit::repository::qi::kwd;
- using boost::spirit::qi::inf;
- using boost::spirit::ascii::space_type;
- using boost::spirit::ascii::alnum;
- using boost::spirit::qi::int_;
- using boost::spirit::qi::rule;
- using boost::spirit::qi::lit;
- using boost::spirit::qi::attr;
- using boost::spirit::qi::lexeme;
- using boost::spirit::qi::hold;
- using boost::spirit::qi::ascii::space;
-
- //Rule declarations
- rule<const char *, std::string(), space_type> parse_string;
- rule<const char *, program_options(), space_type> kwd_rule;
-
- // A string parser
- parse_string %= lexeme[*alnum];
-
- namespace phx=boost::phoenix;
- // kwd rule
- kwd_rule %=
- kwd("--include")[ parse_string ]
- / kwd("--define")[ parse_string >> ((lit('=') > int_) | attr(1)) ]
- / kwd("--output",0,1)[ parse_string ]
- / hold [kwd("--source",1)[ parse_string ]]
- ;
- //
-
- using boost::spirit::qi::phrase_parse;
- // Let's check what that parser can do
- program_options result;
-
- char const input[]="--include path1 --source file1 --define SYMBOL1=10 --include path2 --source file2";
- char const* f(input);
- char const* l(f + strlen(f));
- if (phrase_parse(f, l, kwd_rule, space,result) && (f == l))
- std::cout << "ok" << std::endl;
- else
- std::cout << "fail" << std::endl;
- // Output the result to the console
- std::cout<<result<<std::endl;
- }
- return 0;
- }
|