|
|
|
#!/usr/bin/env node
|
|
|
|
|
|
|
|
var sys = require("sys");
|
|
|
|
var fs = require("fs");
|
|
|
|
var PEG = require("../lib/peg");
|
|
|
|
|
|
|
|
/* ===== Helpers ===== */
|
|
|
|
|
|
|
|
function printVersion() {
|
|
|
|
sys.puts("PEG.js " + PEG.VERSION);
|
|
|
|
}
|
|
|
|
|
|
|
|
function printHelp() {
|
|
|
|
sys.puts("Usage: pegjs [options] [--] [<input_file>] [<output_file>]");
|
|
|
|
sys.puts("");
|
|
|
|
sys.puts("Generates a parser from the PEG grammar specified in the <input_file> and");
|
|
|
|
sys.puts("writes it to the <output_file>.");
|
|
|
|
sys.puts("");
|
|
|
|
sys.puts("If the <output_file> is omitted, its name is generated by changing the");
|
|
|
|
sys.puts("<input_file> extension to \".js\". If both <input_file> and <output_file> are");
|
|
|
|
sys.puts("omitted, standard input and output are used.");
|
|
|
|
sys.puts("");
|
|
|
|
sys.puts("Options:");
|
|
|
|
sys.puts(" -e, --export-var <variable> name of the variable where the parser object");
|
|
|
|
sys.puts(" will be stored (default: \"exports.parser\")");
|
|
|
|
sys.puts(" -v, --version print version information and exit");
|
|
|
|
sys.puts(" -h, --help print help and exit");
|
|
|
|
}
|
|
|
|
|
|
|
|
function exitSuccess() {
|
|
|
|
process.exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
function exitFailure() {
|
|
|
|
process.exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
function abort(message) {
|
|
|
|
sys.error(message);
|
|
|
|
exitFailure();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ===== Arguments ===== */
|
|
|
|
|
|
|
|
var args = process.argv.slice(2); // Trim "node" and the script path.
|
|
|
|
|
|
|
|
function isOption(arg) {
|
|
|
|
return /-.+/.test(arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
function nextArg() {
|
|
|
|
args.shift();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ===== Files ===== */
|
|
|
|
|
|
|
|
function readStream(inputStream, callback) {
|
|
|
|
var input = "";
|
|
|
|
inputStream.on("data", function(data) { input += data; });
|
|
|
|
inputStream.on("end", function() { callback(input); });
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ===== Main ===== */
|
|
|
|
|
|
|
|
/* This makes the generated parser a CommonJS module by default. */
|
|
|
|
var exportVar = "exports.parser";
|
|
|
|
|
|
|
|
while (args.length > 0 && isOption(args[0])) {
|
|
|
|
switch (args[0]) {
|
|
|
|
case "-e":
|
|
|
|
case "--export-var":
|
|
|
|
nextArg();
|
|
|
|
exportVar = args[0];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "-v":
|
|
|
|
case "--version":
|
|
|
|
printVersion();
|
|
|
|
exitSuccess();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "-h":
|
|
|
|
case "--help":
|
|
|
|
printHelp();
|
|
|
|
exitSuccess();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "--":
|
|
|
|
nextArg();
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
abort("Unknown option: " + args[0] + ".");
|
|
|
|
}
|
|
|
|
nextArg();
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (args.length) {
|
|
|
|
case 0:
|
|
|
|
var inputStream = process.openStdin();
|
|
|
|
var outputStream = process.stdout;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
var inputStream = fs.createReadStream(args[0]);
|
|
|
|
var outputStream = fs.createWriteStream(
|
|
|
|
args.length == 1 ? args[0].replace(/\.[^.]*$/, ".js") : args[1]
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort("Too many arguments.");
|
|
|
|
}
|
|
|
|
|
|
|
|
readStream(inputStream, function(input) {
|
|
|
|
try {
|
|
|
|
var parser = PEG.buildParser(input);
|
|
|
|
} catch (e) {
|
|
|
|
if (e.line !== undefined && e.column !== undefined) {
|
|
|
|
abort(e.line + ":" + e.column + ": " + e.message);
|
|
|
|
} else {
|
|
|
|
abort(e.message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
outputStream.write(exportVar + " = " + parser.toSource() + ";\n");
|
|
|
|
outputStream.end();
|
|
|
|
});
|