2020-09-13 23:37:55 +01:00
|
|
|
#pragma once
|
2018-09-25 01:04:42 +01:00
|
|
|
#ifndef PARSEUTIL_H
|
|
|
|
#define PARSEUTIL_H
|
|
|
|
|
2018-09-25 01:12:29 +01:00
|
|
|
#include "heallocation.h"
|
2019-05-05 21:11:00 +01:00
|
|
|
#include "log.h"
|
2022-07-19 22:56:12 +01:00
|
|
|
#include "orderedjson.h"
|
2018-09-25 01:04:42 +01:00
|
|
|
|
|
|
|
#include <QString>
|
|
|
|
#include <QList>
|
|
|
|
#include <QMap>
|
2019-05-06 17:42:09 +01:00
|
|
|
#include <QRegularExpression>
|
2018-09-25 01:04:42 +01:00
|
|
|
|
2023-01-17 00:44:09 +00:00
|
|
|
|
|
|
|
|
2019-09-21 22:06:04 +01:00
|
|
|
enum TokenClass {
|
2018-09-25 01:04:42 +01:00
|
|
|
Number,
|
|
|
|
Operator,
|
2019-05-05 21:11:00 +01:00
|
|
|
Error,
|
|
|
|
};
|
|
|
|
|
2018-09-25 01:04:42 +01:00
|
|
|
class Token {
|
|
|
|
public:
|
|
|
|
Token(QString value = "", QString type = "") {
|
|
|
|
this->value = value;
|
2019-09-21 22:06:04 +01:00
|
|
|
this->type = TokenClass::Operator;
|
2018-09-25 01:04:42 +01:00
|
|
|
if (type == "decimal" || type == "hex") {
|
2019-09-21 22:06:04 +01:00
|
|
|
this->type = TokenClass::Number;
|
2018-09-25 01:04:42 +01:00
|
|
|
this->operatorPrecedence = -1;
|
|
|
|
} else if (type == "operator") {
|
|
|
|
this->operatorPrecedence = precedenceMap[value];
|
2019-05-05 21:11:00 +01:00
|
|
|
} else if (type == "error") {
|
2019-09-21 22:06:04 +01:00
|
|
|
this->type = TokenClass::Error;
|
2018-09-25 01:04:42 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
static QMap<QString, int> precedenceMap;
|
|
|
|
QString value;
|
2019-09-21 22:06:04 +01:00
|
|
|
TokenClass type;
|
2018-09-25 01:04:42 +01:00
|
|
|
int operatorPrecedence; // only relevant for operator tokens
|
|
|
|
};
|
|
|
|
|
|
|
|
class ParseUtil
|
|
|
|
{
|
|
|
|
public:
|
2023-01-12 00:50:38 +00:00
|
|
|
ParseUtil();
|
2021-02-16 12:15:47 +00:00
|
|
|
void set_root(const QString &dir);
|
|
|
|
static QString readTextFile(const QString &path);
|
2023-01-17 00:44:09 +00:00
|
|
|
void invalidateTextFile(const QString &path);
|
2021-02-03 15:24:59 +00:00
|
|
|
static int textFileLineCount(const QString &path);
|
2021-02-16 11:15:54 +00:00
|
|
|
QList<QStringList> parseAsm(const QString &filename);
|
2023-01-17 06:17:24 +00:00
|
|
|
QStringList readCArray(const QString &filename, const QString &label);
|
|
|
|
QMap<QString, QStringList> readCArrayMulti(const QString &filename);
|
2021-02-16 12:15:47 +00:00
|
|
|
QMap<QString, QString> readNamedIndexCArray(const QString &text, const QString &label);
|
|
|
|
QString readCIncbin(const QString &text, const QString &label);
|
2023-01-17 06:17:24 +00:00
|
|
|
QMap<QString, QString> readCIncbinMulti(const QString &filepath);
|
2022-10-07 16:47:05 +01:00
|
|
|
QStringList readCIncbinArray(const QString &filename, const QString &label);
|
2023-12-18 07:19:12 +00:00
|
|
|
QMap<QString, int> readCDefinesByPrefix(const QString &filename, QStringList prefixes);
|
|
|
|
QMap<QString, int> readCDefinesByName(const QString &filename, QStringList names);
|
2023-12-11 21:40:40 +00:00
|
|
|
QStringList readCDefineNames(const QString&, const QStringList&);
|
2022-10-08 18:51:48 +01:00
|
|
|
QMap<QString, QHash<QString, QString>> readCStructs(const QString &, const QString & = "", const QHash<int, QString> = { });
|
2021-02-16 12:15:47 +00:00
|
|
|
QList<QStringList> getLabelMacros(const QList<QStringList>&, const QString&);
|
|
|
|
QStringList getLabelValues(const QList<QStringList>&, const QString&);
|
|
|
|
bool tryParseJsonFile(QJsonDocument *out, const QString &filepath);
|
2021-08-13 00:19:21 +01:00
|
|
|
bool tryParseOrderedJsonFile(poryjson::Json::object *out, const QString &filepath);
|
2021-02-16 12:15:47 +00:00
|
|
|
bool ensureFieldsExist(const QJsonObject &obj, const QList<QString> &fields);
|
2019-05-06 17:42:09 +01:00
|
|
|
|
2020-11-22 06:04:46 +00:00
|
|
|
// Returns the 1-indexed line number for the definition of scriptLabel in the scripts file at filePath.
|
|
|
|
// Returns 0 if a definition for scriptLabel cannot be found.
|
2020-11-26 11:09:58 +00:00
|
|
|
static int getScriptLineNumber(const QString &filePath, const QString &scriptLabel);
|
|
|
|
static int getRawScriptLineNumber(QString text, const QString &scriptLabel);
|
|
|
|
static int getPoryScriptLineNumber(QString text, const QString &scriptLabel);
|
2021-01-30 03:05:08 +00:00
|
|
|
static QStringList getGlobalScriptLabels(const QString &filePath);
|
|
|
|
static QStringList getGlobalRawScriptLabels(QString text);
|
|
|
|
static QStringList getGlobalPoryScriptLabels(QString text);
|
2021-02-16 12:15:47 +00:00
|
|
|
static QString removeStringLiterals(QString text);
|
|
|
|
static QString removeLineComments(QString text, const QString &commentSymbol);
|
|
|
|
static QString removeLineComments(QString text, const QStringList &commentSymbols);
|
2020-11-22 06:04:46 +00:00
|
|
|
|
2020-12-13 09:00:00 +00:00
|
|
|
static QStringList splitShellCommand(QStringView command);
|
2022-10-14 23:55:18 +01:00
|
|
|
static int gameStringToInt(QString gameString, bool * ok = nullptr);
|
2022-10-08 23:05:11 +01:00
|
|
|
static bool gameStringToBool(QString gameString, bool * ok = nullptr);
|
2022-10-14 23:55:18 +01:00
|
|
|
static QString jsonToQString(QJsonValue value, bool * ok = nullptr);
|
|
|
|
static int jsonToInt(QJsonValue value, bool * ok = nullptr);
|
|
|
|
static bool jsonToBool(QJsonValue value, bool * ok = nullptr);
|
2020-12-13 09:00:00 +00:00
|
|
|
|
2018-09-25 01:04:42 +01:00
|
|
|
private:
|
2019-05-06 17:42:09 +01:00
|
|
|
QString root;
|
|
|
|
QString text;
|
|
|
|
QString file;
|
2022-09-26 05:36:42 +01:00
|
|
|
QString curDefine;
|
2022-09-27 20:21:31 +01:00
|
|
|
QHash<QString, QStringList> errorMap;
|
2023-12-18 00:03:58 +00:00
|
|
|
int evaluateDefine(const QString&, const QString &, QMap<QString, int>*, QMap<QString, QString>*);
|
|
|
|
QList<Token> tokenizeExpression(QString, QMap<QString, int>*, QMap<QString, QString>*);
|
2021-02-16 12:15:47 +00:00
|
|
|
QList<Token> generatePostfix(const QList<Token> &tokens);
|
|
|
|
int evaluatePostfix(const QList<Token> &postfix);
|
2022-09-26 05:36:42 +01:00
|
|
|
void recordError(const QString &message);
|
|
|
|
void recordErrors(const QStringList &errors);
|
|
|
|
void logRecordedErrors();
|
|
|
|
QString createErrorMessage(const QString &message, const QString &expression);
|
2023-12-18 00:03:58 +00:00
|
|
|
QString readCDefinesFile(const QString &filename);
|
|
|
|
QMap<QString, int> readCDefines(const QString &filename, const QStringList &searchText, bool fullMatch);
|
2021-01-30 03:05:08 +00:00
|
|
|
|
|
|
|
static const QRegularExpression re_incScriptLabel;
|
|
|
|
static const QRegularExpression re_globalIncScriptLabel;
|
|
|
|
static const QRegularExpression re_poryScriptLabel;
|
|
|
|
static const QRegularExpression re_globalPoryScriptLabel;
|
|
|
|
static const QRegularExpression re_poryRawSection;
|
2018-09-25 01:04:42 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // PARSEUTIL_H
|