docs: function TokenParser(tokens, filters, autoescape, line, filename) {
    this.out = [];
    this.state = [];
    this.filterApplyIdx = [];
    this._parsers = {};
    this.line = line;
    this.filename = filename;
    this.filters = filters;
    this.escape = autoescape;
  
    this.parse = function () {
      var self = this;
  
      if (self._parsers.start) {
        self._parsers.start.call(self);
      }
      utils.each(tokens, function (token, i) {
        var prevToken = tokens[i - 1];
        self.isLast = (i === tokens.length - 1);
        if (prevToken) {
          while (prevToken.type === _t.WHITESPACE) {
            i -= 1;
            prevToken = tokens[i - 1];
          }
        }
        self.prevToken = prevToken;
        self.parseToken(token);
      });
      if (self._parsers.end) {
        self._parsers.end.call(self);
      }
  
      if (self.escape) {
        self.filterApplyIdx = [0];
        if (typeof self.escape === 'string') {
          self.parseToken({ type: _t.FILTER, match: 'e' });
          self.parseToken({ type: _t.COMMA, match: ',' });
          self.parseToken({ type: _t.STRING, match: String(autoescape) });
          self.parseToken({ type: _t.PARENCLOSE, match: ')'});
        } else {
          self.parseToken({ type: _t.FILTEREMPTY, match: 'e' });
        }
      }
  
      return self.out;
    };
  }