Warning: session_start(): open(/var/lib/php/sessions/sess_8tur5isdc0hfoujqinpitc8dmh, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
// parser explainer
static class Explain {
static L primitiveClasses = litlist("quoted", "identifier", "any", "int");
O parseResult;
L tok;
L e;
new L subs;
static boolean debug;
*(O *parseResult, L *e) {
tok = (L) get(parseResult, "tok");
_makeSubExplains();
}
void _makeSubExplains() {
for (int i = 4; i < l(e); i++) {
L sub = cast get(e, i);
int t1 = (int) get(sub, 0);
int t2 = (int) get(sub, 1);
S className = getString(sub, 2);
L subE = sub;
if (!primitiveClasses.contains(className))
subE = (L) call(parseResult, "explainFull", t1, t2, className);
if (debug)
printF("Explaining * * * => *", t1, t2, className, subE);
if (subE == null)
subs.add(null);
else
subs.add(new Explain(parseResult, subE));
}
}
S className() {
ret getString(e, 2);
}
int fromToken() {
ret (int) get(e, 0);
}
int toToken() {
ret (int) get(e, 1);
}
// return tokens, padded with empty non-code tokens first and last
// to make actual CNC
L tok() {
ret concatLists(
litlist(""),
subList(tok, fromToken(), toToken()-1),
litlist(""));
}
S string() {
ret join(subList(tok, fromToken(), toToken()-1));
}
boolean containsToken(S t) {
ret main.containsToken(tok(), t);
}
void findAll(S className, L out) {
if (eq(className, className()))
out.add(string());
else // << this is new - don't recurse
for (Explain e : subs)
if (e != null)
e.findAll(className, out);
}
L findAll(S className) {
new L l;
findAll(className, l);
ret l;
}
// short for findFirst
Explain find(S className) {
ret findFirst(className);
}
Explain findFirst(S className) {
if (eq(className, className()))
ret this;
ret findFirstSub(className);
}
// find class, but exclude myself
Explain findFirstSub(S className) {
for (Explain e : subs)
if (e != null) {
Explain result = e.findFirst(className);
if (result != null) ret result;
}
ret null;
}
boolean has(S className) {
ret findFirst(className) != null;
}
boolean hasSub(S className) {
ret findFirstSub(className) != null;
}
void findAll2(S className, L out) {
if (eq(className, className()))
out.add(this);
for (Explain e : subs)
if (e != null)
e.findAll2(className, out);
}
L findAll2(S className) {
new L l;
findAll2(className, l);
ret l;
}
// short for pruneSubs
Explain prune(S className) {
ret pruneSubs(className);
}
// returns self after pruning
Explain pruneSubs(S className) {
for (int i = 0; i < l(subs); ) {
Explain e = sub(i);
if (e == null) ++i;
else if (eq(e.className(), className))
subs.remove(i);
else {
e.pruneSubs(className);
++i;
}
}
ret this;
}
Explain sub(int i) {
ret get(subs, i);
}
}