#!/usr/bin/env node try { var rr = require('railroad-diagrams'); } catch(e) { // optional dependency not fullfilled console.log('Error: When you installed nearley, the dependency "railroad-diagrams" failed to install. Try running "npm install -g nearley" to re-install nearley. If that doesn\'t fix the problem, please file an issue on the nearley GitHub repository.') process.exit(1) } var fs = require('fs'); var path = require('path'); var opts = require('commander'); var version = require('../package.json').version; opts.version(version, '-v, --version') .arguments('') .option('-o, --out [filename.svg]', 'File to output to (default stdout).', false) .parse(process.argv); var input = opts.args[0] ? fs.createReadStream(opts.args[0]) : process.stdin; var output = opts.out ? fs.createWriteStream(opts.out) : process.stdout; function railroad(grm) { var rules = {}; grm.forEach(function(instr) { if (instr.rules) { if (!rules[instr.name]) { rules[instr.name] = []; } rules[instr.name] = rules[instr.name].concat(instr.rules); } }); var style = fs.readFileSync( path.join( path.dirname(require.resolve('railroad-diagrams')), 'railroad-diagrams.css' ) ); var diagrams = Object.keys(rules).map(function(r) { return [ '

' + r + '

', '
', diagram(r).toString(), '
' ].join('\n'); }); function diagram(name) { var selectedrules = rules[name]; var outer = {subexpression: selectedrules}; function renderTok(tok) { // ctx translated to correct position already if (tok.subexpression) { return new rr.Choice(0, tok.subexpression.map(renderTok)); } else if (tok.ebnf) { switch (tok.modifier) { case ":+": return new rr.OneOrMore(renderTok(tok.ebnf)); break; case ":*": return new rr.ZeroOrMore(renderTok(tok.ebnf)); break; case ":?": return new rr.Optional(renderTok(tok.ebnf)); break; } } else if (tok.literal) { return new rr.Terminal(JSON.stringify(tok.literal)); } else if (tok.mixin) { return new rr.Comment("Pas implementé."); } else if (tok.macrocall) { return new rr.Comment("Pas implementé."); } else if (tok.tokens) { return new rr.Sequence(tok.tokens.map(renderTok)); } else if (typeof(tok) === 'string') { return new rr.NonTerminal(tok); } else if (tok.constructor === RegExp) { return new rr.Terminal(tok.toString()); } else if (tok.token) { return new rr.Terminal(tok.token); } else { return new rr.Comment("[Unimplemented]"); } } return new rr.Diagram([renderTok(outer)]); } return [ '', '', '', '', '', '', '', diagrams.join('\n'), '', '' ].join('\n'); } var nearley = require('../lib/nearley.js'); var StreamWrapper = require('../lib/stream.js'); var parserGrammar = nearley.Grammar.fromCompiled(require('../lib/nearley-language-bootstrapped.js')); var parser = new nearley.Parser(parserGrammar); input .pipe(new StreamWrapper(parser)) .on('finish', function() { if (parser.results[0]) { output.write(railroad(parser.results[0])); } else { process.stderr.write('SyntaxError: unexpected EOF\n'); } });