UNPKG

xqlint

Version:

XQuery & JSONiq Quality Checker

100 lines (84 loc) 3.06 kB
'use strict'; var TokenHandler = function(code) { var input = code; this.tokens = []; this.reset = function() { input = input; this.tokens = []; }; this.startNonterminal = function() {}; this.endNonterminal = function() {}; this.terminal = function(name, begin, end) { this.tokens.push({ name: name, value: input.substring(begin, end) }); }; this.whitespace = function(begin, end) { this.tokens.push({ name: 'WS', value: input.substring(begin, end) }); }; }; exports.Lexer = function(Tokenizer, Rules) { this.tokens = []; this.getLineTokens = function(line, state) { state = (state === 'start' || !state) ? '["start"]' : state; var stack = JSON.parse(state); var h = new TokenHandler(line); var tokenizer = new Tokenizer(line, h); var tokens = []; while(true) { var currentState = stack[stack.length - 1]; try { h.tokens = []; tokenizer['parse_' + currentState](); var info = null; if(h.tokens.length > 1 && h.tokens[0].name === 'WS') { tokens.push({ type: 'text', value: h.tokens[0].value }); h.tokens.splice(0, 1); } var token = h.tokens[0]; var rules = Rules[currentState]; for(var k = 0; k < rules.length; k++) { var rule = Rules[currentState][k]; if((typeof(rule.name) === 'function' && rule.name(token)) || rule.name === token.name) { info = rule; break; } } if(token.name === 'EOF') { break; } if(token.value === '') { throw 'Encountered empty string lexical rule.'; } tokens.push({ type: info === null ? 'text' : (typeof(info.token) === 'function' ? info.token(token.value) : info.token), value: token.value }); if(info && info.next) { info.next(stack); } } catch(e) { if(e instanceof tokenizer.ParseException) { var index = 0; for(var i=0; i < tokens.length; i++) { index += tokens[i].value.length; } tokens.push({ type: 'text', value: line.substring(index) }); return { tokens: tokens, state: JSON.stringify(['start']) }; } else { throw e; } } } return { tokens: tokens, state: JSON.stringify(stack) }; }; };