|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r61580 - in trunk/libs/spirit/example/scheme: example/generate_qiexpr example/parse_qiexpr qi
From: hartmut.kaiser_at_[hidden]
Date: 2010-04-26 13:34:01
Author: hkaiser
Date: 2010-04-26 13:33:59 EDT (Mon, 26 Apr 2010)
New Revision: 61580
URL: http://svn.boost.org/trac/boost/changeset/61580
Log:
Spirit: added Qi rules and grammars to Qi parser
Text files modified:
trunk/libs/spirit/example/scheme/example/generate_qiexpr/generate_qi_test.cpp | 2
trunk/libs/spirit/example/scheme/example/generate_qiexpr/input.txt | 2
trunk/libs/spirit/example/scheme/example/parse_qiexpr/generate_sexpr_to_ostream.cpp | 1
trunk/libs/spirit/example/scheme/example/parse_qiexpr/parse_qi_test.cpp | 88 ++++++++++++++++++++++++++++++++++-----
trunk/libs/spirit/example/scheme/example/parse_qiexpr/parse_qiexpr.cpp | 4 +
trunk/libs/spirit/example/scheme/qi/parse_qiexpr.hpp | 8 +++
trunk/libs/spirit/example/scheme/qi/parse_qiexpr_impl.hpp | 30 +++++++++++++
trunk/libs/spirit/example/scheme/qi/qiexpr_parser.hpp | 70 ++++++++++++++++++++++++++++---
8 files changed, 182 insertions(+), 23 deletions(-)
Modified: trunk/libs/spirit/example/scheme/example/generate_qiexpr/generate_qi_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/example/generate_qiexpr/generate_qi_test.cpp (original)
+++ trunk/libs/spirit/example/scheme/example/generate_qiexpr/generate_qi_test.cpp 2010-04-26 13:33:59 EDT (Mon, 26 Apr 2010)
@@ -29,7 +29,7 @@
str += '\n';
scheme::utree result;
- if (scheme::input::parse_qiexpr(str, result))
+ if (scheme::input::parse_qi_expr(str, result))
{
std::string str;
if (scheme::output::generate_qiexpr(result, str))
Modified: trunk/libs/spirit/example/scheme/example/generate_qiexpr/input.txt
==============================================================================
--- trunk/libs/spirit/example/scheme/example/generate_qiexpr/input.txt (original)
+++ trunk/libs/spirit/example/scheme/example/generate_qiexpr/input.txt 2010-04-26 13:33:59 EDT (Mon, 26 Apr 2010)
@@ -1,3 +1,5 @@
+int_ >> *(('+' >> int_) | ('-' >> int_))
+
// Copyright (c) 2001-2010 Hartmut Kaiser
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
Modified: trunk/libs/spirit/example/scheme/example/parse_qiexpr/generate_sexpr_to_ostream.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/example/parse_qiexpr/generate_sexpr_to_ostream.cpp (original)
+++ trunk/libs/spirit/example/scheme/example/parse_qiexpr/generate_sexpr_to_ostream.cpp 2010-04-26 13:33:59 EDT (Mon, 26 Apr 2010)
@@ -13,6 +13,7 @@
namespace scheme { namespace output
{
template bool generate_sexpr(BOOST_TYPEOF(std::cout)&, utree const& result);
+ template bool generate_sexpr_list(BOOST_TYPEOF(std::cout)&, utree const& result);
}}
///////////////////////////////////////////////////////////////////////////////
Modified: trunk/libs/spirit/example/scheme/example/parse_qiexpr/parse_qi_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/example/parse_qiexpr/parse_qi_test.cpp (original)
+++ trunk/libs/spirit/example/scheme/example/parse_qiexpr/parse_qi_test.cpp 2010-04-26 13:33:59 EDT (Mon, 26 Apr 2010)
@@ -11,15 +11,79 @@
#include <fstream>
#include <iterator>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/lexical_cast.hpp>
+
#include <utree/utree.hpp>
#include <qi/parse_qiexpr.hpp>
#include <output/generate_sexpr.hpp>
///////////////////////////////////////////////////////////////////////////////
+bool parse_rhs(std::string const& str, scheme::utree& result)
+{
+ if (scheme::input::parse_qi_expr(str, result))
+ {
+ if (scheme::output::generate_sexpr(std::cout, result))
+ {
+ std::cout << std::endl;
+ return true;
+ }
+ else
+ {
+ std::cout << "generate error" << std::endl;
+ }
+ }
+ else
+ {
+ std::cout << "parse error" << std::endl;
+ }
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool parse_rule(std::string str)
+{
+ // construct a rule
+ str = "name = " + str;
+
+ // parse it
+ scheme::utree result;
+ if (scheme::input::parse_qi_rule(str, result))
+ {
+ if (scheme::output::generate_sexpr(std::cout, result))
+ {
+ std::cout << std::endl;
+ return true;
+ }
+ }
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+bool parse_grammar(std::string str)
+{
+ // parse it
+ scheme::utree result;
+// if (scheme::input::parse_qi_grammar(str, result))
+ scheme::input::parse_qi_grammar(str, result);
+ {
+ if (scheme::output::generate_sexpr_list(std::cout, result))
+ {
+ std::cout << std::endl;
+ return true;
+ }
+ }
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
// Main program
///////////////////////////////////////////////////////////////////////////////
int main(int argc, char **argv)
{
+ std::string rules;
+ int i = 0;
+
std::string str;
while (std::getline(std::cin, str))
{
@@ -27,22 +91,22 @@
break;
str += '\n';
+ bool r = false;
scheme::utree result;
- if (scheme::input::parse_qiexpr(str, result))
+ BOOST_TEST(r = parse_rhs(str, result));
+ if (r && result.which() != scheme::utree_type::nil_type)
{
- if (scheme::output::generate_sexpr(std::cout, result))
+ BOOST_TEST(r = parse_rule(str));
+ if (r)
{
- std::cout << std::endl;
- }
- else
- {
- std::cout << "generate error" << std::endl;
+ rules += "rule" + boost::lexical_cast<std::string>(++i)
+ + " = " + str + "\n";
}
}
- else
- {
- std::cout << "parse error" << std::endl;
- }
}
- return 0;
+
+ // now test grammar rule
+ BOOST_TEST(parse_grammar(rules));
+
+ return boost::report_errors();
}
Modified: trunk/libs/spirit/example/scheme/example/parse_qiexpr/parse_qiexpr.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/example/parse_qiexpr/parse_qiexpr.cpp (original)
+++ trunk/libs/spirit/example/scheme/example/parse_qiexpr/parse_qiexpr.cpp 2010-04-26 13:33:59 EDT (Mon, 26 Apr 2010)
@@ -11,6 +11,8 @@
// explicit template instantiation for the function parse_qiexpr
namespace scheme { namespace input
{
- template bool parse_qiexpr(std::string const&, utree& result);
+ template bool parse_qi_expr(std::string const&, utree& result);
+ template bool parse_qi_rule(std::string const&, utree& result);
+ template bool parse_qi_grammar(std::string const&, utree& result);
}}
Modified: trunk/libs/spirit/example/scheme/qi/parse_qiexpr.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/qi/parse_qiexpr.hpp (original)
+++ trunk/libs/spirit/example/scheme/qi/parse_qiexpr.hpp 2010-04-26 13:33:59 EDT (Mon, 26 Apr 2010)
@@ -11,7 +11,13 @@
namespace scheme { namespace input
{
template <typename String>
- bool parse_qiexpr(String const& str, utree& result);
+ bool parse_qi_expr(String const& str, utree& result);
+
+ template <typename String>
+ bool parse_qi_rule(String const& str, utree& result);
+
+ template <typename String>
+ bool parse_qi_grammar(String const& str, utree& result);
}}
#endif
Modified: trunk/libs/spirit/example/scheme/qi/parse_qiexpr_impl.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/qi/parse_qiexpr_impl.hpp (original)
+++ trunk/libs/spirit/example/scheme/qi/parse_qiexpr_impl.hpp 2010-04-26 13:33:59 EDT (Mon, 26 Apr 2010)
@@ -17,7 +17,7 @@
{
///////////////////////////////////////////////////////////////////////////
template <typename String>
- bool parse_qiexpr(String const& str, utree& result)
+ bool parse_qi_expr(String const& str, utree& result)
{
typedef typename String::const_iterator iterator_type;
@@ -28,6 +28,34 @@
iterator_type end = str.end();
return phrase_parse(begin, end, p, ws, result) && begin == end;
}
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename String>
+ bool parse_qi_rule(String const& str, utree& result)
+ {
+ typedef typename String::const_iterator iterator_type;
+
+ scheme::qi::qiexpr_parser<iterator_type> p;
+ scheme::qi::qiexpr_white_space<iterator_type> ws;
+
+ iterator_type begin = str.begin();
+ iterator_type end = str.end();
+ return phrase_parse(begin, end, p.rule_, ws, result) && begin == end;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename String>
+ bool parse_qi_grammar(String const& str, utree& result)
+ {
+ typedef typename String::const_iterator iterator_type;
+
+ scheme::qi::qiexpr_parser<iterator_type> p;
+ scheme::qi::qiexpr_white_space<iterator_type> ws;
+
+ iterator_type begin = str.begin();
+ iterator_type end = str.end();
+ return phrase_parse(begin, end, p.grammar_, ws, result) && begin == end;
+ }
}}
#endif
Modified: trunk/libs/spirit/example/scheme/qi/qiexpr_parser.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/qi/qiexpr_parser.hpp (original)
+++ trunk/libs/spirit/example/scheme/qi/qiexpr_parser.hpp 2010-04-26 13:33:59 EDT (Mon, 26 Apr 2010)
@@ -40,6 +40,7 @@
using boost::spirit::qi::_val;
using boost::spirit::qi::_1;
using boost::spirit::qi::_2;
+ using boost::spirit::qi::lexeme;
using boost::phoenix::push_back;
///////////////////////////////////////////////////////////////////////////
@@ -84,7 +85,7 @@
// element is the symbol this function object has been constructed from
struct make_list_node
{
- template <typename T1, typename T2 = nil, typename T3 = nil>
+ template <typename T1, typename T2 = nil>
struct result { typedef void type; };
explicit make_list_node(char const* symbol_)
@@ -120,6 +121,15 @@
val.push_back(element);
}
+ utf8_symbol symbol;
+ };
+
+ ///////////////////////////////////////////////////////////////////////
+ struct make_directive_node
+ {
+ template <typename T1, typename T2, typename T3>
+ struct result { typedef void type; };
+
void operator()(utree& val, utree const& element, utree const& sym) const
{
if (!is_list_node(val, sym)) {
@@ -131,8 +141,29 @@
}
val.push_back(element);
}
+ };
- utf8_symbol symbol;
+ ///////////////////////////////////////////////////////////////////////
+ // this creates a scheme definition:
+ //
+ // i.e. (define (_1) exp)
+ struct make_define_node
+ {
+ template <typename T1, typename T2, typename T3>
+ struct result { typedef void type; };
+
+ explicit make_define_node() : define_("define") {}
+
+ void operator()(utree& val, utree const& name, utree const& exp) const
+ {
+ val.push_back(define_);
+ utree n;
+ n.push_back(name);
+ val.push_back(n);
+ val.push_back(exp);
+ }
+
+ utf8_symbol define_;
};
}
@@ -144,12 +175,16 @@
typedef typename boost::detail::iterator_traits<Iterator>::value_type
char_type;
- qiexpr_parser() : qiexpr_parser::base_type(start)
+ qiexpr_parser() : qiexpr_parser::base_type(rhs)
{
namespace phoenix = boost::phoenix;
typedef phoenix::function<detail::make_list_node> make_list_type;
+ typedef phoenix::function<detail::make_directive_node> make_directive_type;
+ typedef phoenix::function<detail::make_define_node> make_define_type;
+
+ make_directive_type make_directive = detail::make_directive_node();
- make_list_type make_directive = detail::make_list_node("");
+ make_define_type make_define = detail::make_define_node();
make_list_type make_sequence = detail::make_list_node("qi:>>");
make_list_type make_permutation = detail::make_list_node("qi:^");
@@ -163,7 +198,20 @@
make_list_type make_literal = detail::make_list_node("qi:lit");
- start = -alternative;
+ // grammar definition
+ grammar_ = +rule_
+ ;
+
+ // rule definition
+ rule_ =
+ (symbol >> '=' >> alternative)
+ [
+ make_define(_val, _1, _2)
+ ]
+ ;
+
+ // right hand side of a rule (any parser expression)
+ rhs = -alternative;
// A | B
alternative =
@@ -222,6 +270,9 @@
| string_lit.char_lit [ phoenix::push_back(_val, _1) ]
;
+ std::string exclude = std::string(" ();\"\x01-\x1f\x7f") + '\0';
+ symbol = lexeme[+(~char_(exclude))];
+
// fill the symbol tables with all known primitive parser names
std::string name("qi:");
for (char const* const* p = primitives0; *p; ++p)
@@ -251,12 +302,15 @@
directive0.add(*p, u);
}
- BOOST_SPIRIT_DEBUG_NODE(start);
+ BOOST_SPIRIT_DEBUG_NODE(grammar_);
+ BOOST_SPIRIT_DEBUG_NODE(rule_);
+ BOOST_SPIRIT_DEBUG_NODE(rhs);
BOOST_SPIRIT_DEBUG_NODE(directive);
BOOST_SPIRIT_DEBUG_NODE(primitive);
BOOST_SPIRIT_DEBUG_NODE(unary_term);
BOOST_SPIRIT_DEBUG_NODE(term);
BOOST_SPIRIT_DEBUG_NODE(literal);
+ BOOST_SPIRIT_DEBUG_NODE(symbol);
BOOST_SPIRIT_DEBUG_NODE(alternative);
BOOST_SPIRIT_DEBUG_NODE(permutation);
BOOST_SPIRIT_DEBUG_NODE(sequence);
@@ -264,8 +318,10 @@
typedef rule<Iterator, qiexpr_white_space<Iterator>, utree()> rule_type;
- rule_type start, directive, primitive, unary_term, term, literal;
+ rule_type grammar_, rule_;
+ rule_type rhs, directive, primitive, unary_term, term, literal;
rule_type alternative, permutation, sequence;
+ rule<Iterator, utf8_symbol()> symbol;
symbols<char_type, utree> directive0, directive1;
symbols<char_type, utree> primitive0, primitive1, primitive2;
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk