mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-15 01:43: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
|
* AIM script2txt2 (simpler version)
|
||||||
* Copyright (C) 2015 lzwdgc
|
* Copyright (C) 2024 lzwdgc
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* 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/>.
|
* 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/main.h>
|
||||||
#include <primitives/sw/settings.h>
|
#include <primitives/sw/settings.h>
|
||||||
#include <primitives/sw/cl.h>
|
#include <primitives/sw/cl.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
using std::cout;
|
int main(int argc, char *argv[]) {
|
||||||
using std::string;
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
cl::opt<path> p(cl::Positional, cl::desc("<script.scr or scripts dir>"), cl::Required);
|
cl::opt<path> p(cl::Positional, cl::desc("<script.scr or scripts dir>"), cl::Required);
|
||||||
|
|
||||||
cl::ParseCommandLineOptions(argc, argv);
|
cl::ParseCommandLineOptions(argc, argv);
|
||||||
|
|
||||||
auto func = [](auto filename)
|
auto func = [](auto filename) {
|
||||||
{
|
primitives::templates2::mmap_file<uint8_t> f{filename};
|
||||||
// read
|
stream s{f};
|
||||||
buffer b(read_file(filename));
|
script scr = s;
|
||||||
script s;
|
std::vector<std::string_view> lines;
|
||||||
s.load(b);
|
int sz{};
|
||||||
auto str = s.get_text();
|
for (int i = 0; i < scr.nlines; ++i) {
|
||||||
|
sz += lines.emplace_back((const char *)f.p + sizeof(script) + sz).size() + 1;
|
||||||
Script2txtParserDriver driver;
|
|
||||||
if (driver.parse(str))
|
|
||||||
{
|
|
||||||
throw std::runtime_error("error during parsing input file");
|
|
||||||
}
|
}
|
||||||
auto &ctx = driver.getContext();
|
|
||||||
|
|
||||||
// write script
|
// write script
|
||||||
{
|
{
|
||||||
filename += ".txt";
|
filename += ".txt";
|
||||||
std::ofstream ofile(filename);
|
if (std::ofstream ofile(filename, std::ios::binary); ofile) {
|
||||||
if (ofile)
|
std::string indent, space = " "s;
|
||||||
ofile << ctx.getText();
|
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";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write function calls
|
ofile << indent << l << "\n";
|
||||||
{
|
|
||||||
std::ofstream functions("functions.txt", std::ios::app);
|
if ((end || rbrace) && indent.empty()) {
|
||||||
if (functions)
|
ofile << "\n";
|
||||||
{
|
prev_newline = true;
|
||||||
for (auto &f : driver.functions)
|
}
|
||||||
{
|
if (end && procs) {
|
||||||
std::string f2(f.size(), 0);
|
procs = 0;
|
||||||
std::transform(f.begin(), f.end(), f2.begin(), tolower);
|
}
|
||||||
functions << f2 << "\n";
|
if (lbrace || proc) {
|
||||||
|
indent += space;
|
||||||
|
}
|
||||||
|
if (proc) {
|
||||||
|
procs = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (fs::is_regular_file(p))
|
if (fs::is_regular_file(p)) {
|
||||||
func(p.string());
|
func(p.string());
|
||||||
else if (fs::is_directory(p))
|
} else if (fs::is_directory(p)) {
|
||||||
{
|
|
||||||
auto files = enumerate_files_like(p, ".*\\.scr", false);
|
auto files = enumerate_files_like(p, ".*\\.scr", false);
|
||||||
auto files2 = enumerate_files_like(p, ".*\\.QST", false);
|
auto files2 = enumerate_files_like(p, ".*\\.QST", false);
|
||||||
files.insert(files2.begin(), files2.end());
|
files.insert(files2.begin(), files2.end());
|
||||||
for (auto &f : files)
|
for (auto &f : files) {
|
||||||
{
|
|
||||||
std::cout << "processing: " << f << "\n";
|
std::cout << "processing: " << f << "\n";
|
||||||
func(f.string());
|
func(f.string());
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
throw std::runtime_error("Bad fs object");
|
throw std::runtime_error("Bad fs object");
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
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("mmp_extractor") += "org.sw.demo.intel.opencv.highgui"_dep;
|
||||||
add_exe_with_common("mpj_loader");
|
add_exe_with_common("mpj_loader");
|
||||||
add_exe_with_common("paker");
|
add_exe_with_common("paker");
|
||||||
add_exe_with_common("script2txt2");
|
add_exe_with_common("script2txt");
|
||||||
add_exe_with_common("txt2script");
|
add_exe_with_common("txt2script");
|
||||||
add_exe_with_common("tm_converter");
|
add_exe_with_common("tm_converter");
|
||||||
add_exe("name_generator");
|
add_exe("name_generator");
|
||||||
|
|
@ -60,15 +60,6 @@ void build(Solution &s)
|
||||||
;
|
;
|
||||||
|
|
||||||
// not so simple targets
|
// 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");
|
auto &model = tools.addStaticLibrary("model");
|
||||||
{
|
{
|
||||||
model += cppstd;
|
model += cppstd;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue