-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser_main.cpp
220 lines (183 loc) · 7.51 KB
/
parser_main.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
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#include <boost/filesystem.hpp>
#include <iostream>
#include <fstream>
#include "options/OptionPrinter.hpp"
#include "machine.h"
#include "parsetable.h"
#include "leftmost_derivation.h"
#include "ll1_parser.h"
namespace {
const size_t ERROR_IN_COMMAND_LINE = 1;
const size_t SUCCESS = 0;
const size_t ERROR_UNHANDLED_EXCEPTION = 2;
} // namespace
namespace po = boost::program_options;
po::variables_map vm;
std::string appName;
std::string app_description;
std::string src;
std::ifstream ttab_ifs;
std::string ptab_ifs; // TODO: Change serialization to take input stream
std::ifstream src_ifs;
std::ofstream lmost_derivation_ofs;
int retval = 0;
int stack_parse(std::istream &ttab_in, std::string ptab_in, std::istream &src_in, std::ostream &lmost_derivation_out);
void handle_options();
void handle_transition();
void handle_parse_table();
void handle_output();
void handle_src();
//-----------------------------------------------------------------------------
int main(int argc, char **argv) {
try {
appName = boost::filesystem::basename(argv[0]);
app_description = "A simple java Compiler";
/** Define and parse the program options
*/
po::options_description desc("Options");
desc.add_options()
("help,h", "Print (on the standard output) a description of the command-line options understood"
" by Kompiler.")
("verbose,v", "Verbosely list files processed.")
("transition,t", po::value<std::string>(), "Input transition-table file to read from.\n"
"\n"
"\t \tIf -t is not specified, the default"
" is to read from in.ttab file.")
("parse-table,p", po::value<std::string>(), "Input parse-table file to read from.\n"
"\n"
"\t \tIf -p is not specified, the default"
" is to read from in.ptab file.")
("src", po::value<std::string>(&src)->required(), "Input src file to be compiled.")
("output,o", po::value<std::string>(),
"Place output in specified file. This applies to whatever sort of output\n"
"\t \tis being produced.\n"
"\n"
"\t \tIf -o is not specified, the default is to print on the standard output.")
("version", "Display the version number and copyrights of the invoked Kompiler.");
po::positional_options_description positionalOptions;
positionalOptions.add("src", 1);
// positionalOptions.add("like", 1);
try {
po::store(po::command_line_parser(argc, argv).options(desc)
.positional(positionalOptions).run(),
vm);
/** --help option
*/
if (vm.count("help")) {
rad::OptionPrinter::printStandardAppDesc(appName,
app_description,
std::cout,
desc,
&positionalOptions);
return SUCCESS;
}
po::notify(vm); // throws on error, so do after help in case
// there are any problems
}
catch (boost::program_options::required_option &e) {
rad::OptionPrinter::formatRequiredOptionError(e);
std::cerr << "ERROR: " << e.what() << std::endl;
// rad::OptionPrinter::printStandardAppDesc(appName,
// app_description,
// std::cout,
// desc,
// &positionalOptions);
std::cerr << "Try '" << appName << " --help' for more information.";
return ERROR_IN_COMMAND_LINE;
}
catch (boost::program_options::error &e) {
std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
// rad::OptionPrinter::printStandardAppDesc(appName,
// app_description,
// std::cout,
// desc,
// &positionalOptions);
std::cerr << "Try '" << appName << " --help' for more information.";
return ERROR_IN_COMMAND_LINE;
}
// can do this without fear because it is required to be present
// std::cout << "Necessary = "
// << vm["necessary"].as<std::string>() << std::endl;
if (vm.count("verbose")) {
std::cout << "VERBOSE PRINTING" << std::endl;
}
handle_options();
if (lmost_derivation_ofs.is_open())
stack_parse(ttab_ifs, ptab_ifs, src_ifs, lmost_derivation_ofs);
else
stack_parse(ttab_ifs, ptab_ifs, src_ifs, std::cout);
}
catch (std::exception &e) {
std::cerr << "Unhandled Exception reached the top of main: "
<< e.what() << ", application will now exit" << std::endl;
return ERROR_UNHANDLED_EXCEPTION;
}
return SUCCESS;
} // main
void handle_options() {
handle_transition();
handle_parse_table();
handle_output();
handle_src();
}
void handle_transition() {
std::string ttab_fname = "in.ttab";
if (vm.count("transition")) {
ttab_fname = vm["transition"].as<std::string>();
}
ttab_ifs.open(ttab_fname);
if (!ttab_ifs) {
std::cerr << "Unable to read file \"" + ttab_fname + "\"" << std::endl;
}
}
void handle_parse_table() {
if (vm.count("parse-table")) {
ptab_ifs = (vm["parse-table"].as<std::string>());
} else {
ptab_ifs = ("in.ptab");
}
}
void handle_output() {
if (vm.count("output")) {
lmost_derivation_ofs.open(vm["output"].as<std::string>());
if (!lmost_derivation_ofs) {
std::cerr << "Unable to read file \"" + vm["output"].as<std::string>() + "\"" << std::endl;
}
}
}
void handle_src() {
src_ifs.open(src);
if (!src_ifs) {
std::cerr << "Unable to read file \"" + src + "\"" << std::endl;
}
}
void read_ttab(std::istream &in, machine &m) {
in >> m;
}
int stack_parse(std::istream &ttab_in, std::string ptab_in, std::istream &src_in, std::ostream &lmost_derivation_out) {
try {
if (!ttab_in | !src_in | !lmost_derivation_out) {
return -1;
}
machine m("");
read_ttab(ttab_in, m);
parsetable ptab;
ptab.deserialize(ptab_in);
leftmost_derivation derivation = parse::parse_ll1(ptab, m, src_in);
if (vm.count("verbose")) {
std::cout << derivation << std::endl;
}
if(vm.count("output")) {
lmost_derivation_out << derivation << std::endl;
}
return 0;
} catch (const std::exception &ex) {
std::cout << ex.what() << std::endl;
return -1;
} catch (const std::string &ex) {
std::cout << ex << std::endl;
return -1;
} catch (...) {
return -1;
}
}