Bonjour à tous,
J'essaie de me mettre à boost.proto mais j'ai un petit problème dès les premiers exemples du users'guide notamment celui où l'on cherche à faire un petit calculateur permettant d'écrire des trucs comme:
mais surtout des trucs comme:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 auto const& f=_1*_1-_1; std::cout << f(3) << std::endl; //affiche "6"
Ce que j'arrive pas à faire c'est à valider par une grammaire le deuxième exemple.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 auto const& g= square(_1)-_1; std::cout << g(3) << std::endl; //affiche "6"
Voici l'exemple:
tout d'abord les includes nécessaires:
ensuite la fonction square:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 #include <iostream> #include <vector> #include <algorithm> #include <boost/mpl/int.hpp> #include <boost/proto/core.hpp> #include <boost/proto/context.hpp> namespace proto = boost::proto;
ensuite la grammaire des expressions possibles:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 // Define a square_fun function object struct square_fun { typedef double result_type; double operator()(double d) const { return std::pow(d, 2); } }; // Define a lazy square() function for the calculator EDSL. template< typename Arg > typename proto::result_of::make_expr< proto::tag::function // Tag type , square_fun // First child (by value) , Arg const & // Second child (by reference) >::type const square(Arg const &arg) { return proto::make_expr<proto::tag::function>( square_fun() // First child (by value) , boost::ref(arg) // Second child (by reference) ); }
et enfin le reste du code avec le contexte, le domaine et le calculateur:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 struct calculator_grammar : proto::or_< proto::plus< calculator_grammar, calculator_grammar > , proto::minus< calculator_grammar, calculator_grammar > , proto::minus< double, calculator_grammar > , proto::multiplies< calculator_grammar, calculator_grammar > , proto::divides< calculator_grammar, calculator_grammar > , proto::terminal< proto::_ > //ici je ne sais pas quoi mettre pour valider les expressions à base de square > {};
Le truc c'est que si j'active ma grammaire mon exemple avec f compile mais pas celui avec g (normal ça respecte pas ma grammaire). Donc voilà, comment je peux ajouter square(calculator_grammar) à ma grammaire?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 struct calculator_context : proto::callable_context< calculator_context const > { // Values to replace the placeholders std::vector<double> args; // Define the result type of the calculator. // (This makes the calculator_context "callable".) typedef double result_type; // Handle the placeholders: template<int I> double operator()(proto::tag::terminal, boost::mpl::int_<I>) const { return this->args[I]; } }; // Forward-declare an expression wrapper template<typename Expr> struct calculator; // Define a calculator domain. Expression within // the calculator domain will be wrapped in the // calculator<> expression wrapper. struct calculator_domain : proto::domain< proto::generator<calculator>/*, calculator_grammar*/ > {}; // Define a calculator expression wrapper. It behaves just like // the expression it wraps, but with an extra operator() member // function that evaluates the expression. template<typename Expr> struct calculator : proto::extends<Expr, calculator<Expr>, calculator_domain> { typedef proto::extends<Expr, calculator<Expr>, calculator_domain> base_type; calculator(Expr const &expr = Expr()) : base_type(expr) {} typedef double result_type; // Overload operator() to invoke proto::eval() with // our calculator_context. double operator()(double a1) const { calculator_context ctx; ctx.args.push_back(a1); return proto::eval(*this, ctx); } }; // Define the Protofied placeholder terminals calculator<proto::terminal<boost::mpl::int_<0> >::type> const _1; int main() { auto const& f = _1*_1 - _1; std::cout << f(3) << std::endl; auto const& g = square(_1) - _1; std::cout << g(3) << std::endl; return 0; }
Partager