]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/classic/example/fundamental/more_calculators/phoenix_subrule_calc.cpp
1 /*=============================================================================
2 Copyright (c) 2002-2003 Hartmut Kaiser
3 http://spirit.sourceforge.net/
5 Use, modification and distribution is subject to the Boost Software
6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9 ///////////////////////////////////////////////////////////////////////////////
11 // Full calculator example
12 // [ demonstrating phoenix and subrules ]
14 // [ Hartmut Kaiser 10/8/2002 ]
16 ///////////////////////////////////////////////////////////////////////////////
18 //#define BOOST_SPIRIT_DEBUG // define this for debug output
20 #include <boost/spirit/include/classic_core.hpp>
21 #include <boost/spirit/include/classic_attribute.hpp>
25 ///////////////////////////////////////////////////////////////////////////////
27 using namespace BOOST_SPIRIT_CLASSIC_NS
;
28 using namespace phoenix
;
30 ///////////////////////////////////////////////////////////////////////////////
32 // Our calculator grammar using phoenix to do the semantics and subrule's
33 // as it's working horses
35 // Note: The top rule propagates the expression result (value) upwards
36 // to the calculator grammar self.val closure member which is
37 // then visible outside the grammar (i.e. since self.val is the
38 // member1 of the closure, it becomes the attribute passed by
39 // the calculator to an attached semantic action. See the
40 // driver code that uses the calculator below).
42 ///////////////////////////////////////////////////////////////////////////////
43 struct calc_closure
: BOOST_SPIRIT_CLASSIC_NS::closure
<calc_closure
, double>
48 struct calculator
: public grammar
<calculator
, calc_closure::context_t
>
50 template <typename ScannerT
>
53 definition(calculator
const& self
)
58 >> *( ('+' >> term
[self
.val
+= arg1
])
59 | ('-' >> term
[self
.val
-= arg1
])
64 factor
[term
.val
= arg1
]
65 >> *( ('*' >> factor
[term
.val
*= arg1
])
66 | ('/' >> factor
[term
.val
/= arg1
])
71 = ureal_p
[factor
.val
= arg1
]
72 | '(' >> expression
[factor
.val
= arg1
] >> ')'
73 | ('-' >> factor
[factor
.val
= -arg1
])
74 | ('+' >> factor
[factor
.val
= arg1
])
77 BOOST_SPIRIT_DEBUG_NODE(top
);
78 BOOST_SPIRIT_DEBUG_NODE(expression
);
79 BOOST_SPIRIT_DEBUG_NODE(term
);
80 BOOST_SPIRIT_DEBUG_NODE(factor
);
83 subrule
<0, calc_closure::context_t
> expression
;
84 subrule
<1, calc_closure::context_t
> term
;
85 subrule
<2, calc_closure::context_t
> factor
;
90 start() const { return top
; }
94 ///////////////////////////////////////////////////////////////////////////////
98 ///////////////////////////////////////////////////////////////////////////////
102 cout
<< "/////////////////////////////////////////////////////////\n\n";
103 cout
<< "\t\tExpression parser using Phoenix...\n\n";
104 cout
<< "/////////////////////////////////////////////////////////\n\n";
105 cout
<< "Type an expression...or [q or Q] to quit\n\n";
107 calculator calc
; // Our parser
110 while (getline(cin
, str
))
112 if (str
.empty() || str
[0] == 'q' || str
[0] == 'Q')
116 parse_info
<> info
= parse(str
.c_str(), calc
[var(n
) = arg1
], space_p
);
118 // calc[var(n) = arg1] invokes the calculator and extracts
119 // the result of the computation. See calculator grammar
124 cout
<< "-------------------------\n";
125 cout
<< "Parsing succeeded\n";
126 cout
<< "result = " << n
<< endl
;
127 cout
<< "-------------------------\n";
131 cout
<< "-------------------------\n";
132 cout
<< "Parsing failed\n";
133 cout
<< "stopped at: \": " << info
.stop
<< "\"\n";
134 cout
<< "-------------------------\n";
138 cout
<< "Bye... :-) \n\n";