UNPKG

jison-es

Version:

Fork of jison that emits parsers as ES modules

188 lines (164 loc) 5 kB
#!/usr/bin/env node function getCommandlineOptions () { "use strict"; var version = require('../package.json').version; var opts = require("nomnom") .script('jison') .option('file', { flag : true, position : 0, help : 'file containing a grammar' }) .option('lexfile', { flag : true, position : 1, help : 'file containing a lexical grammar' }) .option('json', { abbr : 'j', flag : true, help : 'force jison to expect a grammar in JSON format' }) .option('outfile', { abbr : 'o', metavar : 'FILE', help : 'Filename and base module name of the generated parser' }) .option('debug', { abbr : 't', flag : true, default: false, help : 'Debug mode' }) .option('module-type', { abbr : 'm', default: 'es', metavar : 'TYPE', help : 'The type of module to generate (es, commonjs, amd, js)' }) .option('parser-type', { abbr : 'p', default: 'lalr', metavar : 'TYPE', help : 'The type of algorithm to use for the parser (lr0, slr,' + 'lalr, lr)' }) .option('version', { abbr : 'V', flag : true, help : 'print version and exit', callback : function () { return version; } }).parse(); return opts; } var cli = module.exports; cli.main = function cliMain(opts) { "use strict"; opts = opts || {}; function processGrammar(raw, lex, opts) { var grammar, parser; grammar = cli.processGrammars(raw, lex, opts.json); parser = cli.generateParserString(opts, grammar); return parser; } function processInputFile () { var fs = require('fs'); var path = require('path'); // getting raw files var lex; if (opts.lexfile) { lex = fs.readFileSync(path.normalize(opts.lexfile), 'utf8'); } var raw = fs.readFileSync(path.normalize(opts.file), 'utf8'); // making best guess at json mode opts.json = path.extname(opts.file) === '.json' || opts.json; // setting output file name and module name based on input file name // if they aren't specified. var name = path.basename((opts.outfile || opts.file)); name = name.replace(/\..*$/g, ''); opts.outfile = opts.outfile || (name + '.js'); if (!opts.moduleName && name) { opts.moduleName = name.replace(/-\w/g, function (match) { return match.charAt(1).toUpperCase(); }); } var parser = processGrammar(raw, lex, opts); fs.writeFileSync(opts.outfile, parser); } function readin(cb) { var stdin = process.openStdin(), data = ''; stdin.setEncoding('utf8'); stdin.addListener('data', function (chunk) { data += chunk; }); stdin.addListener('end', function () { cb(data); }); } function processStdin () { readin(function (raw) { console.log(processGrammar(raw, null, opts)); }); } // if an input file wasn't given, assume input on stdin if (opts.file) { processInputFile(); } else { processStdin(); } }; cli.generateParserString = function generateParserString(opts, grammar) { "use strict"; opts = opts || {}; var jison = require('./jison.js'); var settings = grammar.options || {}; if (opts['parser-type']) { settings.type = opts['parser-type']; } if (opts.moduleName) { settings.moduleName = opts.moduleName; } settings.debug = opts.debug; if (!settings.moduleType) { settings.moduleType = opts['module-type']; } var generator = new jison.Generator(grammar, settings); return generator.generate(settings); }; cli.processGrammars = function processGrammars(file, lexFile, jsonMode) { "use strict"; lexFile = lexFile || false; jsonMode = jsonMode || false; var ebnfParser = require('ebnf-parser'); var cjson = require('cjson'); var grammar; try { if (jsonMode) { grammar = cjson.parse(file); } else { grammar = ebnfParser.parse(file); } } catch (e) { throw new Error('Could not parse jison grammar'); } try { if (lexFile) { grammar.lex = require('lex-parser').parse(lexFile); } } catch (e) { throw new Error('Could not parse lex grammar'); } return grammar; }; if (require.main === module) { var opts = getCommandlineOptions(); cli.main(opts); }