| 13 | namespace bp = boost::parser; |
| 14 | |
| 15 | int main() |
| 16 | { |
| 17 | std::cout << "Enter a number using Roman numerals. "; |
| 18 | std::string input; |
| 19 | std::getline(std::cin, input); |
| 20 | |
| 21 | //[ roman_numeral_symbol_tables |
| 22 | bp::symbols<int> const ones = { |
| 23 | {"I", 1}, |
| 24 | {"II", 2}, |
| 25 | {"III", 3}, |
| 26 | {"IV", 4}, |
| 27 | {"V", 5}, |
| 28 | {"VI", 6}, |
| 29 | {"VII", 7}, |
| 30 | {"VIII", 8}, |
| 31 | {"IX", 9}}; |
| 32 | |
| 33 | bp::symbols<int> const tens = { |
| 34 | {"X", 10}, |
| 35 | {"XX", 20}, |
| 36 | {"XXX", 30}, |
| 37 | {"XL", 40}, |
| 38 | {"L", 50}, |
| 39 | {"LX", 60}, |
| 40 | {"LXX", 70}, |
| 41 | {"LXXX", 80}, |
| 42 | {"XC", 90}}; |
| 43 | |
| 44 | bp::symbols<int> const hundreds = { |
| 45 | {"C", 100}, |
| 46 | {"CC", 200}, |
| 47 | {"CCC", 300}, |
| 48 | {"CD", 400}, |
| 49 | {"D", 500}, |
| 50 | {"DC", 600}, |
| 51 | {"DCC", 700}, |
| 52 | {"DCCC", 800}, |
| 53 | {"CM", 900}}; |
| 54 | //] |
| 55 | |
| 56 | //[ roman_numeral_actions |
| 57 | int result = 0; |
| 58 | auto const add_1000 = [&result](auto & ctx) { result += 1000; }; |
| 59 | auto const add = [&result](auto & ctx) { result += _attr(ctx); }; |
| 60 | //] |
| 61 | |
| 62 | //[ roman_numeral_parser |
| 63 | using namespace bp::literals; |
| 64 | auto const parser = |
| 65 | *'M'_l[add_1000] >> -hundreds[add] >> -tens[add] >> -ones[add]; |
| 66 | //] |
| 67 | |
| 68 | if (bp::parse(input, parser) && result != 0) |
| 69 | std::cout << "That's " << result << " in Arabic numerals.\n"; |
| 70 | else |
| 71 | std::cout << "That's not a Roman number.\n"; |
| 72 | } |