-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRecompiler.java
481 lines (443 loc) · 15.6 KB
/
Recompiler.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
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
/**
* REcompiler
* ==========================
* Tamahau Brown - 1314934
* Troy Dean - 0222566
*/
class REcompiler
{
boolean starStart = false;
int num = 0;
String p [];
int j = 0;
int state = 0;
int checkQuotes = 0;
boolean isBracket = false;
boolean firstTime = true;
public static void main(String [] args)
{
REcompiler re = new REcompiler();
//Gets regexp pattern as an arg
String regexp = args[0];
//Creates an array with the size of the argument the user provided
re.p = new String[regexp.length()];
//Adds in the symbol at the specific position that it appeared in the argument to the array.
for(int i = 0; i < regexp.length(); i++)
{
re.p[i] = Character.toString(regexp.charAt(i));
}
//Runs throught the FSM to create the current and next states
re.Expression();
}
/*
Gets anything that is an expression in the FSM and constructs the necessary Factors and Terms needed.
*/
public void Expression()
{
//On the first iteration through the FSM it will create the starting point which will be represented with a '.' to mean an empty character
if(firstTime)
{
//Checks that there is more than one character in the FSM to search for special cases
if(j+1 < p.length)
{
//If a '*', '?' or '|' is the 2nd character it sets the first point that the FSM goes to, to that position
if(p[j+1].equals("*") || p[j+1].equals("?") || p[j+1].equals("|"))
{
set_State(-1, ".", j+2, j+2);
starStart = true;
}
//If no special cases are provided it just makes it go to the first literal or symbol in the FSM
else
{
set_State(-1, ".", j+1, j+1);
}
}
//IF the FSM is not big enough it is assumed there is only a literal in the machine so it points to that position
else
{
set_State(-1, ".", j+1, j+1);
}
firstTime = false;
}
//If there are still values in the array to be indexed it will progress through the FSM, otherwise it will finish and stop creating the FSM
if(num != -1)
{
//Cover E --> T
Term();
//IF after the terms it is not able to continue the expression due to ArrayOutOfBounds it will terminate immediately
if(j > p.length - 1)
{
System.out.println("EXIT");
return;
}
//If it is a new line it will reiterate through the FSM and create another Expression
if(!(p[j].equals("\n")))
{
//Covers E --> TE
Expression();
}
}
//Otherwise it is assumed to be at the end and terminates the FSM
else
{
System.out.println("Exiting Parser");
return;
}
}
/*
Any case that is not defined as an Expression or a Factor will be checked and created in here, this includes: *, ? [], ^[]
*/
public void Term()
{
//If it is outside of the array it terminates immediately
if(num == -1)
{
return;
}
//This is the closure case which makes the item go through the state zero or more times
if(p[j].equals("*"))
{
//Covers the * case
set_State(j, p[j], j, j+2);
j++;
return;
}
//The set or case, which checks each item to see if it is that value, if it is not then it goes to the next item to check if it is.
if(p[j].equals("["))
{
j++;
j = orSets(j);
return;
}
//Does the same as closure but only zero or one time
if(p[j].equals("?"))
{
//Sets it to the previous value and makes the next state of the ?
set_State(j, p[j], j, j+2);
j++;
return;
}
//To ensure an ArrayOutOfBoudnds Exception does not occur
if(j+1 < p.length)
{
//The Set of case to check that it is not the specific character, if it is, it skips out of the output
if(p[j].equals("^") && p[j+1].equals("["))
{
//If the second item was a star it increments correctly
if(starStart)
{
j++;
}
set_State(j, p[j], j+1, j+1);
//Jumping 2 to get the next literal
j += 2;
//Runs the or case to get all the literals
j = orSets(j);
return;
}
//The or case, to check which of the items it is and chooses which state to go to
if(p[j+1].equals("|") || p[j].equals("|"))
{
orStatement();
return;
}
//All other cases are dealt with by Factors
else
{
num = Factor();
}
}
//All other cases are dealt with by Factors
else
{
num = Factor();
}
}
/*
All remaining cases to be built, this includes (), literals and the escape character
*/
public int Factor()
{
if(j < p.length)
{
// ( Case
if(p[j].equals("(") || isBracket == true)
{
//If the last character was not a ( then don't make a new expression, instead make continue through the factors adding the new items until you reach the )
if(isBracket == false)
{
set_State(j, p[j], j+2, j+2);
//Gets the next character
j++;
isBracket = true;
Expression();
}
//Ends when it gets to the closing ()
else if(p[j].equals(")"))
{
set_State(j, p[j], j+2, j+2);
j++;
}
}
if(j < p.length)
{
//Escape character
if(p[j].equals("\\"))
{
System.out.println("ESCAPE");
return -1;
}
//Literal Case, which is any case that is not stated in the FSM before
else
{
//Checks if it is a valid length to have a next character, if it is not, it is assumed no special character cases are happening
if(j+1 < p.length)
{
//If the next value is a special case of a * or a ? it sets the state of the current item to the next value afterwards
if(p[j+1].equals("*") || p[j+1].equals("?"))
{
set_State(j, p[j], j+2, j+2);
}
//Otherwise proceeds as normal
else
{
//If the first character was a special case, it increments correctly
if(starStart)
{
set_State(j, p[j], j+2, j+2);
}
else
{
set_State(j, p[j], j+2, j+2);
}
}
}
//Otherwise proceeds as normal
else if(j < p.length)
{
//If the first character was a special case, it increments correctly
if(starStart)
{
set_State(j, p[j], j+2, j+2);
}
else
{
set_State(j, p[j], j+2, j+2);
}
}
}
}
}
//Goes to the next indexed item
j++;
return j;
}
/*
Deals with any item inside the ^[] case or the [] case
*/
public int orSets(int count)
{
//Sets the state of the opening bracket
set_State(j-1, p[j-1], j+1, j+1);
//Gets the closing bracket position
int closeBracket = count;
int x = 0;
String str = "";
//Checks that it is not the closing bracket of the set or if it is the first character it reads it as a literal
while(!p[closeBracket].equals("]") || x == 0)
{
closeBracket++;
x++;
}
//Resets the counter to allow us to reuse it for the items in the list
x = 0;
closeBracket++;
while(true)
{
//Counts for the case that the first character ] can be an object literal
if(!(p[count].equals("]")) || x == 0)
{
//Get next character
int next = count + 1;
set_State(count, p[count], next, closeBracket);
count++;
x++;
}
//If it is the end of the brackets, close it.
else
{
set_State(count, p[count], count+2, count+2);
count++;
break;
}
}
return count;
}
/*
Deals with anything in the | case and sets the states appropriately
*/
public void orStatement()
{
//DECLARE VARIABLES
int state1 = 0;
int state2 = 0;
int orState = j;
boolean setState2 = true;
//If it ran the case where the next character was the | it sets the increment so the states work correctly
if(p[j+1].equals("|"))
{
j++;
}
//Checks that these have no special symbols, if there is it gets the literal from the spot before
if(j-1 >= 0)
{
if(p[j-1].equals("*") || p[j-1].equals("?"))
{
state1 = j-1;
}
}
else
{
state1 = j;
}
//Sets the position or the | character
orState = j+1;
//Sets the next state to the symbol after the 'or'
state2 = j+1;
//Prevents ArrayOutOfBounds Exception
if(j+2 < p.length)
{
//Checks if there are special cases of or or paranthesis
if(p[j+2].equals("(") || p[j+2].equals("[") || p[j+2].equals("^"))
{
//Goes to the 2nd character it open that case
j+= 2;
setState2 = false;
}
//Checks for special cases such as: * or ?
else
{
//Prevents ArrayOutOfBounds Exception
if(j+3 < p.length)
{
//Checking for special cases and handling correctly
if(p[j+3].equals("*") || p[j+3].equals("?"))
{
j+= 4;
}
//If none of those cases exist it goes to the next literal
else
{
//Makes it go to the next thing after the or.
j+=3;
}
}
//If one will occur just increments correctly
else
{
j += 3;
}
}
}
//Other increments correctly
else
{
j+=2;
}
//Checks an ArrayOutOfBounds Excpetion won't occur for special cases
if(state1 - 1 >= 0)
{
//Checks that the current character isn't a special case, if it is, it ignores it
if(!p[state1].equals("*") && !p[state1].equals("?"))
{
//Sets the state for the literal
set_State(state1, p[state1], j+1, j+1);
}
}
//Otherwise proceeds as normal
else
{
if(state1-1 >= 0)
{
set_State(state1-1, p[state1-1], j+1, j+1);
}
else
{
set_State(state1, p[state1], j+1, j+1);
}
}
//Checks for special cases on the current state
if(p[state1].equals("*") || p[state1].equals("?"))
{
//Prevents ArrayOutOfBounds Exception
if(state2+1 < p.length)
{
//Checking for special cases
if(p[state2+1].equals("*"))
{
//Sets the state of the or operater
set_State(orState-1, "|", state1+1, state2+2);
}
else
{
//Sets the state of the or operater
set_State(orState-1, "|", state1+1, state2+1);
}
}
else
{
//Sets the state of the or operater
set_State(orState-1, "|", state1+1, state2+1);
}
}
//If no special case, proceeds as normal
else
{
//Checks if State 2 has a special case, and this is to prevent ArrayOutOfBounds Exception
if(state2+1 < p.length)
{
if(p[state2+1].equals("*") || p[state1].equals("?"))
{
set_State(orState-1, "|", state1+1, state2+2);
}
}
//Othweise proceeds as normal
else
{
//Sets the state of the or operater
set_State(orState-1, "|", state1+1, state2+1);
}
}
//If State 2 is to be written as not cause issues, it will go through this
if(setState2 == true)
{
//Prevents ArrayOutOfBounds Exception
if(state2 + 1 < p.length)
{
//Checking for special cases
if(p[state2+1].equals("*") || p[state2+1].equals("?"))
{
//Sets the state of the next operator
set_State(state2, p[state2], state2+2, state2+2);
}
}
}
j--;
return;
}
/*****************************************************/
/*****************************************************/
/* */
/* Non-general Methods */
/* */
/*****************************************************/
/*****************************************************/
/*
Creates the states of the FSM to make sure they are in the right current state, next state and branch correctly
*/
public void set_State(int state, String s, int firstState, int secondState)
{
state = state + 1;
System.out.println(state + " " + s + " " + firstState + " " + secondState);
}
}