KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jfun > parsec > ParserInternals


1 package jfun.parsec;
2
3 import java.util.ArrayList JavaDoc;
4 import java.util.List JavaDoc;
5
6 class ParserInternals {
7
8   static boolean _most(final IntOrder ord, final Parser<?>[] ps,
9       final int ind, final ParseContext state, final Object JavaDoc ustate,
10       final Object JavaDoc ret, final int step, final int at,
11       final AbstractParsecError err) {
12     if (ind >= ps.length)
13       return true;
14     int most = state.getAt();
15     int mstep = state.getStep();
16     Object JavaDoc mret = state.getReturn();
17     Object JavaDoc mustate = state.getUserState();
18     AbstractParsecError merr = state.getError();
19     for (int i = ind; i < ps.length; i++) {
20       state.set(step, at, ret, ustate, err);
21       final boolean ok = ps[i].parse(state);
22       if (state.hasException())
23         return false;
24       if (ok) {
25         final int at2 = state.getAt();
26         if (ord.compare(at2, most)) {
27           most = at2;
28           mstep = state.getStep();
29           mret = state.getReturn();
30           mustate = state.getUserState();
31           merr = state.getError();
32         }
33       }
34     }
35     state.set(mstep, most, mret, mustate, merr);
36     return true;
37   }
38
39   static boolean run_repeat(final int n, final Parser<?> p,
40       final ParseContext ctxt) {
41     for (int i = 0; i < n; i++) {
42       if (!p.parse(ctxt))
43         return false;
44     }
45     return true;
46   }
47
48   static boolean run_many(final Parser<?> p, final ParseContext ctxt) {
49     int at = ctxt.getAt();
50     for (;;) {
51       if (p.parse(ctxt)) {
52         int at2 = ctxt.getAt();
53         if (ParserInternals.isInfiniteLoop(at, at2)) {
54           return true;
55         }
56         at = at2;
57         continue;
58       } else if (ctxt.hasException())
59         return false;
60       else if (ctxt.getAt() - at >= 1)
61         return false;
62       else
63         return true;
64     }
65   }
66
67   static boolean run_some(final int max, final Parser<?> p,
68       final ParseContext ctxt) {
69     for (int i = 0; i < max; i++) {
70       final int at = ctxt.getAt();
71       if (p.parse(ctxt))
72         continue;
73       else if (ctxt.hasException())
74         return false;
75       else if (ctxt.getAt() - at >= 1)
76         return false;
77       else
78         return true;
79     }
80     return true;
81   }
82
83   static <A, To> boolean accm_repeat(
84       final Accumulator<? super A, To> acc, final int n, final Parser<A> p,
85       final ParseContext ctxt) {
86     for (int i = 0; i < n; i++) {
87       if (p.parse(ctxt)) {
88         acc.accumulate(p.getReturn(ctxt));
89         continue;
90       } else if (ctxt.hasException()) {
91         ctxt.setReturn(acc.getResult());
92         return false;
93       } else
94         return false;
95     }
96     return true;
97   }
98
99   static <A, To> boolean accm_some(
100       final Accumulator<? super A, To> acc, final int max, final Parser<A> p,
101       final ParseContext ctxt) {
102     for (int i = 0; i < max; i++) {
103       final int at = ctxt.getAt();
104       if (p.parse(ctxt)) {
105         acc.accumulate(p.getReturn(ctxt));
106         continue;
107       } else if (ctxt.hasException()) {
108         ctxt.setReturn(acc.getResult());
109         return false;
110       } else if (ctxt.getAt() - at >= 1) {
111         return false;
112       } else {
113         break;
114       }
115     }
116     return true;
117   }
118
119   static <A, To> boolean accm_many(
120       final Accumulator<? super A, To> acc, final Parser<A> p,
121       final ParseContext ctxt) {
122     int at = ctxt.getAt();
123     for (;;) {
124       if (p.parse(ctxt)) {
125         int at2 = ctxt.getAt();
126         if (ParserInternals.isInfiniteLoop(at, at2)) {
127           break;
128         }
129         at = at2;
130         acc.accumulate(p.getReturn(ctxt));
131         continue;
132       } else if (ctxt.hasException()) {
133         ctxt.setReturn(acc.getResult());
134         return false;
135       } else if (ctxt.getAt() - at >= 1)
136         return false;
137       else
138         break;
139     }
140     return true;
141   }
142
143   static boolean recover(final int look_ahead, final Parser p,
144       final ParseContext state, final int step, final int at, final Object JavaDoc ret,
145       final Object JavaDoc ustate, final AbstractParsecError error) {
146     if (state.getAt() != at && state.getStep() - step >= look_ahead)
147       return false;
148     if (state.hasException())
149       return false;
150     state.set(step, at, ret, ustate, error);
151     if (p.parse(state))
152       return true;
153     state.setError(AbstractParsecError.mergeError(error, state.getError()));
154     return false;
155   }
156
157   // change the infinite loop handling. don't fail. just stop looping.
158
static boolean isInfiniteLoop(final int at0, final int at1) {
159     return (at0 == at1);
160     /*
161      * if(at0 == at1){ throw new ParserException("parser accepts an empty
162      * input", null, "parsec", null); }
163      */

164   }
165
166   static ParsecError errExpecting(final String JavaDoc msg,
167       final ParseContext state) {
168     return ParsecError.raiseExpecting(state.getIndex(), msg);
169   }
170
171   static boolean raiseUnexpected(final String JavaDoc msg,
172       final ParseContext state) {
173     state.setError(ParsecError.raiseUnexpected(state.getIndex(), msg));
174     return false;
175   }
176
177   static boolean raiseRaw(final String JavaDoc msg, final ParseContext state) {
178     state.setError(ParsecError.raiseRaw(state.getIndex(), msg));
179     return false;
180   }
181
182   static ParsecError newException(final Object JavaDoc e,
183       final ParseContext state) {
184     return ParsecError.throwException(state.getIndex(), e);
185   }
186
187   static boolean returnValue(final Object JavaDoc v, final ParseContext state) {
188     state.setError(ParsecError.noError());
189     state.setReturn(v);
190     return true;
191   }
192
193   /** ****************** derived combinators ******************* */
194   
195   static boolean setErrorExpecting(final String JavaDoc s, final ParseContext state) {
196     final AbstractParsecError err = state.getError();
197     if (err == null) {
198       state.setError(errExpecting(s, state));
199     } else
200       state.setError(err.setExpecting(s));
201     return false;
202   }
203
204   // performance of this method is insignificant.
205
static String JavaDoc toErrorStr(final ParseContext state) {
206     final AbstractParsecError aerr = state.getError();
207     if (aerr == null) {
208       return "";
209     }
210     final ParsecError err = aerr.render();
211     if (err.getException() != null) {
212       return ("User exception: " + err.getException().toString());
213     } else
214       return "";
215   }
216
217   static <E, T extends E> E[] getArrayResult(final ArrayList JavaDoc<T> l,
218       final ArrayFactory<E> af) {
219     final E[] arr = af.createArray(l.size());
220     try {
221       l.toArray(arr);
222     } catch (ArrayStoreException JavaDoc e) {
223       final Class JavaDoc etype = arr.getClass().getComponentType();
224       for (int i = 0; i < l.size(); i++) {
225         final Object JavaDoc elem = l.get(i);
226         if (elem != null && !etype.isInstance(elem)) {
227           final String JavaDoc msg = "cannot cast the #" + i + " element: <" + elem
228               + "> of type " + elem.getClass().getName() + " to "
229               + etype.getName();
230           throw new ClassCastException JavaDoc(msg);
231         }
232       }
233       throw e;
234     }
235     return arr;
236   }
237
238   static Tok[] toTokens(Object JavaDoc obj) {
239     if (obj instanceof Tok[]) {
240       return (Tok[]) obj;
241     } else if (obj instanceof List JavaDoc) {
242       final List JavaDoc<?> l = (List JavaDoc) obj;
243       final Tok[] arr = new Tok[l.size()];
244       l.toArray(arr);
245       return arr;
246     } else
247       throw new IllegalParserStateException(
248           "an array of Tok objects expected for token level parsing.");
249   }
250
251   static boolean cont(final ParseContext ctxt, final ParseContext s0,
252       final Parser<?> p) {
253     ctxt.setError(null);
254     if (!p.parse(s0)) {
255       ctxt.set(ctxt.getStep(), s0.getIndex(), null, s0.getUserState(), s0
256           .getError());
257       return false;
258     } else {
259       ctxt.set(ctxt.getStep() + s0.getStep(), ctxt.getAt(), s0.getReturn(), s0
260           .getUserState(), s0.getError());
261       return true;
262     }
263   }
264
265   static <R> R runParser(final ParseContext ctxt, final Parser<R> p,
266       final PositionMap pmap) {
267     if (!ParserInternals.parseIt(ctxt, p, pmap)) {
268       final AbstractParsecError err = ctxt.getError();
269       final int ind = err != null ? err.getIndex() : -1;
270       throw new ParserException(toErrorStr(ctxt), (err == null ? null : err
271           .render()), ctxt.getModuleName(), pmap.getPos(ind >= 0 ? ind : ctxt
272           .getIndex()));
273     }
274     return p.getReturn(ctxt);
275   }
276
277   static boolean parseIt(final ParseContext ctxt, final Parser<?> p,
278       final PositionMap pmap) {
279     try {
280       return p.parse(ctxt);
281     } catch (UserException e) {
282       final int ind = e.getInd();
283       throw new ParserException(e.getMessage(), null, ctxt.getModuleName(),
284           pmap.getPos(ind >= 0 ? ind : ctxt.getIndex()));
285     }
286   }
287
288 }
289
Popular Tags