[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/codeschool/sqlite-parser/master/src/parser.js [Back]  [Original]

// Generated by PEG.js 0.10.0.
//
// http://pegjs.org/

"use strict";

function peg$subclass(child, parent) {
  function ctor() { this.constructor = child; }
  ctor.prototype = parent.prototype;
  child.prototype = new ctor();
}

function peg$SyntaxError(message, expected, found, location) {
  this.message = message;
  this.expected = expected;
  this.found = found;
  this.location = location;
  this.name = "SyntaxError";

  if (typeof Error.captureStackTrace === "function") {
    Error.captureStackTrace(this, peg$SyntaxError);
  }
}

peg$subclass(peg$SyntaxError, Error);

peg$SyntaxError.buildMessage = function(expected, found) {
  var DESCRIBE_EXPECTATION_FNS = {
        literal: function(expectation) {
          return "\"" + literalEscape(expectation.text) + "\"";
        },

        "class": function(expectation) {
          var escapedParts = expectation.parts.map(function(part) {
            return Array.isArray(part)
              ? classEscape(part[0]) + "-" + classEscape(part[1])
              : classEscape(part);
          });

          return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]";
        },

        any: function(expectation) {
          return "any character";
        },

        end: function(expectation) {
          return "end of input";
        },

        other: function(expectation) {
          return expectation.description;
        }
      };

  function hex(ch) {
    return ch.charCodeAt(0).toString(16).toUpperCase();
  }

  function literalEscape(s) {
    return s
      .replace(/\\/g, "\\\\")
      .replace(/"/g,  "\\\"")
      .replace(/\0/g, "\\0")
      .replace(/\t/g, "\\t")
      .replace(/\n/g, "\\n")
      .replace(/\r/g, "\\r")
      .replace(/[\x00-\x0F]/g,          function(ch) { return "\\x0" + hex(ch); })
      .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x"  + hex(ch); });
  }

  function classEscape(s) {
    return s
      .replace(/\\/g, "\\\\")
      .replace(/\]/g, "\\]")
      .replace(/\^/g, "\\^")
      .replace(/-/g,  "\\-")
      .replace(/\0/g, "\\0")
      .replace(/\t/g, "\\t")
      .replace(/\n/g, "\\n")
      .replace(/\r/g, "\\r")
      .replace(/[\x00-\x0F]/g,          function(ch) { return "\\x0" + hex(ch); })
      .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x"  + hex(ch); });
  }

  function describeExpectation(expectation) {
    return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation);
  }

  function describeExpected(expected) {
    var descriptions = expected.map(describeExpectation);
    var i, j;

    descriptions.sort();

    if (descriptions.length > 0) {
      for (i = 1, j = 1; i < descriptions.length; i++) {
        if (descriptions[i - 1] !== descriptions[i]) {
          descriptions[j] = descriptions[i];
          j++;
        }
      }
      descriptions.length = j;
    }

    switch (descriptions.length) {
      case 1:
        return descriptions[0];

      case 2:
        return descriptions[0] + " or " + descriptions[1];

      default:
        return descriptions.slice(0, -1).join(", ")
          + ", or "
          + descriptions[descriptions.length - 1];
    }
  }

  function describeFound(found) {
    return found ? "\"" + literalEscape(found) + "\"" : "end of input";
  }

  return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";
};

function peg$DefaultTracer() {
  this.indentLevel = 0;
}

peg$DefaultTracer.prototype.trace = function(event) {
  var that = this;

  function log(event) {
    function repeat(string, n) {
       var result = "", i;

       for (i = 0; i < n; i++) {
         result += string;
       }

       return result;
    }

    function pad(string, length) {
      return string + repeat(" ", length - string.length);
    }

    if (typeof console === "object") {
      console.log(
        event.location.start.line + ":" + event.location.start.column + "-"
          + event.location.end.line + ":" + event.location.end.column + " "
          + pad(event.type, 10) + " "
          + repeat("  ", that.indentLevel) + event.rule
      );
    }
  }

  switch (event.type) {
    case "rule.enter":
      log(event);
      this.indentLevel++;
      break;

    case "rule.match":
      this.indentLevel--;
      log(event);
      break;

    case "rule.fail":
      this.indentLevel--;
      log(event);
      break;

    default:
      throw new Error("Invalid event type: " + event.type + ".");
  }
};

function peg$parse(input, options) {
  options = options !== undefined ? options : {};

  var peg$FAILED = {};

  var peg$startRuleIndices = { start: 0, start_streaming: 1 };
  var peg$startRuleIndex = 0;

  var peg$consts = [
    function(s) {
        return s;
      },
    function(f, b) {
        return {
          'type': 'statement',
          'variant': 'list',
          'statement': flattenAll([ f, b ])
        };
      },
    function(s) { return s; },
    peg$otherExpectation("Type Definition"),
    function(t, a) {
        return Object.assign(t, a);
      },
    function(n) {
        return {
          'type': 'datatype',
          'variant': n[0],
          'affinity': n[1]
        };
      },
    peg$otherExpectation("Custom Datatype Name"),
    function(t, r) {
        const variant = foldStringKey([ t, r ]);
        let affinity = 'numeric';
        if (/int/i.test(variant)) {
          affinity = 'integer';
        } else if (/char|clob|text/i.test(variant)) {
          affinity = 'text';
        } else if (/blob/i.test(variant)) {
          affinity = 'blob';
        } else if (/real|floa|doub/i.test(variant)) {
          affinity = 'real';
        }
        return {
          'type': 'datatype',
          'variant': variant,
          'affinity': affinity
        };
      },
    /^[\t ]/,
    peg$classExpectation(["\t", " "], false, false),
    function(w) {
        return w;
      },
    peg$otherExpectation("Type Definition Arguments"),
    function(a1, a2) {
        return {
          'args': {
            'type': 'expression',
            'variant': 'list',
            'expression': flattenAll([ a1, a2 ])
          }
        };
      },
    function(n) { return n; },
    peg$otherExpectation("Null Literal"),
    function(n) {
        return {
          'type': 'literal',
          'variant': 'null',
          'value': keyNode(n)
        };
      },
    peg$otherExpectation("Date Literal"),
    function(d) {
        return {
          'type': 'literal',
          'variant': 'date',
          'value': keyNode(d)
        };
      },
    peg$otherExpectation("String Literal"),
    function(n, s) {
        return {
          'type': 'literal',
          'variant': 'text',
          'value': s
        };
      },
    peg$otherExpectation("Single-quoted String Literal"),
    function(s) {
        /**
         * @note Unescaped the pairs of literal single quotation marks
         */
        /**
         * @note Not sure if the BLOB type should be un-escaped
         */
        return unescape(s, "'");
      },
    "''",
    peg$literalExpectation("''", false),
    /^[^']/,
    peg$classExpectation(["'"], true, false),
    peg$otherExpectation("Blob Literal"),
    /^[x]/i,
    peg$classExpectation(["x"], false, true),
    function(b) {
        return {
          'type': 'literal',
          'variant': 'blob',
          'value': b
        };
      },
    function(n) {
        return {
          'type': 'literal',
          'variant': 'text',
          'value': n
        };
      },
    peg$otherExpectation("Number Sign"),
    function(s, n) {
        if (isOkay(s)) {
          n['value'] = foldStringWord([ s, n['value'] ]);
        }
        return n;
      },
    function(d, e) {
        return {
          'type': 'literal',
          'variant': 'decimal',
          'value': foldStringWord([ d, e ])
        };
      },
    peg$otherExpectation("Decimal Literal"),
    function(f, b) { return foldStringWord([ f, b ]); },
    function(t, d) { return foldStringWord([ t, d ]); },
    peg$otherExpectation("Decimal Literal Exponent"),
    "e",
    peg$literalExpectation("E", true),
    /^[+\-]/,
    peg$classExpectation(["+", "-"], false, false),
    function(e, s, d) { return foldStringWord([ e, s, d ]); },
    peg$otherExpectation("Hexidecimal Literal"),
    "0x",
    peg$literalExpectation("0x", true),
    function(f, b) {
        return {
          'type': 'literal',
          'variant': 'hexidecimal',
          'value': foldStringWord([ f, b ])
        };
      },
    /^[0-9a-f]/i,
    peg$classExpectation([["0", "9"], ["a", "f"]], false, true),
    /^[0-9]/,
    peg$classExpectation([["0", "9"]], false, false),
    peg$otherExpectation("Bind Parameter"),
    function(b) {
        return Object.assign({
          'type': 'variable'
        }, b);
      },
    peg$otherExpectation("Numbered Bind Parameter"),
    function(q, id) {
        return {
          'format': 'numbered',
          'name': foldStringWord([ q, id ])
        };
      },
    /^[1-9]/,
    peg$classExpectation([["1", "9"]], false, false),
    function(f, r) {
        return foldStringWord([ f, r ]);
      },
    peg$otherExpectation("Named Bind Parameter"),
    /^[:@]/,
    peg$classExpectation([":", "@"], false, false),
    function(s, name) {
        return {
          'format': 'named',
          'name': foldStringWord([ s, name ])
        };
      },
    peg$otherExpectation("TCL Bind Parameter"),
    "$",
    peg$literalExpectation("$", false),
    ":",
    peg$literalExpectation(":", false),
    function(d, name, s) {
        return Object.assign({
          'format': 'tcl',
          'name': foldStringWord([ d, name ])
        }, s);
      },
    function(sfx) {
        return {
          'suffix': sfx
        };
      },
    peg$otherExpectation("EXISTS Expression"),
    function(n, e) {
        if (isOkay(n)) {
          return {
            'type': 'expression',
            'format': 'unary',
            'variant': 'exists',
            'expression': e,
            'operator': keyNode(n)
          };
        }
        return e;
      },
    peg$otherExpectation("EXISTS Keyword"),
    function(n, x) { return foldStringKey([ n, x ]); },
    peg$otherExpectation("RAISE Expression"),
    function(s, a) {
        return Object.assign({
          'type': 'expression',
          'format': 'unary',
          'variant': keyNode(s),
          'expression': a
        }, a);
      },
    peg$otherExpectation("RAISE Expression Arguments"),
    function(a) {
        return Object.assign({
          'type': 'error'
        }, a);
      },
    peg$otherExpectation("IGNORE Keyword"),
    function(f) {
        return {
          'action': keyNode(f)
        };
      },
    function(f, m) {
        return {
          'action': keyNode(f),
          'message': m
        };
      },
    function(n) {
        return n;
      },
    function(e, c) {
        return Object.assign(c, {
          'expression': e
        });
      },
    function(op, e) {
        return {
          'type': 'expression',
          'format': 'unary',
          'variant': 'operation',
          'expression': e,
          'operator': keyNode(op)
        };
      },
    peg$otherExpectation("COLLATE Expression"),
    function(c) {
        return Object.assign({
          'type': 'expression',
          'format': 'unary',
          'variant': 'operation',
          'operator': 'collate'
        }, c);
      },
    function(f, rest) { return composeBinary(f, rest); },
    function(i) {
        return [null, i, null, {
          'type': 'literal',
          'variant': 'null',
          'value': 'null'
        }];
      },
    "not ",
    peg$literalExpectation("NOT ", true),
    "null",
    peg$literalExpectation("NULL", true),
    function() { return 'not'; },
    function() { return 'is'; },
    peg$otherExpectation("CAST Expression"),
    function(s, e, a) {
        return {
          'type': 'expression',
          'format': 'unary',
          'variant': keyNode(s),
          'expression': e,
          'as': a
        };
      },
    peg$otherExpectation("Type Alias"),
    function(d) { return d; },
    peg$otherExpectation("CASE Expression"),
    function(t, e, w, s) {
        return Object.assign({
          'type': 'expression',
          'variant': keyNode(t),
          'expression': flattenAll([ w, s ])
        }, e);
      },
    function(e) {
        return {
          'discriminant': e
        };
      },
    peg$otherExpectation("WHEN Clause"),
    function(s, w, t) {
        return {
          'type': 'condition',
          'variant': keyNode(s),
          'condition': w,
          'consequent': t
        };
      },
    peg$otherExpectation("ELSE Clause"),
    function(s, e) {
        return {
          'type': 'condition',
          'variant': keyNode(s),
          'consequent': e
        };
      },
    function(v, p) {
        return Object.assign(p, {
          'left': v
        });
      },
    peg$otherExpectation("Comparison Expression"),
    function(n, m, e, x) {
        return Object.assign({
          'type': 'expression',
          'format': 'binary',
          'variant': 'operation',
          'operation': foldStringKey([ n, m ]),
          'right': e
        }, x);
      },
    peg$otherExpectation("ESCAPE Expression"),
    function(s, e) {
        return {
          'escape': e
        };
      },
    peg$otherExpectation("BETWEEN Expression"),
    function(n, b, tail) {
        return {
          'type': 'expression',
          'format': 'binary',
          'variant': 'operation',
          'operation': foldStringKey([ n, b ]),
          'right': tail
        };
      },
    function(f, rest) { return composeBinary(f, [ rest ]); },
    function(n) { return keyNode(n); },
    peg$otherExpectation("IN Expression"),
    function(n, i, e) {
        return {
          'type': 'expression',
          'format': 'binary',
          'variant': 'operation',
          'operation': foldStringKey([ n, i ]),
          'right': e
        };
      },
    function(e) { return e; },
    peg$otherExpectation("Expression List"),
    function(l) {
        return {
          'type': 'expression',
          'variant': 'list',
          'expression': isOkay(l) ? l : []
        };
      },
    function(f, rest) {
        return flattenAll([ f, rest ]);
      },
    peg$otherExpectation("Function Call"),
    function(n, a) {
        return Object.assign({
          'type': 'function',
          'name': n
        }, a);
      },
    peg$otherExpectation("Function Call Arguments"),
    function(s) {
        return {
          'args': {
            'type': 'identifier',
            'variant': 'star',
            'name': s
          }
        };
      },
    function(d, e) {
        return !isOkay(d) || e['expression'].length > 0;
      },
    function(d, e) {
        return {
          'args': Object.assign(e, d)
        };
      },
    function(s) {
        return {
          'filter': keyNode(s)
        };
      },
    peg$otherExpectation("Error Message"),
    function(m) { return m; },
    peg$otherExpectation("Statement"),
    function(m, s) {
        return Object.assign(s, m);
      },
    peg$otherExpectation("QUERY PLAN"),
    function(e, q) {
        return {
          'explain': isOkay(e)
        };
      },
    peg$otherExpectation("QUERY PLAN Keyword"),
    function(q, p) { return foldStringKey([ q, p ]); },
    peg$otherExpectation("END Transaction Statement"),
    function(s, t) {
        return {
          'type': 'statement',
          'variant': 'transaction',
          'action': 'commit'
        };
      },
    peg$otherExpectation("BEGIN Transaction Statement"),
    function(s, m, t, n) {
        return Object.assign({
          'type': 'statement',
          'variant': 'transaction',
          'action': 'begin'
        }, m, n);
      },
    function(t) { return t; },
    function(m) {
        return {
          'defer': keyNode(m)
        };
      },
    peg$otherExpectation("ROLLBACK Statement"),
    function(s, n) {
        return Object.assign({
          'type': 'statement',
          'variant': 'transaction',
          'action': 'rollback'
        }, n);
      },
    peg$otherExpectation("TO Clause"),
    function(n) {
        return {
          'savepoint': n
        }
      },
    function(s) { return keyNode(s); },
    peg$otherExpectation("SAVEPOINT Statement"),
    function(s, n) {
        return {
          'type': 'statement',
          'variant': s,
          'target': n
        };
      },
    peg$otherExpectation("RELEASE Statement"),
    function(s, a, n) {
        return {
          'type': 'statement',
          'variant': keyNode(s),
          'target': n
        };
      },
    peg$otherExpectation("ALTER TABLE Statement"),
    function(s, n, e) {
        return Object.assign({
          'type': 'statement',
          'variant': keyNode(s),
          'target': n
        }, e);
      },
    peg$otherExpectation("ALTER TABLE Keyword"),
    function(a, t) { return foldStringKey([ a, t ]); },
    peg$otherExpectation("RENAME TO Keyword"),
    function(s, n) {
        return {
          'action': keyNode(s),
          'name': n
        };
      },
    peg$otherExpectation("ADD COLUMN Keyword"),
    function(s, d) {
        return {
          'action': keyNode(s),
          'definition': d
        };
      },
    function(w, s) { return Object.assign(s, w); },
    peg$otherExpectation("WITH Clause"),
    function(s, v, t) {
        var recursive = {
          'variant': isOkay(v) ? 'recursive' : 'common'
        };
        if (isArrayOkay(t)) {
          // Add 'recursive' property into each table expression
          t = t.map(function (elem) {
            return Object.assign(elem, recursive);
          });
        }
        return {
          'with': t
        };
      },
    function(f, r) { return flattenAll([ f, r ]); },
    peg$otherExpectation("Common Table Expression"),
    function(t, s) {
        return Object.assign({
          'type': 'expression',
          'format': 'table',
          'variant': 'common',
          'target': t
        }, s);
      },
    function(s) {
        return {
          'expression': s
        };
      },
    function(w, s) {
        return Object.assign(s, w);
      },
    peg$otherExpectation("ATTACH Statement"),
    function(a, b, e, n) {
        return {
          'type': 'statement',
          'variant': keyNode(a),
          'target': n,
          'attach': e
        };
      },
    peg$otherExpectation("DETACH Statement"),
    function(d, b, n) {
        return {
          'type': 'statement',
          'variant': keyNode(d),
          'target': n
        };
      },
    peg$otherExpectation("VACUUM Statement"),
    function(v, t) {
        return Object.assign({
          'type': 'statement',
          'variant': 'vacuum'
        }, t);
      },
    function(t) {
        return {
          'target': t
        };
      },
    peg$otherExpectation("ANALYZE Statement"),
    function(s, a) {
        return Object.assign({
          'type': 'statement',
          'variant': keyNode(s)
        }, a);
      },
    function(n) {
        return {
          'target': n['name']
        };
      },
    peg$otherExpectation("REINDEX Statement"),
    function(a) {
        return {
          'target': a['name']
        };
      },
    peg$otherExpectation("PRAGMA Statement"),
    function(s, n, v) {
        return {
          'type': 'statement',
          'variant': keyNode(s),
          'target': n,
          'args': {
            'type': 'expression',
            'variant': 'list',
            'expression': v
          }
        };
      },
    function(v) { return v; },
    function(v) { return /^(yes|no|on|off|false|true|0|1)$/i.test(v) },
    function(v) {
        return {
          'type': 'literal',
          'variant': 'boolean',
          'normalized': (/^(yes|on|true|1)$/i.test(v) ? '1' : '0'),
          'value': v
        };
      },
    function(n) {
        return keyNode(n);
      },
    function(n) {
        return {
          'type': 'identifier',
          'variant': 'name',
          'name': n
        };
      },
    peg$otherExpectation("SELECT Statement"),
    function(s, o, l) {
        return Object.assign(s, o, l);
      },
    peg$otherExpectation("ORDER BY Clause"),
    function(d) {
        return {
          'order': d['result']
        };
      },
    peg$otherExpectation("LIMIT Clause"),
    function(s, e, d) {
        return {
          'limit': Object.assign({
            'type': 'expression',
            'variant': 'limit',
            'start': e
          }, d)
        };
      },
    peg$otherExpectation("OFFSET Clause"),
    function(o, e) {
        return {
          'offset': e
        };
      },
    function(s, u) {
        if (isArrayOkay(u)) {
          return {
            'type': 'statement',
            'variant': 'compound',
            'statement': s,
            'compound': u
          };
        } else {
          return s;
        }
      },
    peg$otherExpectation("Union Operation"),
    function(c, s) {
        return {
          'type': 'compound',
          'variant': c,
          'statement': s
        };
      },
    function(s, f, w, g) {
        return Object.assign({
          'type': 'statement',
          'variant': 'select',
        }, s, f, w, g);
      },
    peg$otherExpectation("SELECT Results Clause"),
    function(d, t) {
        return Object.assign({
          'result': t
        }, d);
      },
    peg$otherExpectation("SELECT Results Modifier"),
    function(s) {
        return {
          'distinct': true
        };
      },
    function(s) {
        return {};
      },
    peg$otherExpectation("FROM Clause"),
    function(f, s) {
        return {
          'from': s
        };
      },
    peg$otherExpectation("WHERE Clause"),
    function(f, e) {
        return {
          'where': makeArray(e)
        };
      },
    peg$otherExpectation("GROUP BY Clause"),
    function(f, e, h) {
        return Object.assign({
          'group': e
        }, h);
      },
    peg$otherExpectation("HAVING Clause"),
    function(f, e) {
        return {
          'having': e
        };
      },
    function(q, s) {
        return {
          'type': 'identifier',
          'variant': 'star',
          'name': foldStringWord([ q, s ])
        };
      },
    function(n, s) { return foldStringWord([ n, s ]); },
    function(e, a) {
        return Object.assign(e, a);
      },
    function(f, t) {
        if (isArrayOkay(t)) {
          return {
            'type': 'map',
            'variant': 'join',
            'source': f,
            'map': t
          };
        }
        return f;
      },
    function(cl, c) {
        return Object.assign(cl, c);
      },
    peg$otherExpectation("CROSS JOIN Operation"),
    function(n) {
        return {
          'type': 'join',
          'variant': 'cross join',
          'source': n
        };
      },
    peg$otherExpectation("JOIN Operation"),
    function(o, n) {
        return {
          'type': 'join',
          'variant': keyNode(o),
          'source': n
        };
      },
    function(n, l, a) {
        return Object.assign({
          'type': 'function',
          'variant': 'table',
          'name': n,
          'args': l
        }, a);
      },
    peg$otherExpectation("Qualified Table"),
    function(d, i) {
        return Object.assign(d, i);
      },
    peg$otherExpectation("Qualified Table Identifier"),
    function(n, a) {
        return Object.assign(n, a);
      },
    peg$otherExpectation("Qualfied Table Index"),
    function(s, n) {
        return {
          'index': n
        };
      },
    function(n, i) {
        // TODO: Not sure what should happen here
        return {
          'index': foldStringKey([ n, i ])
        };
      },
    peg$otherExpectation("SELECT Source"),
    function(l, a) { return Object.assign(l, a); },
    peg$otherExpectation("Subquery"),
    function(s, a) {
        return Object.assign(s, a);
      },
    peg$otherExpectation("Alias"),
    function(a, n) {
        return {
          'alias': n
        };
      },
    peg$otherExpectation("JOIN Operator"),
    function(n, t, j) { return foldStringKey([ n, t, j ]); },
    function(t, o) { return foldStringKey([ t, o ]); },
    function(t) { return keyNode(t); },
    peg$otherExpectation("JOIN Constraint"),
    function(c) {
        return {
          'constraint': Object.assign({
            'type': 'constraint',
            'variant': 'join'
          }, c)
        }
      },
    peg$otherExpectation("Join ON Clause"),
    function(s, e) {
        return {
          'format': keyNode(s),
          'on': e
        };
      },
    peg$otherExpectation("Join USING Clause"),
    function(s, e) {
        return {
          'format': keyNode(s),
          'using': e
        };
      },
    peg$otherExpectation("VALUES Clause"),
    function(s, l) {
        return {
          'type': 'statement',
          'variant': 'select',
          'result': l
        };
      },
    function(f, b) {
        return {
          'result': flattenAll([ f, b ])
        };
      },
    function(i) { return i; },
    peg$otherExpectation("Ordering Expression"),
    function(e, d) {
        // Only convert this into an ordering expression if it contains
        // more than just the expression.
        if (isOkay(d)) {
          return Object.assign({
            'type': 'expression',
            'variant': 'order',
            'expression': e
          }, d);
        }
        return e;
      },
    peg$otherExpectation("Star"),
    peg$otherExpectation("Fallback Type"),
    peg$otherExpectation("INSERT Statement"),
    function(k, t) {
        return Object.assign({
          'type': 'statement',
          'variant': 'insert'
        }, k, t);
      },
    peg$otherExpectation("INSERT Keyword"),
    function(a, m) {
        return Object.assign({
          'action': keyNode(a)
        }, m);
      },
    peg$otherExpectation("REPLACE Keyword"),
    function(a) {
        return {
          'action': keyNode(a)
        };
      },
    peg$otherExpectation("INSERT OR Modifier"),
    function(s, m) {
        return {
          'or': keyNode(m)
        };
      },
    function(i, r) {
        return Object.assign({
          'into': i
        }, r);
      },
    peg$otherExpectation("INTO Clause"),
    function(s, t) {
        return t;
      },
    peg$otherExpectation("INTO Keyword"),
    function(r) {
        return {
          'result': r
        };
      },
    peg$otherExpectation("Column List"),
    function(f, b) {
        return {
          'columns': flattenAll([ f, b ])
        };
      },
    function(c) { return c; },
    peg$otherExpectation("Column Name"),
    function(n) {
        return {
          'type': 'identifier',
          'variant': 'column',
          'name': n
        };
      },
    function(s, r) { return r; },
    peg$otherExpectation("VALUES Keyword"),
    function(f, b) { return flattenAll([ f, b ]); },
    peg$otherExpectation("Wrapped Expression List"),
    function(e) {
        return e;
      },
    peg$otherExpectation("DEFAULT VALUES Clause"),
    function(d, v) {
        return {
          'type': 'values',
          'variant': 'default'
          // TODO: Not sure what should go here
          // , 'values': null
        };
      },
    peg$otherExpectation("Compound Operator"),
    peg$otherExpectation("UNION Operator"),
    function(s, a) { return foldStringKey([ s, a ]); },
    function(a) { return a; },
    peg$otherExpectation("UPDATE Statement"),
    function(s, f, t, u, w, o, l) {
        return Object.assign({
          'type': 'statement',
          'variant': s,
          'into': t
        }, f, u, w, o, l);
      },
    peg$otherExpectation("UPDATE Keyword"),
    peg$otherExpectation("UPDATE OR Modifier"),
    function(t) {
        return {
          'or': keyNode(t)
        };
      },
    peg$otherExpectation("SET Clause"),
    function(c) {
        return {
          'set': c
        };
      },
    peg$otherExpectation("Column Assignment"),
    function(f, e) {
        return {
          'type': 'assignment',
          'target': f,
          'value': e
        };
      },
    peg$otherExpectation("DELETE Statement"),
    function(s, t, w, o, l) {
        return Object.assign({
          'type': 'statement',
          'variant': s,
          'from': t
        }, w, o, l);
      },
    peg$otherExpectation("DELETE Keyword"),
    peg$otherExpectation("CREATE Statement"),
    peg$otherExpectation("CREATE TABLE Statement"),
    function(s, ne, id, r) {
        return Object.assign({
          'type': 'statement',
          'name': id
        }, s, r, ne);
      },
    function(s, tmp, t) {
        return Object.assign({
          'variant': s,
          'format': keyNode(t)
        }, tmp);
      },
    function(t) {
        return {
          'temporary': isOkay(t)
        };
      },
    peg$otherExpectation("IF NOT EXISTS Modifier"),
    function(i, n, e) {
        return {
          'condition': makeArray({
            'type': 'condition',
            'variant': keyNode(i),
            'condition': {
              'type': 'expression',
              'variant': keyNode(e),
              'operator': foldStringKey([ n, e ])
            }
          })
        };
      },
    peg$otherExpectation("Table Definition"),
    function(s, t, r) {
        return Object.assign({
          'definition': flattenAll([ s, t ])
        }, r);
      },
    function(r, w) {
        return {
          'optimization': [{
            'type': 'optimization',
            'value': foldStringKey([ r, w ])
          }]
        };
      },
    function(f) { return f; },
    peg$otherExpectation("Column Definition"),
    function(n, t, c) {
        return Object.assign({
          'type': 'definition',
          'variant': 'column',
          'name': n,
          'definition': (isOkay(c) ? c : []),
        }, t);
      },
    peg$otherExpectation("Column Datatype"),
    function(t) {
        return {
          'datatype': t
        };
      },
    peg$otherExpectation("Column Constraint"),
    function(n, c, ln) {
        return Object.assign(c, n);
      },
    function(cl) {
        return cl[cl.length - 1];
      },
    peg$otherExpectation("CONSTRAINT Name"),
    function(n) {
        return {
          'name': n
        };
      },
    peg$otherExpectation("FOREIGN KEY Column Constraint"),
    function(f) {
        return Object.assign({
          'variant': 'foreign key'
        }, f);
      },
    peg$otherExpectation("PRIMARY KEY Column Constraint"),
    function(p, d, c, a) {
        return Object.assign(p, c, d, a);
      },
    peg$otherExpectation("PRIMARY KEY Keyword"),
    function(s, k) {
        return {
          'type': 'constraint',
          'variant': foldStringKey([ s, k ])
        };
      },
    peg$otherExpectation("AUTOINCREMENT Keyword"),
    function(a) {
        return {
          'autoIncrement': true
        };
      },
    function(s, c) {
        return Object.assign({
          'type': 'constraint',
          'variant': s
        }, c);
      },
    peg$otherExpectation("UNIQUE Column Constraint"),
    peg$otherExpectation("NULL Column Constraint"),
    function(n, l) { return foldStringKey([ n, l ]); },
    peg$otherExpectation("CHECK Column Constraint"),
    peg$otherExpectation("DEFAULT Column Constraint"),
    function(s, v) {
        return {
          'type': 'constraint',
          'variant': keyNode(s),
          'value': v
        };
      },
    peg$otherExpectation("COLLATE Column Constraint"),
    function(c) {
        return {
          'type': 'constraint',
          'variant': 'collate',
          'collate': c
        };
      },
    peg$otherExpectation("Table Constraint"),
    function(n, c, nl) {
        return Object.assign({
          'type': 'definition',
          'variant': 'constraint'
        }, c, n);
      },
    peg$otherExpectation("CHECK Table Constraint"),
    function(c) {
        return {
          'definition': makeArray(c)
        };
      },
    peg$otherExpectation("PRIMARY KEY Table Constraint"),
    function(k, c, t) {
        return {
          'definition': makeArray(Object.assign(k, t, c[1])),
          'columns': c[0]
        };
      },
    function(s) {
        return {
          'type': 'constraint',
          'variant': keyNode(s)
        };
      },
    function(p, k) { return foldStringKey([ p, k ]); },
    peg$otherExpectation("UNIQUE Keyword"),
    function(u) { return keyNode(u); },
    function(f, b) {
        return [f].concat(b);
      },
    function(c) {
        return c.map(([ res ]) => res);
      },
    function(c) {
        const auto = c.find(([ res, a ]) => isOkay(a));
        return [
          c.map(([ res, a ]) => res),
          auto ? auto[1] : null
        ];
      },
    peg$otherExpectation("Indexed Column"),
    function(e, d, a) {
        // Only convert this into an ordering expression if it contains
        // more than just the expression.
        let res = e;
        if (isOkay(d)) {
          res = Object.assign({
            'type': 'expression',
            'variant': 'order',
            'expression': e
          }, d);
        }
        return [ res, a ];
      },
    peg$otherExpectation("Collation"),
    function(c) {
        return {
          'collate': makeArray(c)
        };
      },
    peg$otherExpectation("Column Direction"),
    function(t) {
        return {
          'direction': keyNode(t),
        };
      },
    function(s, t) {
        return {
          'conflict': keyNode(t)
        };
      },
    peg$otherExpectation("ON CONFLICT Keyword"),
    function(o, c) { return foldStringKey([ o, c ]); },
    function(k, c) {
        return {
          'type': 'constraint',
          'variant': keyNode(k),
          'expression': c
        };
      },
    peg$otherExpectation("FOREIGN KEY Table Constraint"),
    function(k, l, c) {
        return Object.assign({
          'definition': makeArray(Object.assign(k, c))
        }, l);
      },
    peg$otherExpectation("FOREIGN KEY Keyword"),
    function(f, k) {
        return {
          'type': 'constraint',
          'variant': foldStringKey([ f, k ])
        };
      },
    function(r, a, d) {
        return Object.assign({
          'type': 'constraint'
        }, r, a, d);
      },
    peg$otherExpectation("REFERENCES Clause"),
    function(s, t) {
        return {
          'references': t
        };
      },
    function(f, b) {
        return {
          'action': flattenAll([ f, b ])
        };
      },
    peg$otherExpectation("FOREIGN KEY Action Clause"),
    function(m, a, n) {
        return {
          'type': 'action',
          'variant': keyNode(m),
          'action': keyNode(n)
        };
      },
    peg$otherExpectation("FOREIGN KEY Action"),
    function(s, v) { return foldStringKey([ s, v ]); },
    function(c) { return keyNode(c); },
    function(n, a) { return foldStringKey([ n, a ]); },
    function(m, n) {
        return {
          'type': 'action',
          'variant': keyNode(m),
          'action': n
        };
      },
    peg$otherExpectation("DEFERRABLE Clause"),
    function(n, d, i) {
        return {
          'defer': foldStringKey([ n, d, i ])
        };
      },
    function(i, d) { return foldStringKey([ i, d ]); },
    function(s) {
        return {
          'definition': makeArray(s)
        };
      },
    peg$otherExpectation("CREATE INDEX Statement"),
    function(s, ne, n, o, w) {
        return Object.assign({
          'type': 'statement',
          'target': n,
          'on': o,
        }, s, ne, w);
      },
    function(s, u, i) {
        return Object.assign({
          'variant': keyNode(s),
          'format': keyNode(i)
        }, u);
      },
    function(u) {
        return {
          'unique': true
        };
      },
    peg$otherExpectation("ON Clause"),
    function(o, t, c) {
        return {
          'type': 'identifier',
          'variant': 'expression',
          'format': 'table',
          'name': t['name'],
          'columns': c
        };
      },
    peg$otherExpectation("CREATE TRIGGER Statement"),
    function(s, ne, n, cd, o, me, wh, a) {
        return Object.assign({
          'type': 'statement',
          'target': n,
          'on': o,
          'event': cd,
          'by': (isOkay(me) ? me : 'row'),
          'action': makeArray(a)
        }, s, ne, wh);
      },
    function(s, tmp, t) {
        return Object.assign({
          'variant': keyNode(s),
          'format': keyNode(t)
        }, tmp);
      },
    peg$otherExpectation("Conditional Clause"),
    function(m, d) {
        return Object.assign({
          'type': 'event'
        }, m, d);
      },
    function(m) {
        return {
          'occurs': keyNode(m)
        };
      },
    function(i, o) { return foldStringKey([ i, o ]); },
    peg$otherExpectation("Conditional Action"),
    function(o) {
        return {
          'event': keyNode(o)
        };
      },
    function(s, f) {
        return {
          'event': keyNode(s),
          'of': f
        };
      },
    function(s, c) { return c; },
    "statement",
    peg$literalExpectation("STATEMENT", true),
    function(f, e, r) { return keyNode(r); },
    function(w, e) {
        return {
          'when': e
        };
      },
    peg$otherExpectation("Actions Clause"),
    function(s, a, e) { return a; },
    function(l) { return l; },
    peg$otherExpectation("CREATE VIEW Statement"),
    function(s, ne, n, r) {
        return Object.assign({
          'type': 'statement',
          'target': n,
          'result': r
        }, s, ne);
      },
    function(n, a) {
        return Object.assign({
          'type': 'identifier',
          'variant': 'expression',
          'format': 'view',
          'name': n['name'],
          'columns': []
        }, a);
      },
    function(s, tmp, v) {
        return Object.assign({
          'variant': keyNode(s),
          'format': keyNode(v)
        }, tmp);
      },
    peg$otherExpectation("CREATE VIRTUAL TABLE Statement"),
    function(s, ne, n, m) {
        return Object.assign({
          'type': 'statement',
          'target': n,
          'result': m
        }, s, ne);
      },
    function(s, v, t) {
        return {
          'variant': keyNode(s),
          'format': keyNode(v)
        };
      },
    function(m, a) {
        return Object.assign({
          'type': 'module',
          'variant': 'virtual',
          'name': m
        }, a);
      },
    peg$otherExpectation("Module Arguments"),
    function(l) {
        return {
          'args': {
            'type': 'expression',
            'variant': 'list',
            'expression': isOkay(l) ? l : []
          }
        };
      },
    function(f, b) {
        return flattenAll([ f, b ]).filter((arg) => isOkay(arg));
      },
    function(a) {
        return a;
      },
    peg$otherExpectation("DROP Statement"),
    function(s, q) {
        /**
         * @note Manually copy in the correct variant for the target
         */
        return Object.assign({
          'type': 'statement',
          'target': Object.assign(q, {
                      'variant': s['format']
                    })
        }, s);
      },
    peg$otherExpectation("DROP Keyword"),
    function(s, t, i) {
         return Object.assign({
           'variant': keyNode(s),
           'format': t,
           'condition': []
         }, i);
      },
    peg$otherExpectation("DROP Type"),
    peg$otherExpectation("IF EXISTS Keyword"),
    function(i, e) {
        return {
          'condition': [{
            'type': 'condition',
            'variant': keyNode(i),
            'condition': {
              'type': 'expression',
              'variant': keyNode(e),
              'operator': keyNode(e)
            }
          }]
        };
      },
    peg$otherExpectation("Or"),
    peg$otherExpectation("Add"),
    peg$otherExpectation("Subtract"),
    peg$otherExpectation("Multiply"),
    peg$otherExpectation("Divide"),
    peg$otherExpectation("Modulo"),
    peg$otherExpectation("Shift Left"),
    peg$otherExpectation("Shift Right"),
    peg$otherExpectation("Logical AND"),
    peg$otherExpectation("Logical OR"),
    peg$otherExpectation("Less Than"),
    peg$otherExpectation("Greater Than"),
    peg$otherExpectation("Less Than Or Equal"),
    peg$otherExpectation("Greater Than Or Equal"),
    peg$otherExpectation("Equal"),
    peg$otherExpectation("Not Equal"),
    peg$otherExpectation("IS"),
    function(i, n) { return foldStringKey([ i, n ]); },
    peg$otherExpectation("Identifier"),
    peg$otherExpectation("Database Identifier"),
    function(n) {
        return {
          'type': 'identifier',
          'variant': 'database',
          'name': n
        };
      },
    peg$otherExpectation("Function Identifier"),
    function(d, n) {
        return {
          'type': 'identifier',
          // TODO: Should this be `table function` since it is table-function name
          'variant': 'function',
          'name': foldStringWord([ d, n ])
        };
      },
    peg$otherExpectation("Table Identifier"),
    function(d, n) {
        return {
          'type': 'identifier',
          'variant': 'table',
          'name': foldStringWord([ d, n ])
        };
      },
    function(n, d) { return foldStringWord([ n, d ]); },
    peg$otherExpectation("Column Identifier"),
    function(q, n) {
        return {
          'type': 'identifier',
          'variant': 'column',
          'name': foldStringWord([ q, n ])
        };
      },
    function() { return ''; },
    function(d, t) { return foldStringWord([ d, t ]); },
    peg$otherExpectation("Collation Identifier"),
    function(n) {
        return {
          'type': 'identifier',
          'variant': 'collation',
          'name': n
        };
      },
    peg$otherExpectation("Savepoint Identifier"),
    function(n) {
        return {
          'type': 'identifier',
          'variant': 'savepoint',
          'name': n
        };
      },
    peg$otherExpectation("Index Identifier"),
    function(d, n) {
        return {
          'type': 'identifier',
          'variant': 'index',
          'name': foldStringWord([ d, n ])
        };
      },
    peg$otherExpectation("Trigger Identifier"),
    function(d, n) {
        return {
          'type': 'identifier',
          'variant': 'trigger',
          'name': foldStringWord([ d, n ])
        };
      },
    peg$otherExpectation("View Identifier"),
    function(d, n) {
        return {
          'type': 'identifier',
          'variant': 'view',
          'name': foldStringWord([ d, n ])
        };
      },
    peg$otherExpectation("Pragma Identifier"),
    function(d, n) {
        return {
          'type': 'identifier',
          'variant': 'pragma',
          'name': foldStringWord([ d, n ])
        };
      },
    peg$otherExpectation("CTE Identifier"),
    function(d) {
        return d;
      },
    function(n, a) {
        return Object.assign({
          'type': 'identifier',
          'variant': 'expression',
          'format': 'table',
          'name': n['name'],
          'columns': []
        }, a);
      },
    peg$otherExpectation("Table Constraint Identifier"),
    function(n) {
        return {
          'type': 'identifier',
          'variant': 'constraint',
          'format': 'table',
          'name': n
        };
      },
    peg$otherExpectation("Column Constraint Identifier"),
    function(n) {
        return {
          'type': 'identifier',
          'variant': 'constraint',
          'format': 'column',
          'name': n
        };
      },
    peg$otherExpectation("Datatype Name"),
    function(t) { return [t, 'text']; },
    function(t) { return [t, 'real']; },
    function(t) { return [t, 'numeric']; },
    function(t) { return [t, 'integer']; },
    function(t) { return [t, 'none']; },
    peg$otherExpectation("TEXT Datatype Name"),
    "n",
    peg$literalExpectation("N", true),
    "var",
    peg$literalExpectation("VAR", true),
    "char",
    peg$literalExpectation("CHAR", true),
    "tiny",
    peg$literalExpectation("TINY", true),
    "medium",
    peg$literalExpectation("MEDIUM", true),
    "long",
    peg$literalExpectation("LONG", true),
    "text",
    peg$literalExpectation("TEXT", true),
    "clob",
    peg$literalExpectation("CLOB", true),
    peg$otherExpectation("REAL Datatype Name"),
    "float",
    peg$literalExpectation("FLOAT", true),
    "real",
    peg$literalExpectation("REAL", true),
    peg$otherExpectation("DOUBLE Datatype Name"),
    "double",
    peg$literalExpectation("DOUBLE", true),
    "precision",
    peg$literalExpectation("PRECISION", true),
    function(d, p) { return foldStringWord([ d, p ]); },
    peg$otherExpectation("NUMERIC Datatype Name"),
    "numeric",
    peg$literalExpectation("NUMERIC", true),
    "decimal",
    peg$literalExpectation("DECIMAL", true),
    "boolean",
    peg$literalExpectation("BOOLEAN", true),
    "date",
    peg$literalExpectation("DATE", true),
    "time",
    peg$literalExpectation("TIME", true),
    "stamp",
    peg$literalExpectation("STAMP", true),
    "string",
    peg$literalExpectation("STRING", true),
    peg$otherExpectation("INTEGER Datatype Name"),
    "int",
    peg$literalExpectation("INT", true),
    "2",
    peg$literalExpectation("2", false),
    "4",
    peg$literalExpectation("4", false),
    "8",
    peg$literalExpectation("8", false),
    "eger",
    peg$literalExpectation("EGER", true),
    "big",
    peg$literalExpectation("BIG", true),
    "small",
    peg$literalExpectation("SMALL", true),
    "floating",
    peg$literalExpectation("FLOATING", true),
    "point",
    peg$literalExpectation("POINT", true),
    function(f, p) {
        return foldStringWord([ f, p ]);
      },
    peg$otherExpectation("BLOB Datatype Name"),
    "blob",
    peg$literalExpectation("BLOB", true),
    /^[a-z0-9$_]/i,
    peg$classExpectation([["a", "z"], ["0", "9"], "$", "_"], false, true),
    "\\u",
    peg$literalExpectation("\\u", false),
    /^[a-f0-9]/i,
    peg$classExpectation([["a", "f"], ["0", "9"]], false, true),
    function(u, s) {
      return foldStringWord([ u, s ]).toLowerCase();
    },
    function(n) {
       return keyNode(n);
      },
    peg$anyExpectation(),
    function(n) {
        return textNode(n);
      },
    /^[ \t]/,
    peg$classExpectation([" ", "\t"], false, false),
    "\"",
    peg$literalExpectation("\"", false),
    "\"\"",
    peg$literalExpectation("\"\"", false),
    /^[^"]/,
    peg$classExpectation(["\""], true, false),
    function(n) { return unescape(n, '"'); },
    "'",
    peg$literalExpectation("'", false),
    function(n) { return unescape(n, "'"); },
    "`",
    peg$literalExpectation("`", false),
    "``",
    peg$literalExpectation("``", false),
    /^[^`]/,
    peg$classExpectation(["`"], true, false),
    function(n) { return unescape(n, '`'); },
    peg$otherExpectation("Open Bracket"),
    "[",
    peg$literalExpectation("[", false),
    peg$otherExpectation("Close Bracket"),
    "]",
    peg$literalExpectation("]", false),
    peg$otherExpectation("Open Parenthesis"),
    "(",
    peg$literalExpectation("(", false),
    peg$otherExpectation("Close Parenthesis"),
    ")",
    peg$literalExpectation(")", false),
    peg$otherExpectation("Comma"),
    ",",
    peg$literalExpectation(",", false),
    peg$otherExpectation("Period"),
    ".",
    peg$literalExpectation(".", false),
    peg$otherExpectation("Asterisk"),
    "*",
    peg$literalExpectation("*", false),
    peg$otherExpectation("Question Mark"),
    "?",
    peg$literalExpectation("?", false),
    peg$otherExpectation("Single Quote"),
    peg$otherExpectation("Double Quote"),
    peg$otherExpectation("Backtick"),
    peg$otherExpectation("Tilde"),
    "~",
    peg$literalExpectation("~", false),
    peg$otherExpectation("Plus"),
    "+",
    peg$literalExpectation("+", false),
    peg$otherExpectation("Minus"),
    "-",
    peg$literalExpectation("-", false),
    "=",
    peg$literalExpectation("=", false),
    peg$otherExpectation("Ampersand"),
    "&",
    peg$literalExpectation("&", false),
    peg$otherExpectation("Pipe"),
    "|",
    peg$literalExpectation("|", false),
    "%",
    peg$literalExpectation("%", false),
    "", false),
    peg$otherExpectation("Exclamation"),
    "!",
    peg$literalExpectation("!", false),
    peg$otherExpectation("Semicolon"),
    ";",
    peg$literalExpectation(";", false),
    peg$otherExpectation("Colon"),
    peg$otherExpectation("Forward Slash"),
    "/",
    peg$literalExpectation("/", false),
    peg$otherExpectation("Backslash"),
    "\\",
    peg$literalExpectation("\\", false),
    "abort",
    peg$literalExpectation("ABORT", true),
    "action",
    peg$literalExpectation("ACTION", true),
    "add",
    peg$literalExpectation("ADD", true),
    "after",
    peg$literalExpectation("AFTER", true),
    "all",
    peg$literalExpectation("ALL", true),
    "alter",
    peg$literalExpectation("ALTER", true),
    "analyze",
    peg$literalExpectation("ANALYZE", true),
    "and",
    peg$literalExpectation("AND", true),
    "as",
    peg$literalExpectation("AS", true),
    "asc",
    peg$literalExpectation("ASC", true),
    "attach",
    peg$literalExpectation("ATTACH", true),
    "autoincrement",
    peg$literalExpectation("AUTOINCREMENT", true),
    "before",
    peg$literalExpectation("BEFORE", true),
    "begin",
    peg$literalExpectation("BEGIN", true),
    "between",
    peg$literalExpectation("BETWEEN", true),
    "by",
    peg$literalExpectation("BY", true),
    "cascade",
    peg$literalExpectation("CASCADE", true),
    "case",
    peg$literalExpectation("CASE", true),
    "cast",
    peg$literalExpectation("CAST", true),
    "check",
    peg$literalExpectation("CHECK", true),
    "collate",
    peg$literalExpectation("COLLATE", true),
    "column",
    peg$literalExpectation("COLUMN", true),
    "commit",
    peg$literalExpectation("COMMIT", true),
    "conflict",
    peg$literalExpectation("CONFLICT", true),
    "constraint",
    peg$literalExpectation("CONSTRAINT", true),
    "create",
    peg$literalExpectation("CREATE", true),
    "cross",
    peg$literalExpectation("CROSS", true),
    "current_date",
    peg$literalExpectation("CURRENT_DATE", true),
    "current_time",
    peg$literalExpectation("CURRENT_TIME", true),
    "current_timestamp",
    peg$literalExpectation("CURRENT_TIMESTAMP", true),
    "database",
    peg$literalExpectation("DATABASE", true),
    "default",
    peg$literalExpectation("DEFAULT", true),
    "deferrable",
    peg$literalExpectation("DEFERRABLE", true),
    "deferred",
    peg$literalExpectation("DEFERRED", true),
    "delete",
    peg$literalExpectation("DELETE", true),
    "desc",
    peg$literalExpectation("DESC", true),
    "detach",
    peg$literalExpectation("DETACH", true),
    "distinct",
    peg$literalExpectation("DISTINCT", true),
    "drop",
    peg$literalExpectation("DROP", true),
    "each",
    peg$literalExpectation("EACH", true),
    "else",
    peg$literalExpectation("ELSE", true),
    "end",
    peg$literalExpectation("END", true),
    "escape",
    peg$literalExpectation("ESCAPE", true),
    "except",
    peg$literalExpectation("EXCEPT", true),
    "exclusive",
    peg$literalExpectation("EXCLUSIVE", true),
    "exists",
    peg$literalExpectation("EXISTS", true),
    "explain",
    peg$literalExpectation("EXPLAIN", true),
    "fail",
    peg$literalExpectation("FAIL", true),
    "for",
    peg$literalExpectation("FOR", true),
    "foreign",
    peg$literalExpectation("FOREIGN", true),
    "from",
    peg$literalExpectation("FROM", true),
    "full",
    peg$literalExpectation("FULL", true),
    "glob",
    peg$literalExpectation("GLOB", true),
    "group",
    peg$literalExpectation("GROUP", true),
    "having",
    peg$literalExpectation("HAVING", true),
    "if",
    peg$literalExpectation("IF", true),
    "ignore",
    peg$literalExpectation("IGNORE", true),
    "immediate",
    peg$literalExpectation("IMMEDIATE", true),
    "in",
    peg$literalExpectation("IN", true),
    "index",
    peg$literalExpectation("INDEX", true),
    "indexed",
    peg$literalExpectation("INDEXED", true),
    "initially",
    peg$literalExpectation("INITIALLY", true),
    "inner",
    peg$literalExpectation("INNER", true),
    "insert",
    peg$literalExpectation("INSERT", true),
    "instead",
    peg$literalExpectation("INSTEAD", true),
    "intersect",
    peg$literalExpectation("INTERSECT", true),
    "into",
    peg$literalExpectation("INTO", true),
    "is",
    peg$literalExpectation("IS", true),
    "isnull",
    peg$literalExpectation("ISNULL", true),
    "join",
    peg$literalExpectation("JOIN", true),
    "key",
    peg$literalExpectation("KEY", true),
    "left",
    peg$literalExpectation("LEFT", true),
    "like",
    peg$literalExpectation("LIKE", true),
    "limit",
    peg$literalExpectation("LIMIT", true),
    "match",
    peg$literalExpectation("MATCH", true),
    "natural",
    peg$literalExpectation("NATURAL", true),
    "no",
    peg$literalExpectation("NO", true),
    "not",
    peg$literalExpectation("NOT", true),
    "notnull",
    peg$literalExpectation("NOTNULL", true),
    "of",
    peg$literalExpectation("OF", true),
    "offset",
    peg$literalExpectation("OFFSET", true),
    "on",
    peg$literalExpectation("ON", true),
    "or",
    peg$literalExpectation("OR", true),
    "order",
    peg$literalExpectation("ORDER", true),
    "outer",
    peg$literalExpectation("OUTER", true),
    "plan",
    peg$literalExpectation("PLAN", true),
    "pragma",
    peg$literalExpectation("PRAGMA", true),
    "primary",
    peg$literalExpectation("PRIMARY", true),
    "query",
    peg$literalExpectation("QUERY", true),
    "raise",
    peg$literalExpectation("RAISE", true),
    "recursive",
    peg$literalExpectation("RECURSIVE", true),
    "references",
    peg$literalExpectation("REFERENCES", true),
    "regexp",
    peg$literalExpectation("REGEXP", true),
    "reindex",
    peg$literalExpectation("REINDEX", true),
    "release",
    peg$literalExpectation("RELEASE", true),
    "rename",
    peg$literalExpectation("RENAME", true),
    "replace",
    peg$literalExpectation("REPLACE", true),
    "restrict",
    peg$literalExpectation("RESTRICT", true),
    "right",
    peg$literalExpectation("RIGHT", true),
    "rollback",
    peg$literalExpectation("ROLLBACK", true),
    "row",
    peg$literalExpectation("ROW", true),
    "rowid",
    peg$literalExpectation("ROWID", true),
    "savepoint",
    peg$literalExpectation("SAVEPOINT", true),
    "select",
    peg$literalExpectation("SELECT", true),
    "set",
    peg$literalExpectation("SET", true),
    "table",
    peg$literalExpectation("TABLE", true),
    "temp",
    peg$literalExpectation("TEMP", true),
    "temporary",
    peg$literalExpectation("TEMPORARY", true),
    "then",
    peg$literalExpectation("THEN", true),
    "to",
    peg$literalExpectation("TO", true),
    "transaction",
    peg$literalExpectation("TRANSACTION", true),
    "trigger",
    peg$literalExpectation("TRIGGER", true),
    "union",
    peg$literalExpectation("UNION", true),
    "unique",
    peg$literalExpectation("UNIQUE", true),
    "update",
    peg$literalExpectation("UPDATE", true),
    "using",
    peg$literalExpectation("USING", true),
    "vacuum",
    peg$literalExpectation("VACUUM", true),
    "values",
    peg$literalExpectation("VALUES", true),
    "view",
    peg$literalExpectation("VIEW", true),
    "virtual",
    peg$literalExpectation("VIRTUAL", true),
    "when",
    peg$literalExpectation("WHEN", true),
    "where",
    peg$literalExpectation("WHERE", true),
    "with",
    peg$literalExpectation("WITH", true),
    "without",
    peg$literalExpectation("WITHOUT", true),
    function(r) { return keyNode(r); },
    function() { return null; },
    peg$otherExpectation("Line Comment"),
    "--",
    peg$literalExpectation("--", false),
    /^[\n\v\f\r]/,
    peg$classExpectation(["\n", "\v", "\f", "\r"], false, false),
    peg$otherExpectation("Block Comment"),
    "/*",
    peg$literalExpectation("/*", false),
    "*/",
    peg$literalExpectation("*/", false),
    /^[\n\v\f\r\t ]/,
    peg$classExpectation(["\n", "\v", "\f", "\r", "\t", " "], false, false),
    peg$otherExpectation("Whitespace"),
    "__TODO__",
    peg$literalExpectation("__TODO__", false)
  ];

  var peg$bytecode = [
    peg$decode("%;\u023F/H#;#/?$;\".\" &\"/1$;#/($8$: $!!)($'#(#'#(\"'#&'#"),
    peg$decode("%;\u023F/C#;#/:$;x/1$;#/($8$: $!!)($'#(#'#(\"'#&'#"),
    peg$decode("%;x/B#;\u023F/9$$;%0#*;%&/)$8#:!#\"\" )(#'#(\"'#&'#"),
    peg$decode("$;\u01B30#*;\u01B3&"),
    peg$decode("$;\u01B3/�#*;\u01B3&&&#"),
    peg$decode("%;$/:#;x/1$;\u023F/($8#:\"#!!)(#'#(\"'#&'#"),
    peg$decode("#;T/5$;\u023F/,$;R/#$+$)($'#(#'#(\"'#&'#&/)$8\":u\"\"! )(\"'#&'#"),
    peg$decode(";\u0169.) &;\u016A.# &;\u016B"),
    peg$decode("%;S/\x83#$%;\u023F/>#;V/5$;\u023F/,$;S/#$+$)($'#(#'#(\"'#&'#0H*%;\u023F/>#;V/5$;\u023F/,$;S/#$+$)($'#(#'#(\"'#&'#&/)$8\":u\"\"! )(\"'#&'#"),
    peg$decode(";\u0167.# &;\u0168"),
    peg$decode("%;U/\x83#$%;\u023F/>#;X/5$;\u023F/,$;U/#$+$)($'#(#'#(\"'#&'#0H*%;\u023F/>#;X/5$;\u023F/,$;U/#$+$)($'#(#'#(\"'#&'#&/)$8\":u\"\"! )(\"'#&'#"),
    peg$decode(";\u016C.U &;\u016D.O &;\u016E.I &%%;\u016F/8#%$9:\x9B \"! -\"\"&!&#/)$8#:\x9C#\"\"!)(#'#(\"'#&'#=.\" 7\x99"),
    peg$decode("%;\u01DC.# &;\u01BB/1#;\u023F/($8\":\x9D\"!!)(\"'#&'#"),
    peg$decode("

Web Proxy Viewer  |  New URL  |  Original Page