1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 http://spirit.sourceforge.net/
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #include <boost/spirit/include/qi.hpp>
9 #include <boost/spirit/include/karma.hpp>
10 #include <boost/fusion/include/adapt_struct.hpp>
11 #include <boost/spirit/repository/include/qi_kwd.hpp>
12 #include <boost/spirit/repository/include/qi_keywords.hpp>
13 #include <boost/optional.hpp>
14 #include <boost/cstdint.hpp>
22 // Data structure definitions
24 // preprocessor constants
25 typedef std::pair
<std::string
, boost::int32_t> preprocessor_symbol
;
27 BOOST_FUSION_ADAPT_STRUCT( preprocessor_symbol
,
29 (boost::int32_t, second
)
32 // A data structure to store our program options
33 struct program_options
{
34 std::vector
<std::string
> includes
; // include paths
35 typedef std::vector
< preprocessor_symbol
> preprocessor_symbols_container
; // symbol container type definition
36 preprocessor_symbols_container preprocessor_symbols
; // preprocessor symbols
37 boost::optional
<std::string
> output_filename
; // output file name
38 std::string source_filename
; // source file name
42 // Make the program_options compatible with fusion sequences
43 BOOST_FUSION_ADAPT_STRUCT( program_options
,
44 (std::vector
<std::string
>, includes
)
45 (program_options::preprocessor_symbols_container
, preprocessor_symbols
)
46 (boost::optional
<std::string
>, output_filename
)
47 (std::string
, source_filename
)
51 // Output helper to check that the data parsed matches what we expect
52 std::ostream
&operator<<(std::ostream
&os
, const program_options
&obj
)
54 using boost::spirit::karma::string
;
55 using boost::spirit::karma::int_
;
56 using boost::spirit::karma::lit
;
57 using boost::spirit::karma::buffer
;
58 using boost::spirit::karma::eol
;
59 using boost::spirit::karma::format
;
61 lit("Includes:") << (string
% ',') << eol
62 << lit("Preprocessor symbols:") << ((string
<<"="<< int_
) % ',') << eol
63 << buffer
[-( lit("Output file:")<< string
<< eol
)]
64 << lit("Source file:")<< string
<< eol
75 // Pull everything we need from qi into this scope
76 using boost::spirit::repository::qi::kwd
;
77 using boost::spirit::qi::inf
;
78 using boost::spirit::ascii::space_type
;
79 using boost::spirit::ascii::alnum
;
80 using boost::spirit::qi::int_
;
81 using boost::spirit::qi::rule
;
82 using boost::spirit::qi::lit
;
83 using boost::spirit::qi::attr
;
84 using boost::spirit::qi::lexeme
;
85 using boost::spirit::qi::hold
;
86 using boost::spirit::qi::ascii::space
;
89 rule
<const char *, std::string(), space_type
> parse_string
;
90 rule
<const char *, program_options(), space_type
> kwd_rule
;
93 parse_string
%= lexeme
[*alnum
];
95 namespace phx
=boost::phoenix
;
98 kwd("--include")[ parse_string
]
99 / kwd("--define")[ parse_string
>> ((lit('=') > int_
) | attr(1)) ]
100 / kwd("--output",0,1)[ parse_string
]
101 / hold
[kwd("--source",1)[ parse_string
]]
105 using boost::spirit::qi::phrase_parse
;
107 // Let's check what that parser can do
108 program_options result
;
110 char const input
[]="--include path1 --source file1 --define SYMBOL1=10 --include path2 --source file2";
111 char const* f(input
);
112 char const* l(f
+ strlen(f
));
113 if (phrase_parse(f
, l
, kwd_rule
, space
,result
) && (f
== l
))
114 std::cout
<< "ok" << std::endl
;
116 std::cout
<< "fail" << std::endl
;
118 // Output the result to the console
119 std::cout
<<result
<<std::endl
;