mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-14 17:33:25 +00:00
Remove old script2txt.
This commit is contained in:
parent
98425912c2
commit
1caa842481
6 changed files with 70 additions and 737 deletions
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <buffer.h>
|
||||
#include <common.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
template <typename T>
|
||||
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<std::string>(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<uint8_t> raw_text;
|
||||
uint32_t line_start_pos_len; // always 800
|
||||
std::vector<uint32_t> line_start_pos;
|
||||
|
||||
//
|
||||
std::vector<std::string> 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;
|
||||
}
|
||||
};
|
||||
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "script.h"
|
||||
#include <mmap.h>
|
||||
#include <types.h>
|
||||
|
||||
#include <script2txt_parser.h>
|
||||
|
||||
#include <primitives/filesystem.h>
|
||||
#include <primitives/sw/main.h>
|
||||
#include <primitives/sw/settings.h>
|
||||
#include <primitives/sw/cl.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
|
||||
using std::cout;
|
||||
using std::string;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int main(int argc, char *argv[]) {
|
||||
cl::opt<path> p(cl::Positional, cl::desc("<script.scr or scripts dir>"), 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<uint8_t> f{filename};
|
||||
stream s{f};
|
||||
script scr = s;
|
||||
std::vector<std::string_view> 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <script2txt_parser.h>
|
||||
%}
|
||||
|
||||
%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); }
|
||||
<user_string>\" { POP_STATE(); return MAKE(QUOTE); }
|
||||
<user_string>(?:[^"\\]|\\.)*/\" {
|
||||
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); }
|
||||
<<EOF>> return MAKE(EOQ);
|
||||
|
||||
%%
|
||||
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <script2txt_parser.h>
|
||||
%}
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
// 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 <primitives/helper/bison_yy.h> }
|
||||
%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 <Polygon4/DataManager/Schema/Emitter.h>
|
||||
|
||||
#include <set>
|
||||
}
|
||||
|
||||
%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<std::string> 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 <std::string> STRING
|
||||
%token <int> INTEGER
|
||||
|
||||
%type <std::string> string integer number
|
||||
object_variable object
|
||||
variables variable
|
||||
function_name procedure_begin
|
||||
parameters parameter
|
||||
conds cond condition_body
|
||||
function_call
|
||||
|
||||
%type <Emitter> 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); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <mmap.h>
|
||||
#include <types.h>
|
||||
|
||||
#include <primitives/sw/main.h>
|
||||
#include <primitives/sw/settings.h>
|
||||
#include <primitives/sw/cl.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
cl::opt<path> p(cl::Positional, cl::desc("<script.scr or scripts dir>"), cl::Required);
|
||||
|
||||
cl::ParseCommandLineOptions(argc, argv);
|
||||
|
||||
auto func = [](auto filename) {
|
||||
primitives::templates2::mmap_file<uint8_t> f{filename};
|
||||
stream s{f};
|
||||
script scr = s;
|
||||
std::vector<std::string_view> 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;
|
||||
}
|
||||
11
sw.cpp
11
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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue