1 /*=============================================================================
2 Copyright (c) 2001-2015 Joel de Guzman
3 Copyright (c) 2015 Ahmed Charles
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 ///////////////////////////////////////////////////////////////////////////////
10 // A Roman Numerals Parser (demonstrating the symbol table). This is
11 // discussed in the "Symbols" chapter in the Spirit User's Guide.
13 // [ JDG August 22, 2002 ] spirit1
14 // [ JDG March 13, 2007 ] spirit2
15 // [ JDG May 13, 2015 ] spirit X3
17 ///////////////////////////////////////////////////////////////////////////////
19 #include <boost/spirit/home/x3.hpp>
26 namespace x3
= boost::spirit::x3
;
27 namespace ascii
= boost::spirit::x3::ascii
;
29 ///////////////////////////////////////////////////////////////////////////////
30 // Parse roman hundreds (100..900) numerals using the symbol table.
31 // Notice that the data associated with each slot is the parser's attribute
32 // (which is passed to attached semantic actions).
33 ///////////////////////////////////////////////////////////////////////////////
34 struct hundreds_
: x3::symbols
<unsigned>
53 ///////////////////////////////////////////////////////////////////////////////
54 // Parse roman tens (10..90) numerals using the symbol table.
55 ///////////////////////////////////////////////////////////////////////////////
56 struct tens_
: x3::symbols
<unsigned>
75 ///////////////////////////////////////////////////////////////////////////////
76 // Parse roman ones (1..9) numerals using the symbol table.
77 ///////////////////////////////////////////////////////////////////////////////
78 struct ones_
: x3::symbols
<unsigned>
97 ///////////////////////////////////////////////////////////////////////////////
98 // roman (numerals) grammar
100 // Note the use of the || operator. The expression
101 // a || b reads match a or b and in sequence. Try
102 // defining the roman numerals grammar in YACC or
103 // PCCTS. Spirit rules! :-)
104 ///////////////////////////////////////////////////////////////////////////////
113 auto set_zero
= [](auto& ctx
){ _val(ctx
) = 0; };
114 auto add1000
= [](auto& ctx
){ _val(ctx
) += 1000; };
115 auto add
= [](auto& ctx
){ _val(ctx
) += _attr(ctx
); };
117 x3::rule
<class roman
, unsigned> const roman
= "roman";
119 auto const roman_def
=
123 -(+lit('M') [add1000
])
130 BOOST_SPIRIT_DEFINE(roman
);
134 ///////////////////////////////////////////////////////////////////////////////
136 ///////////////////////////////////////////////////////////////////////////////
140 std::cout
<< "/////////////////////////////////////////////////////////\n\n";
141 std::cout
<< "\t\tRoman Numerals Parser\n\n";
142 std::cout
<< "/////////////////////////////////////////////////////////\n\n";
143 std::cout
<< "Type a Roman Numeral ...or [q or Q] to quit\n\n";
145 typedef std::string::const_iterator iterator_type
;
146 using client::parser::roman
; // Our parser
150 while (std::getline(std::cin
, str
))
152 if (str
.empty() || str
[0] == 'q' || str
[0] == 'Q')
155 iterator_type iter
= str
.begin();
156 iterator_type
const end
= str
.end();
157 bool r
= parse(iter
, end
, roman
, result
);
159 if (r
&& iter
== end
)
161 std::cout
<< "-------------------------\n";
162 std::cout
<< "Parsing succeeded\n";
163 std::cout
<< "result = " << result
<< std::endl
;
164 std::cout
<< "-------------------------\n";
168 std::string
rest(iter
, end
);
169 std::cout
<< "-------------------------\n";
170 std::cout
<< "Parsing failed\n";
171 std::cout
<< "stopped at: \": " << rest
<< "\"\n";
172 std::cout
<< "-------------------------\n";
176 std::cout
<< "Bye... :-) \n\n";