forked from beark/ftl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser_combinatorics.cpp
73 lines (53 loc) · 1.37 KB
/
parser_combinatorics.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <limits>
#include <vector>
#include <string>
#include <ftl/prelude.h>
#include "parser_combinator/parser_combinator.h"
// Workaround because stoi is not unary
int string2int(const std::string& str) {
return std::stoi(str);
}
template<typename T>
parser<T> option(parser<T> p, T&& t) {
using ftl::operator|;
return p | ftl::monad<parser<T>>::pure(std::forward<T>(t));
}
parser<int> parseNatural() {
using ftl::operator%;
return string2int % many1(oneOf("0123456789"));
}
parser<std::string> whitespace() {
return many1(oneOf(" \t\r\n"));
}
std::vector<int> cons(int n, std::vector<int> v) {
v.insert(v.begin(), n);
return v;
}
parser<std::vector<int>> parseList() {
using namespace ftl;
return curry(cons)
% (parseNatural())
* option(
whitespace() >> lazy(parseList),
std::vector<int>());
}
parser<std::vector<int>> parseLispList() {
using namespace ftl;
return parseChar('(') >> parseList() << parseChar(')');
}
int main(int, char**) {
using std::string;
auto parser = parseLispList();
auto res = run(parser, std::cin);
while(res.isTypeAt<0>()) {
std::cout << "expected " << ftl::get<0>(res)->message() << std::endl;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
res = run(parser, std::cin);
}
for(auto e : *ftl::get<1>(res)) {
std::cout << e << ", ";
}
std::cout << std::endl;
return 0;
}