123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- /*==============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2010-2011 Bryce Lelbach
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file BOOST_LICENSE_1_0.rst or copy at http://www.boost.org/LICENSE_1_0.txt)
- ==============================================================================*/
- #if !defined(BOOST_SPIRIT_UTREE_EXAMPLE_SEXPR_PARSER_HPP)
- #define BOOST_SPIRIT_UTREE_EXAMPLE_SEXPR_PARSER_HPP
- #include "utf8_parser.hpp"
- #include "error_handler.hpp"
- namespace boost {
- namespace spirit {
- namespace traits {
- template<>
- struct transform_attribute<utree::nil_type, unused_type, qi::domain> {
- typedef unused_type type;
- static unused_type pre (utree::nil_type&) { return unused_type(); }
- static void post (utree::nil_type&, unused_type) { }
- static void fail (utree::nil_type&) { }
- };
- } // traits
- } // spirit
- } // boost
- namespace sexpr
- {
- namespace qi = boost::spirit::qi;
- namespace px = boost::phoenix;
- namespace standard = boost::spirit::standard;
- using boost::spirit::utree;
- using boost::spirit::utf8_symbol_type;
- using boost::spirit::utf8_string_type;
- using boost::spirit::binary_string_type;
- struct bool_input_policies
- {
- template <typename Iterator, typename Attribute>
- static bool
- parse_true(Iterator& first, Iterator const& last, Attribute& attr)
- {
- using boost::spirit::qi::detail::string_parse;
- using boost::spirit::qi::bool_policies;
- using boost::spirit::qi::unused;
- using boost::spirit::traits::assign_to;
- if (string_parse("#t", first, last, unused))
- {
- assign_to(true, attr); // result is true
- return true;
- }
- return bool_policies<bool>::parse_true(first, last, attr);
- }
- template <typename Iterator, typename Attribute>
- static bool
- parse_false(Iterator& first, Iterator const& last, Attribute& attr)
- {
- using boost::spirit::qi::detail::string_parse;
- using boost::spirit::qi::bool_policies;
- using boost::spirit::qi::unused;
- using boost::spirit::traits::assign_to;
- if (string_parse("#f", first, last, unused))
- {
- assign_to(false, attr); // result is false
- return true;
- }
- return bool_policies<bool>::parse_false(first, last, attr);
- }
- };
- struct save_line_pos
- {
- template <typename, typename>
- struct result
- {
- typedef void type;
- };
- template <typename Range>
- void operator()(utree& ast, Range const& rng) const
- {
- using boost::spirit::get_line;
- std::size_t n = get_line(rng.begin());
- if (n != -1)
- {
- BOOST_ASSERT(n <= (std::numeric_limits<short>::max)());
- ast.tag(n);
- }
- else
- ast.tag(-1);
- }
- };
- template <typename Iterator, typename F>
- struct tagger : qi::grammar<Iterator, void(utree&, char)>
- {
- qi::rule<Iterator, void(utree&, char)>
- start;
-
- qi::rule<Iterator, void(utree&)>
- epsilon;
- px::function<F>
- f;
- tagger(F f_ = F()) : tagger::base_type(start), f(f_)
- {
- using qi::omit;
- using qi::raw;
- using qi::eps;
- using qi::lit;
- using qi::_1;
- using qi::_r1;
- using qi::_r2;
- start = omit[raw[lit(_r2)] [f(_r1, _1)]];
- epsilon = omit[raw[eps] [f(_r1, _1)]];
- }
- };
- template <typename Iterator>
- struct whitespace : qi::grammar<Iterator> {
- qi::rule<Iterator>
- start;
- whitespace() : whitespace::base_type(start)
- {
- using standard::space;
- using standard::char_;
- using qi::eol;
- start = space | (';' >> *(char_ - eol) >> eol);
- }
- };
- } // sexpr
- //[utree_sexpr_parser
- namespace sexpr
- {
- template <typename Iterator, typename ErrorHandler = error_handler<Iterator> >
- struct parser : qi::grammar<Iterator, utree(), whitespace<Iterator> >
- {
- qi::rule<Iterator, utree(), whitespace<Iterator> >
- start, element, list;
- qi::rule<Iterator, utree()>
- atom;
- qi::rule<Iterator, int()>
- integer;
- qi::rule<Iterator, utf8_symbol_type()>
- symbol;
-
- qi::rule<Iterator, utree::nil_type()>
- nil_;
- qi::rule<Iterator, binary_string_type()>
- binary;
- utf8::parser<Iterator>
- string;
- px::function<ErrorHandler> const
- error;
-
- tagger<Iterator, save_line_pos>
- pos;
- parser(std::string const& source_file = "<string>"):
- parser::base_type(start), error(ErrorHandler(source_file))
- {
- using standard::char_;
- using qi::unused_type;
- using qi::lexeme;
- using qi::hex;
- using qi::oct;
- using qi::no_case;
- using qi::real_parser;
- using qi::strict_real_policies;
- using qi::uint_parser;
- using qi::bool_parser;
- using qi::on_error;
- using qi::fail;
- using qi::int_;
- using qi::lit;
- using qi::_val;
- using qi::_1;
- using qi::_2;
- using qi::_3;
- using qi::_4;
- real_parser<double, strict_real_policies<double> > strict_double;
- uint_parser<unsigned char, 16, 2, 2> hex2;
- bool_parser<bool, sexpr::bool_input_policies> boolean;
-
- start = element.alias();
- element = atom | list;
- list = pos(_val, '(') > *element > ')';
- atom = nil_
- | strict_double
- | integer
- | boolean
- | string
- | symbol
- | binary;
- nil_ = qi::attr_cast(lit("nil"));
- integer = lexeme[ no_case["#x"] > hex]
- | lexeme[ no_case["#o"] >> oct]
- | lexeme[-no_case["#d"] >> int_];
- std::string exclude = std::string(" ();\"\x01-\x1f\x7f") + '\0';
- symbol = lexeme[+(~char_(exclude))];
- binary = lexeme['#' > *hex2 > '#'];
- start.name("sexpr");
- element.name("element");
- list.name("list");
- atom.name("atom");
- nil_.name("nil");
- integer.name("integer");
- symbol.name("symbol");
- binary.name("binary");
-
- on_error<fail>(start, error(_1, _2, _3, _4));
- }
- };
- } // sexpr
- //]
- #endif // BOOST_SPIRIT_UTREE_EXAMPLE_SEXPR_PARSER_HPP
|