This repository has been archived by the owner on Nov 26, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
/
ParserDriver.java
272 lines (236 loc) · 8.74 KB
/
ParserDriver.java
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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
import java.io.*;
import java.util.LinkedList;
/**
* Class that runs the parsing segment of the project.
*
* @author Logan Blyth, James McCarty, & Robert Rayborn
*
*/
public class ParserDriver
{
private static boolean verbose;
/**
* If there are zero, three, or four input arguments then we are running a full parse table build and file parse
* If there are zero inputs then
* we use the default scanner file "scan.txt"
* we use the default grammar file "grammar.txt"
* we use save the parse table to the default "parseTable.csv"
* Else are three or four inputs then
* the first argument is the scanner file location
* the second argument is the grammar file location
* the third argument is the file location to save the parse table at (make sure to end in .csv if you want to read it in a spreadsheet editor)
* If there are three inputs then
* Verbose mode is off
* Elseif the fourth input is -v then
* Verbose mode is on (verbose mode is off with any other input)
* Elseif there are one or two input arguments then we are just building the parse table
* If there are one inputs then
* the input is the grammar file location
* Else there are two inputs then
* the first argument is the grammar file location
* the second argument is the file location to save the parse table at (make sure to end in .csv if you want to read it in a spreadsheet editor)
* Else the program will throw an error
*
* @param args
*/
public static void main(String[] args)
{
String scannerFile, grammarFile, parseTableFile;
ParserGenerator parserGenerator;
LinkedList<String> input;
// Assign file names
if(args.length == 0) // no parameters given
{
// Set default paramenters
scannerFile = "scan.txt";
grammarFile = "grammar.txt";
parseTableFile = "parseTable.csv";
verbose = false;
}
else if(args.length == 3) // all parameters given except for verbose
{
// Assign any input parameter
scannerFile = args[0];
grammarFile = args[1];
parseTableFile = args[2];
verbose = false;
}
else if( (args.length == 4) && (args[3].equalsIgnoreCase("-v")) ) // all parameters given, verbose on
{
// Assign any input parameter
scannerFile = args[0];
grammarFile = args[1];
parseTableFile = args[2];
verbose = true;
}
else if(args.length == 2) // parse table only
{
// Assign any input parameter
grammarFile = args[0];
parseTableFile = args[1];
scannerFile = null;
verbose = false;
}
else if(args.length == 1) // parse table only
{
// Assign any input parameter
grammarFile = args[0];
parseTableFile = "parseTable.csv";
scannerFile = null;
verbose = false;
}
else
{
throw new RuntimeException("\n Wrong input parameters to ParseDriver.java. Input parameters are: \n"
+" Scanner File Name \n"
+" Grammar File Name \n"
+" Parse Table File Name (to save to)");
}
//======================================================================
//=======STEP 1: LOADING DATA FOR PARSE TABLE BUILD=====================
//======================================================================
try
{
String line;
String lineTokens[], terminalTokens[], nonterminalTokens[], startToken;
// Set up file input
FileInputStream fstream = new FileInputStream(grammarFile);
DataInputStream dstream = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(dstream));
// Read "Tokens" line
line = br.readLine();
line = removeMultipleSpaces(line);
lineTokens = line.trim().split(" ");
if (!lineTokens[0].equals("%Tokens"))
throw new RuntimeException("\n Grammar file malformed.");
terminalTokens = new String[lineTokens.length-1];
for(int i=0; i<terminalTokens.length; i++)
terminalTokens[i] = lineTokens[i+1].trim();
// Read "Non-terminal" line
line = br.readLine();
line = removeMultipleSpaces(line);
lineTokens = line.trim().split(" ");
if (!lineTokens[0].equals("%Non-terminals"))
throw new RuntimeException("\n Grammar file malformed.");
nonterminalTokens = new String[lineTokens.length-1];
for(int i=0; i<nonterminalTokens.length; i++)
nonterminalTokens[i] = lineTokens[i+1].trim();
// Start line
line = br.readLine();
line = removeMultipleSpaces(line);
lineTokens = line.trim().split(" ");
if (!lineTokens[0].equals("%Start"))
throw new RuntimeException("\n Grammar file malformed.");
startToken = lineTokens[1].trim();
// Create parse table builder
parserGenerator = new ParserGenerator(terminalTokens,nonterminalTokens,startToken);
// Rule line
line = br.readLine();
line = removeMultipleSpaces(line);
lineTokens = line.trim().split(" ");
if (!lineTokens[0].equals("%Rules"))
throw new RuntimeException("\n Grammar file malformed.");
String rule;
String productionRules[];
String splitString[];
// Set up rules
while( (line = br.readLine()) != null )
{
line = removeMultipleSpaces(line);
splitString = line.split(":"); // "RULE : A B | C D " -> {"RULE " , " A B | C D "}
rule = splitString[0].trim(); // "RULE " -> "RULE"
productionRules = splitString[1].split("\\|"); // " A B | C D " -> {" A B " , " C D "}
for(String productionRule : productionRules)
parserGenerator.addGrammarRule(rule, productionRule.trim().split(" "));
}
dstream.close();
}
catch(IOException e)
{
throw new RuntimeException("\n Grammar file read failed.");
}
catch(ArrayIndexOutOfBoundsException e)
{
throw new RuntimeException("\n Grammar file malformed.");
}
//======================================================================
//=======STEP 2: BUILD THE PARSE TABLE==================================
//======================================================================
parserGenerator.buildParseTable();
try
{
parserGenerator.saveParseTable(parseTableFile);
}
catch(IOException e)
{
throw new RuntimeException("\n Save parse table failed.");
}
//======================================================================
//=======RETURN IF ONLY BUILDING PARSE TABLE, NOT PARSING===============
//======================================================================
if(scannerFile==null)
{
System.out.println("Parse table saved at: "+parseTableFile);
return;
}
//======================================================================
//=======STEP 3: LOAD THE INPUT DATA====================================
//======================================================================
try
{
String line;
String lineTokens[];
//========SET UP INPUT=============================================
// Set up data input
FileInputStream fstream = new FileInputStream(scannerFile);
DataInputStream dstream = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(dstream));
// Set up input list
input = new LinkedList<String>();
// Read line
line = br.readLine();
line = removeMultipleSpaces(line);
if(line.contains("$"))
throw new RuntimeException("\n The symbol $ found in the scanner output. $ is a reserved symbol.");
if( br.readLine() != null ) // File should only be one line long
throw new RuntimeException("\n Scanner file greater than one line long.");
// end file read
dstream.close();
lineTokens = line.split(" ");
for(String token : lineTokens)
{
input.addLast(token);
}
// Make sure input ends with $
input.addLast("$");
}
catch(IOException e)
{
throw new RuntimeException("\n Scanner file read failed.");
}
//======================================================================
//=======STEP 4: Parse the input========================================
//======================================================================
Parser.parse(input, parserGenerator.getParseTable());
System.out.println("Parse completed successfully! No errors detected.");
}
/**
* Removes repeated spaces from a string (i.e. if string contains " " it will be shortened to " "
* @param string - string to have multiple spaces removed
* @return string without multiple spaces
*/
private static String removeMultipleSpaces(String string)
{
String oldString;
do
{
oldString = string;
string = string.replace(" ", " ");
}while( !string.equals(oldString) );
return string;
}
public static boolean verboseOn()
{
return verbose;
}
}