-
Notifications
You must be signed in to change notification settings - Fork 33
/
15.39.cpp
70 lines (61 loc) · 1.38 KB
/
15.39.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
/*
* Exercise 15.39: Implement the Query and Query_base classes. Test your
* application by evaluating and printing a query such as the one in Figure
* 15.3 (p. 638).
*
* By Faisal Saadatmand
*/
/*
* This is the program to test the Query classes. Note that the buildQuery
* function is optional.
* */
#include <iostream>
#include <sstream>
#include <string>
#include "15.39.h"
// build queries using recursion
Query buildQuery(std::istringstream &iss, Query q)
{
static bool recurseOnce = false;
std::string op;
if (!(iss >> op))
return q;
if (op == "&") {
recurseOnce = true;
q = q & buildQuery(iss, q); // give precedence to &
recurseOnce = false;
return buildQuery(iss, q); // continue with normal recursion
}
if (op == "|")
return q | buildQuery(iss, q);
if (op[0] == '~')
q = ~Query(op.substr(1));
else
q = Query(op);
return (recurseOnce) ? q : buildQuery(iss, q);
}
int main(int argc, char **argv)
{
if (argc != 2) {
std::cerr << "Usage: " << *argv << " <filename>\n";
return -1;
}
std::ifstream text(*++argv);
if (!text) {
std::cerr << "Couldn't open " << *argv << '\n';
return -1;
}
TextQuery tq(text);
std::string input;
Query q;
while (true) {
if (!std::getline(std::cin, input) || input == "q")
break;
if (!input.empty()) {
std::istringstream line(input);
q = buildQuery(line, q);
std::cout << q.eval(tq);
}
}
return 0;
}