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
|
package com.modulus.dataread.expressions.impl;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
import com.modulus.common.TwoTypeBean;
import com.modulus.dataread.expressions.LineNumberException;
import com.modulus.dataread.expressions.StatementFormatter;
import com.modulus.dataread.expressions.StatementTreeParser;
import com.modulus.dataread.expressions.ParseRules;
import com.modulus.dataread.expressions.Statement;
import com.modulus.dataread.expressions.StatementFactory;
/**
* This simple expression parser is meant not to do anything fancy
* all it does is break up the file into a tree based on the folders
* in the file.
*
* @author jrahm
*
*/
public class SimpleStatementTreeParser implements StatementTreeParser{
/*
* used by methods to keep track of
* the number of lines
*/
private int line = 0;
/*
* The rules to parse by
*/
private ParseRules rules;
/**
* Creates a new <code>SimpleExpressionParser</code> based
* off of the rules that was given to it.
*
* @param rules the rules to parse by
*/
public SimpleStatementTreeParser(ParseRules rules){
this.rules = rules;
}
@Override
public <T extends Statement> Statement parseStatements(StatementFactory<T> factory) {
// set the line counter to 1
this.line = 0;
return recurParseStatement(factory, 0).getObject1();
}
/*
* Setup a recursive parser to
* return a tree of statements
*/
private <T extends Statement> TwoTypeBean<T, Integer> recurParseStatement(StatementFactory<T> factory, int off){
try{
// System.out.println(" parseStatements");
final String code = rules.getCode();
// statement which will be returned in the end,
// this statement is the parent of all the other
// statements
T ret = factory.generateStatement(null);
int i = off;
int n = 0;
// start an iteration through the
// string
for( ;i < code.length(); n++, i += rules.read(i) ){
// if the next character is a new line character,
// the increment the line counter
// System.out.println( i );
if(code.charAt(i) == '\n'){
line ++;
// that is all a new line does;
continue;
}
// check to see if the rules say that here a statement
// is to be terminated
if( rules.statementTerminated(i) ){
// if so, then it is time to manifest a new statement
// header is equal to the substring of the code from
// off to i
String header = code.substring(off, i);
// create a new child from the type provided
T child = factory.generateStatement(null);
// set the header
child.setHeader( header );
// set the line number to what it should be
child.setLineNumber( this.line );
// we are done with creating this beam, so it is time to
// return it
return new TwoTypeBean<T, Integer>(child, i);
}
// if the rules say that at this point,
// a folder is opened, then it is time to
// use recursion to implement a tree.
else if ( rules.openFolder(i) ){
// the header is from off to when the
// folder is being closed
String header = code.substring(off, i);
// set the header
ret.setHeader(header);
// set the line number
ret.setLineNumber(line);
// it is time to increment i by the
// amount the rules say to.
i += rules.read(i);
// while the folder is not closed
while( !rules.closeFolder(i) ){
// read the next statement
TwoTypeBean<T, Integer> bean = recurParseStatement(factory, i);
// the second object is the offset
//that the previous call terminated with
i = bean.getObject2();
// add this child to the main bean
ret.addChild(bean.getObject1());
// increment the incrementer by how
// much the rules say to
i += rules.read(i);
while(code.charAt(i) == '\n'){
line ++;
i++;
}
}
// When finished reading this file, it is time
// to return the main bean.
return new TwoTypeBean<T, Integer>(ret, i);
}
}
// System.out.println(" /parseStatements");
return new TwoTypeBean<T, Integer>(ret, i);
} catch( Exception e ){
throw new LineNumberException("Sytax error", e, line);
}
}
}
|