]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/classic/example/fundamental/phoenix_calc.cpp
1 /*=============================================================================
2 Copyright (c) 2002-2003 Joel de Guzman
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 demonstrating Phoenix
12 // This is discussed in the "Closures" chapter in the Spirit User's Guide.
16 ////////////////////////////////////////////////////////////////////////////
17 #include <boost/spirit/include/classic_core.hpp>
18 #include <boost/spirit/include/classic_attribute.hpp>
22 ////////////////////////////////////////////////////////////////////////////
24 using namespace BOOST_SPIRIT_CLASSIC_NS
;
25 using namespace phoenix
;
27 ////////////////////////////////////////////////////////////////////////////
29 // Our calculator grammar using phoenix to do the semantics
31 // Note: The top rule propagates the expression result (value) upwards
32 // to the calculator grammar self.val closure member which is
33 // then visible outside the grammar (i.e. since self.val is the
34 // member1 of the closure, it becomes the attribute passed by
35 // the calculator to an attached semantic action. See the
36 // driver code that uses the calculator below).
38 ////////////////////////////////////////////////////////////////////////////
39 struct calc_closure
: BOOST_SPIRIT_CLASSIC_NS::closure
<calc_closure
, double>
44 struct calculator
: public grammar
<calculator
, calc_closure::context_t
>
46 template <typename ScannerT
>
49 definition(calculator
const& self
)
51 top
= expression
[self
.val
= arg1
];
54 = term
[expression
.val
= arg1
]
55 >> *( ('+' >> term
[expression
.val
+= arg1
])
56 | ('-' >> term
[expression
.val
-= arg1
])
61 = factor
[term
.val
= arg1
]
62 >> *( ('*' >> factor
[term
.val
*= arg1
])
63 | ('/' >> factor
[term
.val
/= arg1
])
68 = ureal_p
[factor
.val
= arg1
]
69 | '(' >> expression
[factor
.val
= arg1
] >> ')'
70 | ('-' >> factor
[factor
.val
= -arg1
])
71 | ('+' >> factor
[factor
.val
= arg1
])
75 typedef rule
<ScannerT
, calc_closure::context_t
> rule_t
;
76 rule_t expression
, term
, factor
;
80 start() const { return top
; }
84 ////////////////////////////////////////////////////////////////////////////
88 ////////////////////////////////////////////////////////////////////////////
92 cout
<< "/////////////////////////////////////////////////////////\n\n";
93 cout
<< "\t\tExpression parser using Phoenix...\n\n";
94 cout
<< "/////////////////////////////////////////////////////////\n\n";
95 cout
<< "Type an expression...or [q or Q] to quit\n\n";
97 calculator calc
; // Our parser
100 while (getline(cin
, str
))
102 if (str
.empty() || str
[0] == 'q' || str
[0] == 'Q')
106 parse_info
<> info
= parse(str
.c_str(), calc
[var(n
) = arg1
], space_p
);
108 // calc[var(n) = arg1] invokes the calculator and extracts
109 // the result of the computation. See calculator grammar
114 cout
<< "-------------------------\n";
115 cout
<< "Parsing succeeded\n";
116 cout
<< "result = " << n
<< endl
;
117 cout
<< "-------------------------\n";
121 cout
<< "-------------------------\n";
122 cout
<< "Parsing failed\n";
123 cout
<< "stopped at: \": " << info
.stop
<< "\"\n";
124 cout
<< "-------------------------\n";
128 cout
<< "Bye... :-) \n\n";