re2-js-generator/main.js

48 lines
2.3 KiB
JavaScript

/**
* Created by Aleksey Chichenkov <a.chichenkov@initi.ru> on 1/23/19.
*/
var js_beautify = require("js-beautify");
var fs = require("fs");
var exec = require('child_process').exec;
exec("re2c -i lexer.l", function(err, stdout, stderr) {
err && console.log("ERROR: ", err);
err && process.exit(1);
post_process_lexer(stdout);
});
var post_process_lexer = function (_string) {
// insert last case for string detect
_string = _string.replace(/\}\nENDER}/gm, "yy100000000: { this._searchString(); this._set_next(); return; }}}");
_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;
_string = _string.replace(/\*(.*?);/gm, "this._string[$1];"); // замена разыменовываний
_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
// black magic
_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
_string = js_beautify(_string, {indent_size: 4, space_in_empty_paren: true});
var output = "lexer.js";
if(process.argv[2]){
output = process.argv[2];
}
fs.writeFileSync(output, _string);
};