123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- /*=============================================================================
- 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)
- =============================================================================*/
- //[reference_includes
- #include <boost/spirit/include/qi.hpp>
- #include <boost/spirit/include/phoenix_core.hpp>
- #include <boost/spirit/include/phoenix_operator.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 <iostream>
- #include <string>
- #include <cstdlib>
- #include <iterator>
- //]
- //[reference_test
- template <typename P>
- void test_parser(
- char const* input, P const& p, bool full_match = true)
- {
- using boost::spirit::qi::parse;
- char const* f(input);
- char const* l(f + strlen(f));
- if (parse(f, l, p) && (!full_match || (f == l)))
- std::cout << "ok" << std::endl;
- else
- std::cout << "fail" << std::endl;
- }
- template <typename P>
- void test_phrase_parser(
- char const* input, P const& p, bool full_match = true)
- {
- using boost::spirit::qi::phrase_parse;
- using boost::spirit::qi::ascii::space;
-
- char const* f(input);
- char const* l(f + strlen(f));
- if (phrase_parse(f, l, p, space) && (!full_match || (f == l)))
- std::cout << "ok" << std::endl;
- else
- std::cout << "fail" << std::endl;
- }
- //]
- //[reference_test_attr
- template <typename P, typename T>
- void test_parser_attr(
- char const* input, P const& p, T& attr, bool full_match = true)
- {
- using boost::spirit::qi::parse;
- char const* f(input);
- char const* l(f + strlen(f));
- if (parse(f, l, p, attr) && (!full_match || (f == l)))
- std::cout << "ok" << std::endl;
- else
- std::cout << "fail" << std::endl;
- }
- template <typename P, typename T>
- void test_phrase_parser_attr(
- char const* input, P const& p, T& attr, bool full_match = true)
- {
- using boost::spirit::qi::phrase_parse;
- using boost::spirit::qi::ascii::space;
- char const* f(input);
- char const* l(f + strlen(f));
- if (phrase_parse(f, l, p, space, attr) && (!full_match || (f == l)))
- std::cout << "ok" << std::endl;
- else
- std::cout << "fail" << std::endl;
- }
- //]
- //[reference_keyword_list_test_data_structure
- // Data structure definitions to test the kwd directive
- // and the keywords list operator
- struct person {
- std::string name;
- int age;
- double size;
- std::vector<std::string> favorite_colors;
-
- };
- std::ostream &operator<<(std::ostream &os, const person &p)
- {
- os<<"Person : "<<p.name<<", "<<p.age<<", "<<p.size<<std::endl;
- std::copy(p.favorite_colors.begin(),p.favorite_colors.end(),std::ostream_iterator<std::string>(os,"\n"));
- return os;
- }
- BOOST_FUSION_ADAPT_STRUCT( person,
- (std::string, name)
- (int, age)
- (double, size)
- (std::vector<std::string>, favorite_colors)
- )
- //]
- int
- main()
- {
-
- // keyword_list
- {
- //[reference_using_declarations_keyword_list
- using boost::spirit::repository::qi::kwd;
- using boost::spirit::qi::inf;
- using boost::spirit::ascii::space_type;
- using boost::spirit::ascii::char_;
- using boost::spirit::qi::double_;
- using boost::spirit::qi::int_;
- using boost::spirit::qi::rule;
- //]
-
- //[reference_keyword_list_rule_declarations
- rule<const char *, std::string(), space_type> parse_string;
- rule<const char *, person(), space_type> no_constraint_person_rule, constraint_person_rule;
-
- parse_string %= '"'> *(char_-'"') > '"';
- //]
-
- //[reference_keyword_list_no_constraint_rule
- no_constraint_person_rule %=
- kwd("name")['=' > parse_string ]
- / kwd("age") ['=' > int_]
- / kwd("size") ['=' > double_ > 'm']
- ;
- //]
-
- //[reference_keyword_list
- //`Parsing a keyword list:
- // Let's declare a small list of people for which we want to collect information.
- person John,Mary,Mike,Hellen,Johny;
- test_phrase_parser_attr(
- "name = \"John\" \n age = 10 \n size = 1.69m "
- ,no_constraint_person_rule
- ,John); // full in orginal order
- std::cout<<John;
- test_phrase_parser_attr(
- "age = 10 \n size = 1.69m \n name = \"Mary\""
- ,no_constraint_person_rule
- ,Mary); // keyword oder doesn't matter
- std::cout<<Mary;
- test_phrase_parser_attr(
- "size = 1.69m \n name = \"Mike\" \n age = 10 "
- ,no_constraint_person_rule
- ,Mike); // still the same result
-
- std::cout<<Mike;
-
- /*`The code above will print:[teletype]
-
- Person : John, 10, 1.69
- Person : Mary, 10, 1.69
- Person : Mike, 10, 1.69
- */
- //]
- //[reference_keyword_list_constraint_rule
- /*`The parser definition below uses the kwd directive occurrence constraint variants to
- make sure that the name and age keyword occur only once and allows the favorite color
- entry to appear 0 or more times. */
- constraint_person_rule %=
- kwd("name",1) ['=' > parse_string ]
- / kwd("age" ,1) ['=' > int_]
- / kwd("size" ,1) ['=' > double_ > 'm']
- / kwd("favorite color",0,inf) [ '=' > parse_string ]
- ;
- //]
-
- //[reference_keyword_list_constraints
-
- // Here all the give constraint are resepected : parsing will succeed.
- test_phrase_parser_attr(
- "name = \"Hellen\" \n age = 10 \n size = 1.80m \n favorite color = \"blue\" \n favorite color = \"green\" "
- ,constraint_person_rule
- ,Hellen);
- std::cout<<Hellen;
-
- // Parsing this string will fail because the age and size minimum occurrence requirements aren't met.
- test_phrase_parser_attr(
- "name = \"Johny\" \n favorite color = \"blue\" \n favorite color = \"green\" "
- ,constraint_person_rule
- ,Johny );
-
- /*`Parsing the first string will succeed but fail for the second string as the
- occurrence constraints aren't met. This code should print:[teletype]
-
- Person : Hellen, 10, 1.8
- blue
- green
- */
- //]
- }
-
-
- return 0;
- }
|