(tokenizer: Tokenizer)
| 18 | * Creates a parser object which wraps the setup of Nearley parser |
| 19 | */ |
| 20 | export function createParser(tokenizer: Tokenizer): Parser { |
| 21 | let paramTypesOverrides: ParamTypes = {}; |
| 22 | const lexer = new LexerAdapter(chunk => [ |
| 23 | ...disambiguateTokens(tokenizer.tokenize(chunk, paramTypesOverrides)), |
| 24 | createEofToken(chunk.length), |
| 25 | ]); |
| 26 | const parser = new NearleyParser(Grammar.fromCompiled(grammar), { lexer }); |
| 27 | |
| 28 | return { |
| 29 | parse: (sql: string, paramTypes: ParamTypes) => { |
| 30 | // share paramTypesOverrides with Tokenizer |
| 31 | paramTypesOverrides = paramTypes; |
| 32 | |
| 33 | const { results } = parser.feed(sql); |
| 34 | |
| 35 | if (results.length === 1) { |
| 36 | return results[0]; |
| 37 | } else if (results.length === 0) { |
| 38 | // Ideally we would report a line number where the parser failed, |
| 39 | // but I haven't found a way to get this info from Nearley :( |
| 40 | throw new Error('Parse error: Invalid SQL'); |
| 41 | } else { |
| 42 | throw new Error(`Parse error: Ambiguous grammar\n${JSON.stringify(results, undefined, 2)}`); |
| 43 | } |
| 44 | }, |
| 45 | }; |
| 46 | } |
searching dependent graphs…