Add pscan tool, to convert JSON parse stream into AST-like object

This commit is contained in:
Jeff Garzik
2019-01-05 02:35:54 -05:00
parent 75ee778e7e
commit b55855e24f
3 changed files with 101 additions and 0 deletions

View File

@ -11,6 +11,7 @@ pkgconfig_DATA = libsqlpars.pc
# noinst_PROGRAMS = $(TESTS) # noinst_PROGRAMS = $(TESTS)
EXTRA_DIST = sql.y sql.l \ EXTRA_DIST = sql.y sql.l \
pscan.js \
test-ok.sh test-fail.sh \ test-ok.sh test-fail.sh \
fail1.sql \ fail1.sql \
fail3.sql \ fail3.sql \
@ -25,6 +26,7 @@ EXTRA_DIST = sql.y sql.l \
ok6.sql \ ok6.sql \
ok7.sql \ ok7.sql \
ok8.sql \ ok8.sql \
ok9.sql \
tst-create-db.sql \ tst-create-db.sql \
tst-create-table1.sql tst-create-table1.sql

5
ok9.sql Normal file
View File

@ -0,0 +1,5 @@
CREATE TEMPORARY TABLE IF NOT EXISTS mytab (
i INT PRIMARY KEY,
t TEXT NOT NULL,
s VARCHAR(100) DEFAULT 'buzz'
);

94
pscan.js Executable file
View File

@ -0,0 +1,94 @@
#!/usr/bin/env node
const fs = require('fs');
const assert = require('assert');
const lines = fs.readFileSync(process.argv[2], {encoding:'utf8'}).split("\n");
function getRecordStream(lineList)
{
var recs = [];
const blankRx = /^\s*$/;
lineList.forEach(function(line) {
if (blankRx.test(line))
return;
try {
const record = JSON.parse(line);
recs.push(record);
} catch (e) {
console.error("Invalid line: ", line);
console.error(e);
}
});
return recs;
}
function parseRecordStream(recs)
{
var stk = [];
var ret = null;
recs.forEach(function(current) {
if (current.op && current.op == 'DEFINE-COL') {
var objColumn = {
name: current.name,
flags: current.flags,
attr: [],
};
while (stk.length > 0) {
const rec = stk.pop();
if ('attr' in rec)
objColumn.attr.push(rec);
else if (rec.op && rec.op == 'START-COL')
break;
else {
assert.fail('unhandled rec: ' + JSON.stringify(rec));
}
}
stk.push(objColumn);
} else if (current.op && current.op == 'CREATE-TABLE') {
var objTable = {
verb: 'CREATE_TABLE',
name: current.name,
temp: current.temp,
if_n_exists: current.if_n_exists,
n_cols: current.n_cols,
columns: [],
};
var wantCols = objTable.n_cols;
while (wantCols-- > 0) {
const col = stk.pop();
assert(col !== undefined);
objTable.columns.push(col);
}
stk.push(objTable);
} else if (current.op && current.op == 'STMT') {
const stmt = stk.pop();
assert(stk.length === 0);
ret = stmt;
} else if ('result' in current) {
// EOF; do nothing
} else {
// console.log("PUSH", current);
stk.push(current);
}
});
return ret;
}
const recs = getRecordStream(lines);
// console.dir(recs);
const stmt = parseRecordStream(recs);
console.log(JSON.stringify(stmt, null, 2) + "\n");