1 package jfun.parsec; 2 3 import java.util.ArrayList ; 4 import java.util.List ; 5 6 class ParserInternals { 7 8 static boolean _most(final IntOrder ord, final Parser<?>[] ps, 9 final int ind, final ParseContext state, final Object ustate, 10 final Object 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 mret = state.getReturn(); 17 Object 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 ret, 145 final Object 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 static boolean isInfiniteLoop(final int at0, final int at1) { 159 return (at0 == at1); 160 164 } 165 166 static ParsecError errExpecting(final String msg, 167 final ParseContext state) { 168 return ParsecError.raiseExpecting(state.getIndex(), msg); 169 } 170 171 static boolean raiseUnexpected(final String msg, 172 final ParseContext state) { 173 state.setError(ParsecError.raiseUnexpected(state.getIndex(), msg)); 174 return false; 175 } 176 177 static boolean raiseRaw(final String msg, final ParseContext state) { 178 state.setError(ParsecError.raiseRaw(state.getIndex(), msg)); 179 return false; 180 } 181 182 static ParsecError newException(final Object e, 183 final ParseContext state) { 184 return ParsecError.throwException(state.getIndex(), e); 185 } 186 187 static boolean returnValue(final Object v, final ParseContext state) { 188 state.setError(ParsecError.noError()); 189 state.setReturn(v); 190 return true; 191 } 192 193 194 195 static boolean setErrorExpecting(final String 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 static String 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 <T> l, 218 final ArrayFactory<E> af) { 219 final E[] arr = af.createArray(l.size()); 220 try { 221 l.toArray(arr); 222 } catch (ArrayStoreException e) { 223 final Class etype = arr.getClass().getComponentType(); 224 for (int i = 0; i < l.size(); i++) { 225 final Object elem = l.get(i); 226 if (elem != null && !etype.isInstance(elem)) { 227 final String msg = "cannot cast the #" + i + " element: <" + elem 228 + "> of type " + elem.getClass().getName() + " to " 229 + etype.getName(); 230 throw new ClassCastException (msg); 231 } 232 } 233 throw e; 234 } 235 return arr; 236 } 237 238 static Tok[] toTokens(Object obj) { 239 if (obj instanceof Tok[]) { 240 return (Tok[]) obj; 241 } else if (obj instanceof List ) { 242 final List <?> l = (List ) 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 |