diff --git a/src/script2txt/script.h b/src/script2txt/script.h deleted file mode 100644 index c07cf7d..0000000 --- a/src/script2txt/script.h +++ /dev/null @@ -1,130 +0,0 @@ -/* -* AIM script2txt -* Copyright (C) 2015 lzwdgc -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*/ - -#pragma once - -#include -#include - -#include - -template -inline bool replace_all(T &str, const T &from, const T &to) -{ - bool replaced = false; - size_t start_pos = 0; - while ((start_pos = str.find(from, start_pos)) != T::npos) - { - str.replace(start_pos, from.length(), to); - start_pos += to.length(); - replaced = true; - } - return replaced; -} - -inline bool replace_all(std::string &str, const std::string &from, const std::string &to) -{ - return replace_all(str, from, to); -} - -struct script -{ - uint32_t file_size; - uint32_t unk0; // stack size? always 16000? section bits? magic? max size? - uint32_t raw_text_size; - uint32_t nlines; - std::vector raw_text; - uint32_t line_start_pos_len; // always 800 - std::vector line_start_pos; - - // - std::vector lines; - - void load(const buffer &b) - { - READ(b, file_size); - READ(b, unk0); - READ(b, raw_text_size); - READ(b, nlines); - raw_text.resize(raw_text_size); - if (raw_text_size) - READ_N(b, raw_text[0], raw_text.size()); - READ(b, line_start_pos_len); - line_start_pos.resize(line_start_pos_len); - READ_N(b, line_start_pos[0], line_start_pos.size()); - - if (!b.eof()) - { - std::stringstream ss; - ss << std::hex << b.index() << " != " << std::hex << b.size(); - throw std::logic_error(ss.str()); - } - - fix_text(); - } - - void fix_text() - { - std::string line; - for (size_t i = 0; i < raw_text.size(); i++) - { - if (raw_text[i] == 0) - { - lines.push_back(line); - line.clear(); - } - else - line.push_back(raw_text[i]); - } - } - - std::string get_text() const - { - std::string s; - for (auto &line : lines) - { - if (line != "\n") - s += line + "\n"; - } - - replace_all(s, "PROC", "PROC "); - replace_all(s, "ENFD", "END"); - replace_all(s, "\nEN\n", "\n"); - replace_all(s, "?", " "); - s += "\nEND\n"; - - // remove wrong braces - int braces = 0; - for (auto &c : s) - { - switch (c) - { - case '{': - braces++; - break; - case '}': - if (braces == 0) - c = ' '; - else - braces--; - break; - } - } - return s; - } -}; diff --git a/src/script2txt/script2txt.cpp b/src/script2txt/script2txt.cpp index 1ecb40c..0a1da84 100644 --- a/src/script2txt/script2txt.cpp +++ b/src/script2txt/script2txt.cpp @@ -1,6 +1,6 @@ /* - * AIM script2txt - * Copyright (C) 2015 lzwdgc + * AIM script2txt2 (simpler version) + * Copyright (C) 2024 lzwdgc * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,81 +16,103 @@ * along with this program. If not, see . */ -#include "script.h" +#include +#include -#include - -#include #include #include #include #include -#include -#include -using std::cout; -using std::string; - -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { cl::opt p(cl::Positional, cl::desc(""), cl::Required); cl::ParseCommandLineOptions(argc, argv); - auto func = [](auto filename) - { - // read - buffer b(read_file(filename)); - script s; - s.load(b); - auto str = s.get_text(); - - Script2txtParserDriver driver; - if (driver.parse(str)) - { - throw std::runtime_error("error during parsing input file"); + auto func = [](auto filename) { + primitives::templates2::mmap_file f{filename}; + stream s{f}; + script scr = s; + std::vector lines; + int sz{}; + for (int i = 0; i < scr.nlines; ++i) { + sz += lines.emplace_back((const char *)f.p + sizeof(script) + sz).size() + 1; } - auto &ctx = driver.getContext(); // write script { filename += ".txt"; - std::ofstream ofile(filename); - if (ofile) - ofile << ctx.getText(); - } + if (std::ofstream ofile(filename, std::ios::binary); ofile) { + std::string indent, space = " "s; + auto inc = [&]() { + indent += space; + }; + auto dec = [&]() { + if (!indent.empty()) { + indent.resize(indent.size() - space.size()); + return true; + } + return false; + }; + int procs{}; + bool prev_newline{}; + for (auto &&l : lines) { + auto else_ = l == "ELSE"sv; + auto proc = l.starts_with("PROC"sv); + auto end = l == "END"sv; + auto lbrace = l == "{"sv; + auto rbrace = l == "}"sv; - // write function calls - { - std::ofstream functions("functions.txt", std::ios::app); - if (functions) - { - for (auto &f : driver.functions) - { - std::string f2(f.size(), 0); - std::transform(f.begin(), f.end(), f2.begin(), tolower); - functions << f2 << "\n"; + if (else_ && prev_newline) { + ofile.seekp(-1, std::ios::cur); + } + prev_newline = false; + + if (rbrace) { + if (!dec()) { + ofile << "// script2txt2 comment: unbalanced!\n"; + } + } + if (end && procs) { + if (!dec()) { + ofile << "// script2txt2 comment: unbalanced!\n"; + } + } + + ofile << indent << l << "\n"; + + if ((end || rbrace) && indent.empty()) { + ofile << "\n"; + prev_newline = true; + } + if (end && procs) { + procs = 0; + } + if (lbrace || proc) { + indent += space; + } + if (proc) { + procs = 1; + } } } } }; - if (fs::is_regular_file(p)) + if (fs::is_regular_file(p)) { func(p.string()); - else if (fs::is_directory(p)) - { + } else if (fs::is_directory(p)) { auto files = enumerate_files_like(p, ".*\\.scr", false); auto files2 = enumerate_files_like(p, ".*\\.QST", false); files.insert(files2.begin(), files2.end()); - for (auto &f : files) - { + for (auto &f : files) { std::cout << "processing: " << f << "\n"; func(f.string()); } - } - else + } else { throw std::runtime_error("Bad fs object"); + } return 0; } diff --git a/src/script2txt/script2txt.ll b/src/script2txt/script2txt.ll deleted file mode 100644 index c7fad95..0000000 --- a/src/script2txt/script2txt.ll +++ /dev/null @@ -1,100 +0,0 @@ -%{ -/* - * AIM tm_converter - * Copyright (C) 2015 lzwdgc - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -%} - -%option nounistd -%option yylineno -%option nounput -%option batch -%option never-interactive -%option reentrant -%option noyywrap - -DIGIT [0-9] -DIGITS {DIGIT}{DIGIT}* -INTEGER {DIGITS}[Ff]? - -STRING [[:alpha:]_-][[:alnum:]_-]* - -%x user_string - -%% - -%{ - // Code run each time yylex is called. - loc.step(); -%} - -#.*/\n ; // ignore comments - -[ \t]+ loc.step(); -\r loc.step(); -\n { - loc.lines(yyleng); - loc.step(); - } - -";" return MAKE(SEMICOLON); -":" return MAKE(COLON); -"(" return MAKE(L_BRACKET); -")" return MAKE(R_BRACKET); -"{" return MAKE(L_CURLY_BRACKET); -"}" return MAKE(R_CURLY_BRACKET); -"[" return MAKE(L_SQUARE_BRACKET); -"]" return MAKE(R_SQUARE_BRACKET); -"," return MAKE(COMMA); -"\." return MAKE(POINT); -"->" return MAKE(R_ARROW); -"=" return MAKE(EQUAL); -"\*" return MAKE(ASTERISK); - -IF { return MAKE(IF); } -ELSE { return MAKE(ELSE); } -"!" { return MAKE(NOT); } -"&" { return MAKE(AND); } -"|" { return MAKE(OR); } -"||" { return MAKE(OR); } -END { return MAKE(END); } -PROC { return MAKE(PROC); } -_PROC { return MAKE(_PROC); } - -{INTEGER} { return MAKE_VALUE(INTEGER, std::stoi(yytext)); } -{STRING} { return MAKE_VALUE(STRING, yytext); } - -\" { PUSH_STATE(user_string); return MAKE(QUOTE); } -\" { POP_STATE(); return MAKE(QUOTE); } -(?:[^"\\]|\\.)*/\" { - int n = 0; - char *p = yytext; - while ((p = strstr(p, "\n"))++ != 0) - n++; - if (n) - { - loc.lines(n); - loc.step(); - } - return MAKE_VALUE(STRING, yytext); -} - -. { /*driver.error(loc, "invalid character");*/ return MAKE(ERROR_SYMBOL); } -<> return MAKE(EOQ); - -%% diff --git a/src/script2txt/script2txt.yy b/src/script2txt/script2txt.yy deleted file mode 100644 index e34c75e..0000000 --- a/src/script2txt/script2txt.yy +++ /dev/null @@ -1,332 +0,0 @@ -%{ -/* - * AIM tm_converter - * Copyright (C) 2015 lzwdgc - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -%} - -//////////////////////////////////////// - -// general settings -%require "3.0" -//%debug -%start file -%locations -%verbose -//%no-lines -%define parse.error verbose - -//////////////////////////////////////// - -// c++ skeleton and options -%skeleton "lalr1.cc" -%define api.value.type variant -%define api.token.constructor // C++ style of handling variants -%define parse.assert // check C++ variant types -%code provides { #include } -%parse-param { MY_PARSER_DRIVER &driver } // param to yy::parser() constructor (the parsing context) - -%code requires // forward decl of C++ driver (our parser) in HPP -{ -#include - -#include -} - -%code provides -{ -struct MY_PARSER_DRIVER : MY_PARSER -{ - void setContext(Emitter &&ctx) { context = std::move(ctx); } - const Emitter &getContext() const { return context; } - - Emitter context; - std::set functions; -}; -} - -//////////////////////////////////////// - -// tokens and types -%token EOQ 0 "end of file" -%token ERROR_SYMBOL -%token L_BRACKET R_BRACKET COMMA QUOTE SEMICOLON COLON POINT - L_CURLY_BRACKET R_CURLY_BRACKET SHARP R_ARROW EQUAL - L_SQUARE_BRACKET R_SQUARE_BRACKET ASTERISK -%token IF ELSE NOT AND OR -%token END PROC _PROC - -%token STRING -%token INTEGER - -%type string integer number - object_variable object - variables variable - function_name procedure_begin - parameters parameter - conds cond condition_body - function_call - -%type condition condition_begin - statements statement - proc_statements proc_statement - procedure - global_statements global_statement - script - -//////////////////////////////////////// - -%% - -file: script EOQ - { driver.setContext(std::move($1)); } - ; - -script: global_statements - { $$ = std::move($1); } - ; - -global_statements: global_statement - { $$ = std::move($1); } - | global_statements global_statement - { - auto &ctx = $1; - ctx.addLine(); - ctx.addEmitter(std::move($2)); - $$ = std::move(ctx); - } - ; - -global_statement: function_call - { - Emitter ctx; - ctx.addLine($1); - $$ = std::move(ctx); - } - | condition - { $$ = std::move($1); } - | procedure - { $$ = std::move($1); } - | R_CURLY_BRACKET - { $$ = Emitter(); } - | END - { $$ = Emitter(); } - | ERROR_SYMBOL - { $$ = Emitter(); } - | POINT - { $$ = Emitter(); } - | STRING - { $$ = Emitter(); } - | R_BRACKET - { $$ = Emitter(); } - ; - -procedure: procedure_begin proc_statements END - { - Emitter ctx; - ctx.beginBlock($1); - ctx.addEmitter(std::move($2)); - ctx.endBlock(); - $$ = std::move(ctx); - } - | procedure_begin END - { - Emitter ctx; - ctx.beginBlock($1); - ctx.endBlock(); - $$ = std::move(ctx); - } - | procedure_begin L_CURLY_BRACKET statements R_CURLY_BRACKET - { - Emitter ctx; - ctx.beginBlock($1); - ctx.addEmitter(std::move($3)); - ctx.endBlock(); - $$ = std::move(ctx); - } - ; -procedure_begin: PROC function_name L_BRACKET R_BRACKET - { $$ = "PROC " + $2 + "()"; } - | PROC function_name - { $$ = "PROC " + $2 + "()"; } - ; - -proc_statements: proc_statement - { $$ = std::move($1); } - | proc_statements proc_statement - { - auto &ctx = $1; - ctx.addEmitter(std::move($2)); - $$ = std::move(ctx); - } - ; -proc_statement: function_call - { - Emitter ctx; - ctx.addLine($1); - $$ = std::move(ctx); - } - | _PROC function_call - { - Emitter ctx; - ctx.addLine("_PROC " + $2); - $$ = std::move(ctx); - } - | condition - { $$ = std::move($1); } - | COLON - { $$ = Emitter(); } - | R_BRACKET - { $$ = Emitter(); } - | ERROR_SYMBOL - { $$ = Emitter(); } - ; - -statements: statement - { $$ = std::move($1); } - | statements statement - { - auto &ctx = $1; - ctx.addEmitter(std::move($2)); - $$ = std::move(ctx); - } - ; -statement: proc_statement - { $$ = std::move($1); } - | END - { - Emitter ctx; - ctx.addLine("END"); - $$ = std::move(ctx); - } - ; - -function_call: function_name L_BRACKET parameters R_BRACKET - { $$ = $1 + "(" + $3 + ")"; driver.functions.insert($1); } - | function_name L_BRACKET parameters COMMA R_BRACKET - { $$ = $1 + "(" + $3 + ")"; driver.functions.insert($1); } - | function_name L_BRACKET R_BRACKET - { $$ = $1 + "()"; driver.functions.insert($1); } - ; -parameters: parameter - { $$ = $1; } - | parameters COMMA parameter - { $$ = $1 + ", " + $3; } - ; -parameter: object - { $$ = $1; } - | number - { $$ = $1; } - | object_variable - { $$ = $1; } - | ASTERISK - { $$ = "*"; } - ; - -condition: condition_begin - { $$ = std::move($1); } - | condition_begin ELSE L_CURLY_BRACKET statements R_CURLY_BRACKET - { - auto &ctx = $1; - ctx.beginBlock("else"); - ctx.addEmitter(std::move($4)); - ctx.endBlock(); - $$ = std::move(ctx); - } - ; -condition_begin: IF L_BRACKET condition_body R_BRACKET L_CURLY_BRACKET statements R_CURLY_BRACKET - { - Emitter ctx; - ctx.beginBlock("if (" + $3 + ")"); - ctx.addEmitter(std::move($6)); - ctx.endBlock(); - $$ = std::move(ctx); - } - | IF L_BRACKET condition_body L_CURLY_BRACKET statements R_CURLY_BRACKET - { - Emitter ctx; - ctx.beginBlock("if (" + $3 + ")"); - ctx.addEmitter(std::move($5)); - ctx.endBlock(); - $$ = std::move(ctx); - } - | IF L_BRACKET condition_body R_BRACKET L_CURLY_BRACKET R_CURLY_BRACKET - { - Emitter ctx; - ctx.beginBlock("if (" + $3 + ")"); - ctx.endBlock(); - $$ = std::move(ctx); - } - ; -condition_body: conds - { $$ = $1; } - ; -conds: cond - { $$ = $1; } - | conds AND cond - { $$ = $1 + " && " + $3; } - | conds OR cond - { $$ = $1 + " || " + $3; } - ; -cond: object - { $$ = $1; } - | object_variable - { $$ = $1; } - | function_call - { $$ = $1; } - | NOT cond - { $$ = "!" + $2; } - ; - -object_variable: object POINT variables - { $$ = $1 + "." + $3; } - ; -variables: /* empty */ - { $$ = ""; } - | variable - { $$ = $1; } - | variables POINT variable - { $$ = $1 + "." + $3; } - ; - -function_name: string - { $$ = $1; } - ; -object: string - { $$ = $1; } - ; -variable: string - { $$ = $1; } - | integer - { $$ = $1; } - ; - -number: integer POINT integer - { $$ = $1 + "." + $3; } - | integer - { $$ = $1; } - ; - -string: STRING - { $$ = $1; } - ; -integer: INTEGER - { $$ = std::to_string($1); } - ; - -%% diff --git a/src/script2txt2/script2txt2.cpp b/src/script2txt2/script2txt2.cpp deleted file mode 100644 index 0a1da84..0000000 --- a/src/script2txt2/script2txt2.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - * AIM script2txt2 (simpler version) - * Copyright (C) 2024 lzwdgc - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include -#include -#include - -#include - -int main(int argc, char *argv[]) { - cl::opt p(cl::Positional, cl::desc(""), cl::Required); - - cl::ParseCommandLineOptions(argc, argv); - - auto func = [](auto filename) { - primitives::templates2::mmap_file f{filename}; - stream s{f}; - script scr = s; - std::vector lines; - int sz{}; - for (int i = 0; i < scr.nlines; ++i) { - sz += lines.emplace_back((const char *)f.p + sizeof(script) + sz).size() + 1; - } - - // write script - { - filename += ".txt"; - if (std::ofstream ofile(filename, std::ios::binary); ofile) { - std::string indent, space = " "s; - auto inc = [&]() { - indent += space; - }; - auto dec = [&]() { - if (!indent.empty()) { - indent.resize(indent.size() - space.size()); - return true; - } - return false; - }; - int procs{}; - bool prev_newline{}; - for (auto &&l : lines) { - auto else_ = l == "ELSE"sv; - auto proc = l.starts_with("PROC"sv); - auto end = l == "END"sv; - auto lbrace = l == "{"sv; - auto rbrace = l == "}"sv; - - if (else_ && prev_newline) { - ofile.seekp(-1, std::ios::cur); - } - prev_newline = false; - - if (rbrace) { - if (!dec()) { - ofile << "// script2txt2 comment: unbalanced!\n"; - } - } - if (end && procs) { - if (!dec()) { - ofile << "// script2txt2 comment: unbalanced!\n"; - } - } - - ofile << indent << l << "\n"; - - if ((end || rbrace) && indent.empty()) { - ofile << "\n"; - prev_newline = true; - } - if (end && procs) { - procs = 0; - } - if (lbrace || proc) { - indent += space; - } - if (proc) { - procs = 1; - } - } - } - } - }; - - if (fs::is_regular_file(p)) { - func(p.string()); - } else if (fs::is_directory(p)) { - auto files = enumerate_files_like(p, ".*\\.scr", false); - auto files2 = enumerate_files_like(p, ".*\\.QST", false); - files.insert(files2.begin(), files2.end()); - for (auto &f : files) { - std::cout << "processing: " << f << "\n"; - func(f.string()); - } - } else { - throw std::runtime_error("Bad fs object"); - } - - return 0; -} diff --git a/sw.cpp b/sw.cpp index 9fa46fd..9ea02ac 100644 --- a/sw.cpp +++ b/sw.cpp @@ -49,7 +49,7 @@ void build(Solution &s) add_exe_with_common("mmp_extractor") += "org.sw.demo.intel.opencv.highgui"_dep; add_exe_with_common("mpj_loader"); add_exe_with_common("paker"); - add_exe_with_common("script2txt2"); + add_exe_with_common("script2txt"); add_exe_with_common("txt2script"); add_exe_with_common("tm_converter"); add_exe("name_generator"); @@ -60,15 +60,6 @@ void build(Solution &s) ; // not so simple targets - auto &script2txt = add_exe_with_common("script2txt"); - { - script2txt += ".*"_rr; - script2txt += "pub.lzwdgc.Polygon4.DataManager.schema-master"_dep; - gen_flex_bison_pair("org.sw.demo.lexxmark.winflexbison"_dep, script2txt, "LALR1_CPP_VARIANT_PARSER", "script2txt"); - if (script2txt.getCompilerType() == CompilerType::MSVC) - script2txt.CompileOptions.push_back("/Zc:__cplusplus"); - } - auto &model = tools.addStaticLibrary("model"); { model += cppstd;