1 package acl2s.lib.parse;
2
3 import java.util.ArrayList;
4
5 import acl2s.lib.parse.obj.LispObject;
6
7
8 public abstract class Parser {
9 public static final char EOF = Character.MAX_VALUE;
10 protected final IParseContext pc;
11
12 public Parser(IParseContext pc) {
13 this.pc = pc;
14 }
15
16 public abstract Object save();
17 public abstract void restore(Object o);
18 public abstract char peek(int n);
19 public abstract void advance(int n);
20
21 public final void skip() { advance(1); }
22 public final char pop() { char c = peek(); skip(); return c; }
23 public final char peek() { return peek(0); }
24 public final char next() { skip(); return peek(); }
25
26 public final IParseContext getContext() { return pc; }
27 //public final void resetContext(ParseContext pc) { this.pc = pc; }
28
29 public boolean eof() { return peek(0) == EOF; }
30 public boolean matches(String s) {
31 for (int i = 0; i < s.length(); i++) {
32 if (s.charAt(i) != peek(i)) return false;
33 }
34 return true;
35 }
36 public String peekString(int n) {
37 StringBuilder b = new StringBuilder(n);
38 for (int i = 0; i < n; i++) {
39 char c = peek(i);
40 if (c != EOF) b.append(c);
41 }
42 return b.toString();
43 }
44
45 public void skip(boolean hspace, boolean vspace, boolean comments) throws ParseException {
46 char c;
47 for(;;) {
48 switch (peek()) {
49 case ' ':
50 case '\t':
51 if (hspace) {
52 advance(1);
53 continue;
54 } else {
55 return;
56 }
57 case '\f':
58 case '\r':
59 case '\n':
60 if (vspace) {
61 advance(1);
62 continue;
63 } else {
64 return;
65 }
66 case ';':
67 if (comments) {
68 do {
69 advance(1);
70 c = peek();
71 } while (c != '\n' && c != '\r' && c != EOF);
72 continue;
73 } else {
74 return;
75 }
76 case '#':
77 if (comments && matches("#|")) {
78 int depth = 1;
79 advance(2);
80 while (!eof()) {
81 if (matches("|#")) {
82 depth--;
83 advance(2);
84 if (depth == 0) break;
85 } else if (matches("#|")) {
86 depth++;
87 advance(2);
88 } else {
89 advance(1);
90 }
91 }
92 if (eof() && depth > 0)
93 throw new ParseException("#|-style comment unterminated. EOF reached.");
94 continue;
95 } else {
96 return; //some other # construct
97 }
98 default:
99 return; // not space or comment
100 }
101 }
102 }
103
104 public void skip(boolean hspace, boolean vspace) {
105 for (;;) {
106 switch (peek()) {
107 case ' ':
108 case '\t':
109 if (hspace) {
110 advance(1);
111 continue;
112 } else {
113 return;
114 }
115 case '\f':
116 case '\r':
117 case '\n':
118 if (vspace) {
119 advance(1);
120 continue;
121 }
122 default:
123 return;
124 }
125 }
126 }
127
128 public void skipSpace() {
129 skip(true,true);
130 }
131
132 public void skipSpaceAndComments() throws ParseException {
133 skip(true,true,true);
134 }
135
136 public void skipToTerminator() {
137 while (!SymOrNumFns.isTerminator(peek())) skip();
138 }
139
140 /***
141 * parseListOfSymbols
142 *
143 * @param output
144 * String to parse. Either "NIL" or list of symbols.
145 * @param result
146 * ArrayList to populate with results.
147 * @param offset
148 * Starting offset of text to replace
149 * @param replacementLength
150 * Length of text to replace.
151 */
152 public static int parseListOfSymbols(String output, ArrayList<String> results,
153 int i) {
154 if (output.trim().toLowerCase().startsWith("nil") || i < 0)
155 return -1;
156
157 ArrayList<String> sortList = new ArrayList<String>();
158 int start = 0;
159 String symb;
160 while (i < output.length()
161 && (Character.isWhitespace(output.charAt(i)) || output
162 .charAt(i) == '('))
163 ++i;
164 start = i;
165 while (i < output.length()) {
166 while (i < output.length()
167 && Character.isWhitespace(output.charAt(i)))
168 ++i;
169 if (i >= output.length())
170 break;
171 start = i;
172 // begin |this kind of symbol|
173 if (output.charAt(i) == '|') {
174 ++i;
175 while (i < output.length() && output.charAt(i) != '|')
176 ++i;
177 if (i >= output.length())
178 break;
179 ++i;
180 symb = output.substring(start, i);
181 if (!results.contains(symb))
182 sortList.add(symb); // vert bars have case sensitive
183 // symbols. Do not lowercase
184 } else if (output.charAt(i) == ')') { // done
185 break;
186 } else {
187 // regular symbol
188 while (i < output.length()
189 && !Character.isWhitespace(output.charAt(i))
190 && output.charAt(i) != ')')
191 ++i;
192 if (i >= output.length())
193 break;
|
Event do_not_call: |
"java.lang.String.toLowerCase()" implicitly uses the environment's default character set, which might lead to unexpected behavior. Consider using toLowerCase(Locale locale). |
194 symb = output.substring(start, i).toLowerCase();
195 if (!results.contains(symb))
196 sortList.add(symb);
197 }
198 }
199 java.util.Collections.sort(sortList);
200 results.addAll(sortList);
201 return i;
202 }
203
204 public static void main(String[] args) {
205 ParseContext pc = new ParseContext();
206 pc.loadBootstrapPackages();
207 if (args.length > 0) {
208 pc.defltPackage = args[0];
209 }
210 //pc.readBase = 16;
211 StreamParser sp = new StreamParser(pc, System.in);
212 do {
213 LispObject o = LispObject.robustParseFirst(sp);
214 System.out.println("-> " + o.toString(pc));
215 System.out.println("=> " + o.toString(null));
216 } while (!sp.ready() || !sp.eof());
217 }
218 }