453fa326f3
[SVN r71759]
123 lines
4.1 KiB
C++
123 lines
4.1 KiB
C++
/*=============================================================================
|
|
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;
|
|
}
|