const moo = require('moo') function compileClass(constructor, indent) { let s = '' s += indent + 'var ' + constructor.name + ' = ' + constructor for (let key in constructor.prototype) { s += '\n\n' const value = constructor.prototype[key] if (typeof value === 'function') { s += indent + constructor.name + '.prototype.' + key + ' = ' + value } } if (constructor.prototype[Symbol.iterator]) { s += '\n\n' s += indent + constructor.name + '.prototype[Symbol.iterator] = ' + constructor.prototype[Symbol.iterator] } return s } function compileGroup(group, indent) { let s = '' s += '{\n' for (let key in group) { const value = group[key] switch (key) { case 'type': case 'value': case 'next': case 'push': if (value === null) continue break case 'match': s += indent + ' // ' + value + '\n'; continue } let valueStr = JSON.stringify(value) if (typeof value === 'function') { valueStr = ('' + value).replace(/\n/g, "\n" + indent) } s += indent + ' ' + key + ': ' + valueStr + ',\n' } s += indent + '}' return s } function compileLexer(lexer) { let s = '' s += '(function() {\n' // Emit utility functions s += ' function tokenToString() { return this.value }\n\n' // Emit Lexer source const Lexer = lexer.__proto__.constructor s += compileClass(Lexer, ' ') + '\n\n' // Emit LexerIterator source const iterator = lexer[Symbol.iterator]() const LexerIterator = iterator.__proto__.constructor s += ' {\n' s += compileClass(LexerIterator, ' ') + '\n' s += ' }\n\n' // Emit lexer instance let sticky = true s += ' return new Lexer({\n' for (let name in lexer.states) { s += ' ' + JSON.stringify(name) + ': {\n' const state = lexer.states[name] sticky = state.regexp.sticky s += ' regexp: ' + ('' + state.regexp).replace('\n', '\\n') + ',\n' s += ' groups: [\n' for (let group of state.groups) { s += ' ' + compileGroup(group, ' ') + ',\n' } s += ' ],\n' s += ' fast: {\n' for (let key in state.fast) { const group = state.fast[key] s += ' ' + (+key) + ': ' + compileGroup(group, ' ') + ',\n' } s += ' },\n' s += ' error: ' + compileGroup(state.error, ' ') + ',\n' s += ' },\n' } s += ' }, ' + JSON.stringify(lexer.startState) + ')\n\n' // More utility functions // assume hasSticky = true s += ' function eat(re, buffer) {\n' s += ' return re.exec(buffer)\n' s += ' }\n' s += '}())' return s } module.exports = compileLexer