Warning: session_start(): open(/var/lib/php/sessions/sess_lr5lgade3rs8v3ude2q8k7ncbe, 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
sclass SimpleLeftToRightParser > Meta {
S text;
LS tok;
gettable TokPtr ptr;
TokPtr mainLoopPtr;
S currentToken;
bool caseInsensitive;
new L warnings;
*() {}
*(S *text) {}
*(LS *tok) {}
swappable LS tokenize(S text) { ret javaTok(text); }
S t aka token() { ret currentToken; }
S token(int i) { ret get(tok, ptr.idx()+i*2); }
S next aka consume aka tpp() { var t = t(); next(1); ret t; }
S lastSpace aka prevSpace() { ret get(tok, ptr.idx()-1); }
S nextSpace() { ret get(tok, ptr.idx()+1); }
S space(int i) { ret get(tok, ptr.idx()+i*2+1); }
void unconsume() { next(-1); }
bool tokEq aka eqTok(S a, S b) { ret eqOrEqic(caseInsensitive, a, b); }
bool tokEqOneOf(S a, S... l) { ret any(l, b -> tokEq(a, b)); }
bool is(int i, S t) { ret tokEq(token(i), t); }
bool is(S t) { ret tokEq(currentToken, t); }
bool was(S t) { ret tokEq(token(-1), t); }
bool isOneOf(S... tokens) { ret tokEqOneOf(currentToken, tokens); }
S[] consumeArray(int n) {
S[] array = new[n];
for i to n: array[i] = consume();
ret array;
}
meta-for isInteger also as isIdentifier {
bool isInteger() { ret isInteger(t()); }
bool isInteger(S s) { ret main isInteger(s); }
}
S consumeIdentifier() { ret assertIdentifier(consume()); }
bool consumeOpt(S token) {
if (!is(token)) false;
consume();
true;
}
void consume(S token) {
if (!is(token))
fail("Expected " + quote(token) + ", got " + describeToken(token());
consume();
}
S describeToken(S token) {
ret token == null ? "EOF" : quote(token);
}
S consumeOneOf(S... tokens) {
if (!isOneOf(tokens))
fail("Expected one of " + asList(tokens));
ret consume();
}
void ptr(TokPtr ptr) { this.ptr = ptr; fetch(); }
int idx aka tokIdx() { ret ptr.idx(); }
int lTok() { ret l(tok); }
int nRemainingTokens() { ret (lTok()-idx())/2; }
bool atEnd aka endOfText() { ret ptr.atEnd(); }
void fetch { currentToken = ptr!; }
bool lineBreak() { ret containsLineBreak(get(tok, ptr.idx()-1)); }
bool atEndOrLineBreak() { ret atEnd() || lineBreak(); }
void init {
tok if null = tokenize(text);
if (ptr == null) ptr(ListAndIndex(tok, 1));
}
bool mainLoop() {
init();
if (atEnd()) false;
if (eq(mainLoopPtr, ptr))
fail("main loop didn't advance (current token: " + quote(token()) + ")");
mainLoopPtr = ptr;
true;
}
class AssureAdvance {
TokPtr cur;
{ init(); }
bool get() {
if (atEnd()) false;
if (eq(cur, ptr))
fail("Parse loop didn't advance (current token: " + quote(token()) + ")");
cur = ptr;
true;
}
}
void unknownToken {
warn("Unknown token: " + t());
}
void warn(S msg) {
warnings.add(print(msg));
}
// can also move backwards for negative n
void next aka skip(int n) {
ptr(min(lTok(), ptr.idx()+n*2));
}
// if i points to an N token, it is incremented
void ptr(int i) {
ptr(ListAndIndex(tok, min(i | 1, l(tok))));
}
LineAndColumn lineAndColumn() {
ret tokenToLineAndColumn(ptr);
}
LineAndColumn lineAndColumn(int idx) {
ret tokenToLineAndColumn(ptr.plus(idx*2));
}
S consumeUntilSpaceOr(IF0 pred) {
int i = idx();
do next(); while (!atEnd() && empty(lastSpace()) && !pred!);
ret joinSubList(tok, i, idx()-1);
}
void setText(S text) {
this.text = text;
tok = null;
ptr = null;
}
int relativeIndexOf(S token) {
int n = nRemainingTokens();
for i to n:
if (eqTok(token(i), token))
ret i;
ret -1;
}
}