36 lines
1.4 KiB
JavaScript
36 lines
1.4 KiB
JavaScript
import nearley from 'nearley';
|
|
import { disambiguateTokens } from '../lexer/disambiguateTokens.js';
|
|
import grammar from './grammar.js';
|
|
import LexerAdapter from './LexerAdapter.js';
|
|
import { createEofToken } from '../lexer/token.js';
|
|
const { Parser: NearleyParser, Grammar } = nearley;
|
|
/**
|
|
* Creates a parser object which wraps the setup of Nearley parser
|
|
*/
|
|
export function createParser(tokenizer) {
|
|
let paramTypesOverrides = {};
|
|
const lexer = new LexerAdapter(chunk => [
|
|
...disambiguateTokens(tokenizer.tokenize(chunk, paramTypesOverrides)),
|
|
createEofToken(chunk.length),
|
|
]);
|
|
const parser = new NearleyParser(Grammar.fromCompiled(grammar), { lexer });
|
|
return {
|
|
parse: (sql, paramTypes) => {
|
|
// share paramTypesOverrides with Tokenizer
|
|
paramTypesOverrides = paramTypes;
|
|
const { results } = parser.feed(sql);
|
|
if (results.length === 1) {
|
|
return results[0];
|
|
}
|
|
else if (results.length === 0) {
|
|
// Ideally we would report a line number where the parser failed,
|
|
// but I haven't found a way to get this info from Nearley :(
|
|
throw new Error('Parse error: Invalid SQL');
|
|
}
|
|
else {
|
|
throw new Error(`Parse error: Ambiguous grammar\n${JSON.stringify(results, undefined, 2)}`);
|
|
}
|
|
},
|
|
};
|
|
}
|
|
//# sourceMappingURL=createParser.js.map
|