-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparse.cpp
More file actions
157 lines (144 loc) · 3.32 KB
/
parse.cpp
File metadata and controls
157 lines (144 loc) · 3.32 KB
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include "parse.hpp"
#include <stdexcept>
using std::runtime_error;
static int getc_space(FILE *fp) {
int c;
do {
c = getc(fp);
} while (isspace(c));
return c;
}
static bool isvalidprop(int c) {
return islower(c) || isdigit(c) || c == '_';
}
static Formula parseSingle(FILE *fp, const Numbering &map) {
int c = getc_space(fp);
switch (c) {
case '(': {
Formula f = parse(fp, map);
c = getc_space(fp);
if (c != ')') {
throw runtime_error("parse: Unmatched parenthesis");
} else {
return f;
}
}
case '!':
return mkNegation(parseSingle(fp, map));
case 'X':
return mkNext(parseSingle(fp, map));
case 'G':
return mkAlways(parseSingle(fp, map));
case 'F':
return mkEvent(parseSingle(fp, map));
default:
if (!isvalidprop(c)) {
throw runtime_error("parse: Expected proposition, but got ...");
} else {
std::string s;
do {
s += c;
c = getc(fp);
} while (isvalidprop(c));
ungetc(c, fp);
auto ret = map.toId(s);
if (!ret) {
throw runtime_error("parse: Unknown atom proposition");
} else {
return mkAtom(ret.value());
}
}
}
}
static Formula parseConj(FILE *fp, const Numbering &map) {
Formula first = parseSingle(fp, map);
int c = getc_space(fp);
switch (c) {
case '/':
if (getc(fp) != '\\') {
throw runtime_error("parse: Expected ‘\\’ after ‘/’");
} else {
return mkConj(first, parseConj(fp, map));
}
default:
ungetc(c, fp);
return first;
}
}
static Formula parseDisj(FILE *fp, const Numbering &map) {
Formula first = parseConj(fp, map);
int c = getc_space(fp);
switch (c) {
case '\\':
if (getc(fp) != '/') {
throw runtime_error("parse: Expected ‘/’ after ‘\\’");
} else {
return mkDisj(first, parseDisj(fp, map));
}
default:
ungetc(c, fp);
return first;
}
}
static Formula parseUntil(FILE *fp, const Numbering &map) {
Formula first = parseDisj(fp, map);
int c = getc_space(fp);
switch (c) {
case 'U':
return mkUntil(first, parseUntil(fp, map));
default:
ungetc(c, fp);
return first;
}
}
static Formula parseImply(FILE *fp, const Numbering &map) {
Formula first = parseUntil(fp, map);
int c = getc_space(fp);
switch (c) {
case '-':
if (getc(fp) != '>') {
throw runtime_error("parse: Expected ‘>’ after ‘-’");
} else {
return mkImply(first, parseImply(fp, map));
}
default:
ungetc(c, fp);
return first;
}
}
Formula parse(FILE *fp, const Numbering &map) {
return parseImply(fp, map);
}
static void skipLowerEqual(char *&str) {
while (islower(*(++str)))
;
if (*str != '=') {
throw runtime_error("parse: Unknown command-line argument");
} else {
str++;
}
}
void parseCLIArgs(int argc, char *argv[],
FILE *&ts, FILE *&formula, FILE *&output) {
for (int i = 1; i < argc; i++) {
char *str = argv[i];
while (*(++str) == '-')
;
switch (*str) {
case 't':
skipLowerEqual(str);
ts = fopen(str, "r");
break;
case 'f':
skipLowerEqual(str);
formula = fopen(str, "r");
break;
case 'o':
skipLowerEqual(str);
output = fopen(str, "w");
break;
default:
throw runtime_error("parse: Unknown command-line argument");
}
}
}