re2-js-generator/main.js

106 lines
4.1 KiB
JavaScript
Raw Normal View History

2019-01-24 13:57:54 +00:00
/**
* Created by Aleksey Chichenkov <a.chichenkov@initi.ru> on 1/23/19.
*/
2019-01-30 12:43:01 +00:00
var js_beautify = require("./libs/js-beautifier");
var args = require("./libs/args-parser")(process.argv);
2019-01-25 13:30:02 +00:00
2019-01-24 13:57:54 +00:00
var fs = require("fs");
var exec = require('child_process').exec;
2019-01-30 11:16:22 +00:00
var inp = args["in"] ? args["in"] : "lexer.l";
var enable_logs = args["logs"] ? args["logs"] : false;
exec("re2c -i " + inp, function(err, stdout, stderr) {
2019-01-24 13:57:54 +00:00
err && console.log("ERROR: ", err);
err && process.exit(1);
post_process_lexer(stdout);
});
var post_process_lexer = function (_string) {
2019-01-30 13:53:12 +00:00
var output = args["o"] || "lexer.js";
2019-01-24 15:10:15 +00:00
2019-01-30 09:49:21 +00:00
// replace start and end fbrackets
_string = _string.replace(/START\n\{/gm, "");
_string = _string.replace(/\}\nEND/gm, "");
2019-01-24 15:10:15 +00:00
2019-01-24 13:57:54 +00:00
_string = _string.replace(/^.*(_r2c_var_.*;|unsigned int yyaccept = 0;)\n/gm, ""); // replace var yych;
_string = _string.replace(/(yych = \*this._yy_cursor);\n/gm, "\tcase 1:\n yych = this._string[this._yy_cursor];\n"); // insert "case 1:" before;
2019-01-30 13:53:12 +00:00
2019-01-30 14:39:07 +00:00
_string = _string.replace(/switch \(\(yych = \*this\._yy_cursor\)\) \{/gm, "this._yy_char = this._string[this._yy_cursor]; \n switch (yych) {"); // замена разыменовываний
2019-01-30 13:53:12 +00:00
_string = _string.replace(/\*\((.*?)\);/gm, "this._string[($1)];"); // замена разыменовываний
_string = _string.replace(/\*(.* ?);/gm, "this._string[$1];"); // замена разыменовываний
2019-01-30 13:59:42 +00:00
_string = _string.replace(/\*(.* ?)\)/gm, "this._string[$1])"); // замена разыменовываний
2019-01-30 14:13:54 +00:00
2019-01-24 13:57:54 +00:00
_string = _string.replace(/^yy(\d*?):/gm, "case $1:"); // replace goto marker onto case
_string = _string.replace(/\) goto yy(\d*?);/gm, ") { id = $1; break; }"); // replace goto inside if
_string = _string.replace(/goto yy(\d*?);/gm, "id = $1; break;"); // replace goto outside if
_string = _string.replace(/\{ (addLexeme.*break;) \}/gm, "$1"); // replace addLexeme
_string = _string.replace(/\{ (unknownSymbol.*break;) \}/gm, "$1"); // replace unknownSymbol
_string = _string.replace(/0x00/gm, 'undefined'); // replace 0x00
_string = _string.replace(/(switch \(yych\) \{[\s\S]*?})/gm, "(function(){$1}.bind(this))(); break;"); // добавим замыкание что бы обработать свиче в свиче
_string = _string.replace(/switch\((id)\)/gm, "switch(this._state)"); // replace id to this._state
_string = _string.replace(/id = (\d.*?);/gm, "this._state = $1;"); // replace id = n to this._state = n
_string = _string.replace(/yyaccept/gm, "this._yy_accept"); // replace yyaccept to this._yy_accept
_string = _string.replace(/yych/gm, "this._yy_char"); // replace yych to this._yy_char
2019-01-24 13:57:54 +00:00
2019-01-25 13:30:02 +00:00
if(args["t"] !== undefined) {
switch (args["t"]) {
case "web":
2019-01-30 11:16:22 +00:00
_string = "(function () {var deps = [];define(deps, function(){\n" + _string + "return Lexer; \n});})();";
2019-01-25 13:30:02 +00:00
break;
case "node":
_string += "\n module.exports = Lexer";
break;
}
}
2019-01-24 13:57:54 +00:00
2019-01-30 09:49:21 +00:00
_string = process_metatags(_string);
2019-01-25 13:30:02 +00:00
if( !(args["no-beautify"] || args["nb"]) ) {
2019-01-30 12:43:01 +00:00
_string = js_beautify(_string, {
indent_size: 4,
indent_char: ' ',
preserve_newlines: true,
space_after_anon_function: true,
keep_array_indentation: false,
braces_on_own_line: false
});
2019-01-25 12:15:41 +00:00
}
2019-01-30 11:16:22 +00:00
if(!enable_logs){
_string = _string.replace(/^ *console\.log[\s\S]*?$\n/gm, "");
}
2019-01-25 12:15:41 +00:00
fs.writeFileSync(output, _string);
2019-01-30 09:49:21 +00:00
};
var process_metatags = function (_string) {
var metatags = {};
_string = _string.replace(/&&>([A-Z_][A-Z0-9_]+)([\s\S]*?)&&/gm, function (_full, _metatag, _text) {
if(!metatags[_metatag]){
metatags[_metatag] = {
includes: []
};
}
metatags[_metatag].includes.push(_text);
return "";
});
_string = _string.replace(/&&<([A-Z_][A-Z0-9_]+)&&/gm, function (_full, _metatag) {
var metatag = metatags[_metatag];
if(!metatag){
throw "not found metatag for include"
}
return metatag.includes.join("");
});
return _string;
2019-01-24 13:57:54 +00:00
};