Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

165
LINES

< > BotCompany Repo | #1033967 // SimpleLeftToRightParser

JavaX fragment (include) [tags: use-pretranspiled]

Transpiled version (22797L) is out of date.

sclass SimpleLeftToRightParser > Meta {
  S text;
  LS tok;
  gettable TokPtr ptr;
  TokPtr mainLoopPtr;
  S currentToken;
  bool caseInsensitive;
  new L warnings;
  
  settable bool internIdentifiers;
  
  *() {}
  *(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() {
    S s = assertIdentifier(consume());
    if (internIdentifiers)
      s = intern(s);
    ret s;
  }
  
  S consumeIdentifierOpt() { ret isIdentifier(t()) ? consumeIdentifier() : null; }
  
  int consumeInteger() { ret parseInt(assertInteger(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 aka consume(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<Bool> 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;
  }
}

Author comment

Began life as a copy of #1033717

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1033967
Snippet name: SimpleLeftToRightParser
Eternal ID of this version: #1033967/68
Text MD5: cc399b5488851a5354d616454363b7ed
Author: stefan
Category: javax / parsing
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2024-07-14 10:55:35
Source code size: 4098 bytes / 165 lines
Pitched / IR pitched: No / No
Views / Downloads: 396 / 877
Version history: 67 change(s)
Referenced in: #1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674)