]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/context/example/parser.cpp
bump version to 12.2.12-pve1
[ceph.git] / ceph / src / boost / libs / context / example / parser.cpp
CommitLineData
7c673cae 1
b32b8144 2// Copyright Oliver Kowalke 2016.
7c673cae
FG
3// Distributed under the Boost Software License, Version 1.0.
4// (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6
b32b8144 7#include <cstdio>
7c673cae
FG
8#include <cstdlib>
9#include <exception>
10#include <functional>
11#include <iostream>
12#include <memory>
13#include <sstream>
14
b32b8144
FG
15#include <boost/context/continuation.hpp>
16
17namespace ctx = boost::context;
7c673cae
FG
18
19/*
20 * grammar:
21 * P ---> E '\0'
22 * E ---> T {('+'|'-') T}
23 * T ---> S {('*'|'/') S}
24 * S ---> digit | '(' E ')'
25 */
26class Parser{
27 char next;
28 std::istream& is;
29 std::function<void(char)> cb;
30
31 char pull(){
32 return std::char_traits<char>::to_char_type(is.get());
33 }
34
35 void scan(){
36 do{
37 next=pull();
38 }
39 while(isspace(next));
40 }
41
42public:
43 Parser(std::istream& is_,std::function<void(char)> cb_) :
44 next(), is(is_), cb(cb_)
45 {}
46
47 void run() {
48 scan();
49 E();
50 }
51
52private:
53 void E(){
54 T();
55 while (next=='+'||next=='-'){
56 cb(next);
57 scan();
58 T();
59 }
60 }
61
62 void T(){
63 S();
64 while (next=='*'||next=='/'){
65 cb(next);
66 scan();
67 S();
68 }
69 }
70
71 void S(){
72 if (isdigit(next)){
73 cb(next);
74 scan();
75 }
76 else if(next=='('){
77 cb(next);
78 scan();
79 E();
80 if (next==')'){
81 cb(next);
82 scan();
83 }else{
84 throw std::runtime_error("parsing failed");
85 }
86 }
87 else{
88 throw std::runtime_error("parsing failed");
89 }
90 }
91};
92
93int main() {
94 try {
95 std::istringstream is("1+1");
7c673cae 96 // execute parser in new execution context
b32b8144 97 ctx::continuation source;
7c673cae
FG
98 // user-code pulls parsed data from parser
99 // invert control flow
b32b8144
FG
100 char c;
101 bool done = false;
102 source=ctx::callcc(
103 [&is,&c,&done](ctx::continuation && sink){
104 // create parser with callback function
105 Parser p( is,
106 [&sink,&c](char c_){
107 // resume main execution context
108 c = c_;
109 sink=sink.resume();
110 });
111 // start recursive parsing
112 p.run();
113 // signal termination
114 done = true;
115 // resume main execution context
116 return std::move(sink);
117 });
118 while(!done){
119 printf("Parsed: %c\n",c);
120 source=source.resume();
7c673cae
FG
121 }
122 std::cout << "main: done" << std::endl;
123 return EXIT_SUCCESS;
b32b8144 124 } catch (std::exception const& e) {
7c673cae
FG
125 std::cerr << "exception: " << e.what() << std::endl;
126 }
127 return EXIT_FAILURE;
128}