|
Boost Users : |
Subject: [Boost-users] Question on grammar
From: Manjunath Kudlur (keveman_at_[hidden])
Date: 2010-01-26 22:31:09
I am sure this has been asked before, but I am not able to find an
answer to my specific question in the archives. I wanted to create a
grammar that can accept statements like if_(expr)[ statement-list
].else_[statement-list]. I created a if_expr type using
proto::extends, and added a member called else_ to it, of type
proto::function<proto::terminal<if_then_else>, Expr const&>. The code
is given below. I am trying to match statements of the above form.
Look for if_only_grammar and if_grammar below. The main function has 2
cases, one with just if_ and another with if_ and else_. My grammar
matches neither of them. What am I doing wrong? I am quite the newbie
to proto, so I am not still able to parse the compiler error message
and understand it yet. I will be grateful for any help.
Thanks,
Manjunath
#include <boost/proto/proto.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/assert.hpp>
#include <iostream>
#include <sstream>
#include <string>
using namespace boost;
using namespace std;
unsigned int ids;
template<typename VT>
struct Var {
unsigned int id;
Var() {
id = ++ids;
}
};
struct if_fun {};
struct program {};
struct if_then_else {};
struct if_domain;
template <typename Expr>
struct if_expr
: proto::extends<Expr, if_expr<Expr>, if_domain> {
typedef proto::extends<Expr, if_expr<Expr>, if_domain> base_type;
using base_type::operator =;
typedef typename proto::result_of::make_expr<proto::tag::function,
if_then_else, Expr const &>::type else_type;
else_type else_;
if_expr(Expr const &e = Expr())
: base_type(e)
, else_(proto::make_expr<proto::tag::function>(if_then_else(),
boost::ref(e)))
{}
};
struct if_domain
: proto::domain<proto::generator<if_expr> > {
};
struct napl_grammar;
struct arith_expr_grammar;
struct rel_expr_grammar;
struct assign_grammar;
struct statement_grammar;
struct bb_grammar;
struct if_only_grammar :
proto::or_<
proto::subscript<proto::function<if_expr<proto::terminal<if_fun>::type>,
rel_expr_grammar >, bb_grammar>
> {
};
struct if_grammar :
proto::or_<
if_only_grammar,
proto::subscript<proto::function<proto::terminal<if_then_else>,
if_only_grammar>, bb_grammar>
> {
};
struct arith_expr_grammar :
proto::or_<
proto::plus< arith_expr_grammar, arith_expr_grammar>,
proto::minus< arith_expr_grammar, arith_expr_grammar>,
proto::multiplies< arith_expr_grammar, arith_expr_grammar>,
proto::divides< arith_expr_grammar, arith_expr_grammar>,
proto::terminal<Var<int> >,
proto::terminal<int>,
rel_expr_grammar
> {
};
struct rel_expr_grammar :
proto::or_<
proto::less< arith_expr_grammar, arith_expr_grammar>,
proto::greater< arith_expr_grammar, arith_expr_grammar>,
proto::less_equal< arith_expr_grammar, arith_expr_grammar>,
proto::greater_equal< arith_expr_grammar, arith_expr_grammar>,
proto::equal_to< arith_expr_grammar, arith_expr_grammar>,
proto::not_equal_to< arith_expr_grammar, arith_expr_grammar>,
proto::logical_not< rel_expr_grammar>
> {
};
struct assign_grammar :
proto::or_<
proto::assign<proto::terminal<Var<int> >, arith_expr_grammar>,
proto::assign<proto::terminal<Var<int> >, rel_expr_grammar>
> {
};
struct statement_grammar :
proto::or_<
assign_grammar,
if_grammar
> {
};
struct bb_grammar :
proto::or_<
statement_grammar,
proto::comma<bb_grammar, statement_grammar>
> {
};
struct napl_grammar :
proto::or_<
proto::terminal<program>,
proto::subscript<proto::terminal<program>, bb_grammar>
> {
};
template<typename Expr>
void check_and_execute(const Expr &e, mpl::true_)
{
cout << "Program printer TBD.\n";
}
template<typename Expr>
void check_and_execute(const Expr &e, mpl::false_)
{
cout << "Should not be here\n";
}
template<typename Expr>
void check_grammar(const Expr &e)
{
BOOST_MPL_ASSERT_MSG((proto::matches<Expr, napl_grammar>::value),
SYNTAX_NOT_CORRECT,
(void));
check_and_execute(e, proto::matches<Expr, napl_grammar>());
//cout << napl_grammar()(e) << "\n";
}
int main()
{
proto::terminal<Var<int> >::type i1, i2, i3, i4, i5;
proto::terminal<program>::type Program;
if_expr<proto::terminal<if_fun>::type> if_;
int i=4242;
check_grammar(
Program[
if_(i1 < i2) [
i2
]
]);
/*
check_grammar(
Program[
if_(i1 < i2) [
i2
].else_[
i3
]
]);
*/
}
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net