Generalize C struct parsing
This commit is contained in:
parent
85a5f07695
commit
ebdf22145d
3 changed files with 41 additions and 45 deletions
|
@ -69,6 +69,7 @@ public:
|
||||||
static QString removeLineComments(QString text, const QStringList &commentSymbols);
|
static QString removeLineComments(QString text, const QStringList &commentSymbols);
|
||||||
|
|
||||||
static QStringList splitShellCommand(QStringView command);
|
static QStringList splitShellCommand(QStringView command);
|
||||||
|
static QMap<QString, QMap<QString, QString>> readCStructs(const QString &filePath, const QHash<int, QString> memberMap = { });
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString root;
|
QString root;
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QStack>
|
#include <QStack>
|
||||||
|
|
||||||
|
#include "lib/fex/lexer.h"
|
||||||
|
#include "lib/fex/parser.h"
|
||||||
|
|
||||||
const QRegularExpression ParseUtil::re_incScriptLabel("\\b(?<label>[\\w_][\\w\\d_]*):{1,2}");
|
const QRegularExpression ParseUtil::re_incScriptLabel("\\b(?<label>[\\w_][\\w\\d_]*):{1,2}");
|
||||||
const QRegularExpression ParseUtil::re_globalIncScriptLabel("\\b(?<label>[\\w_][\\w\\d_]*)::");
|
const QRegularExpression ParseUtil::re_globalIncScriptLabel("\\b(?<label>[\\w_][\\w\\d_]*)::");
|
||||||
const QRegularExpression ParseUtil::re_poryScriptLabel("\\b(script)(\\((global|local)\\))?\\s*\\b(?<label>[\\w_][\\w\\d_]*)");
|
const QRegularExpression ParseUtil::re_poryScriptLabel("\\b(script)(\\((global|local)\\))?\\s*\\b(?<label>[\\w_][\\w\\d_]*)");
|
||||||
|
@ -375,6 +378,31 @@ QMap<QString, QString> ParseUtil::readNamedIndexCArray(const QString &filename,
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMap<QString, QMap<QString, QString>> ParseUtil::readCStructs(const QString &filePath, const QHash<int, QString> memberMap) {
|
||||||
|
auto cParser = fex::Parser();
|
||||||
|
auto tokens = fex::Lexer().LexFile(filePath.toStdString());
|
||||||
|
auto structs = cParser.ParseTopLevelObjects(tokens);
|
||||||
|
QMap<QString, QMap<QString, QString>> structMaps;
|
||||||
|
for (auto it = structs.begin(); it != structs.end(); it++) {
|
||||||
|
QMap<QString, QString> values;
|
||||||
|
int i = 0;
|
||||||
|
for (const fex::ArrayValue &v : it->second.values()) {
|
||||||
|
if (v.type() == fex::ArrayValue::Type::kValuePair) {
|
||||||
|
QString key = QString::fromStdString(v.pair().first);
|
||||||
|
QString value = QString::fromStdString(v.pair().second->string_value());
|
||||||
|
values.insert(key, value);
|
||||||
|
} else {
|
||||||
|
// For backwards compatibility with structs that don't specify member names.
|
||||||
|
if (memberMap.contains(i))
|
||||||
|
values.insert(memberMap.value(i), QString::fromStdString(v.string_value()));
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
structMaps.insert(QString::fromStdString(it->first), values);
|
||||||
|
}
|
||||||
|
return structMaps;
|
||||||
|
}
|
||||||
|
|
||||||
QList<QStringList> ParseUtil::getLabelMacros(const QList<QStringList> &list, const QString &label) {
|
QList<QStringList> ParseUtil::getLabelMacros(const QList<QStringList> &list, const QString &label) {
|
||||||
bool in_label = false;
|
bool in_label = false;
|
||||||
QList<QStringList> new_list;
|
QList<QStringList> new_list;
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
#include "orderedjson.h"
|
#include "orderedjson.h"
|
||||||
#include "lib/fex/lexer.h"
|
|
||||||
#include "lib/fex/parser.h"
|
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
@ -2481,7 +2479,18 @@ bool Project::readEventGraphics() {
|
||||||
qDeleteAll(eventGraphicsMap);
|
qDeleteAll(eventGraphicsMap);
|
||||||
eventGraphicsMap.clear();
|
eventGraphicsMap.clear();
|
||||||
QStringList gfxNames = gfxDefines.keys();
|
QStringList gfxNames = gfxDefines.keys();
|
||||||
QMap<QString, QMap<QString, QString>> gfxInfos = readObjEventGfxInfo();
|
|
||||||
|
// The positions of each of the required members for the gfx info struct.
|
||||||
|
// For backwards compatibility if the struct doesn't use initializers.
|
||||||
|
const auto gfxInfoMemberMap = QHash<int, QString>{
|
||||||
|
{8, "inanimate"},
|
||||||
|
{11, "oam"},
|
||||||
|
{12, "subspriteTables"},
|
||||||
|
{14, "images"},
|
||||||
|
};
|
||||||
|
|
||||||
|
QString filepath = root + "/" + projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx_info);
|
||||||
|
QMap<QString, QMap<QString, QString>> gfxInfos = ParseUtil::readCStructs(filepath, gfxInfoMemberMap);
|
||||||
for (QString gfxName : gfxNames) {
|
for (QString gfxName : gfxNames) {
|
||||||
EventGraphics * eventGraphics = new EventGraphics;
|
EventGraphics * eventGraphics = new EventGraphics;
|
||||||
|
|
||||||
|
@ -2529,48 +2538,6 @@ bool Project::readEventGraphics() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString, QMap<QString, QString>> Project::readObjEventGfxInfo() {
|
|
||||||
// TODO: refactor this to be more general if we end up directly parsing C
|
|
||||||
// for more use cases in the future.
|
|
||||||
auto cParser = fex::Parser();
|
|
||||||
auto tokens = fex::Lexer().LexFile((root + "/" + projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx_info)).toStdString());
|
|
||||||
auto gfxInfoObjects = cParser.ParseTopLevelObjects(tokens);
|
|
||||||
QMap<QString, QMap<QString, QString>> gfxInfos;
|
|
||||||
for (auto it = gfxInfoObjects.begin(); it != gfxInfoObjects.end(); it++) {
|
|
||||||
QMap<QString, QString> values;
|
|
||||||
int i = 0;
|
|
||||||
for (const fex::ArrayValue &v : it->second.values()) {
|
|
||||||
if (v.type() == fex::ArrayValue::Type::kValuePair) {
|
|
||||||
QString key = QString::fromStdString(v.pair().first);
|
|
||||||
QString value = QString::fromStdString(v.pair().second->string_value());
|
|
||||||
values.insert(key, value);
|
|
||||||
} else {
|
|
||||||
// This is for backwards compatibility with the old-style version of
|
|
||||||
// object_event_graphics_info.h, in which the structs didn't use
|
|
||||||
// attribute names to specify each struct member.
|
|
||||||
switch (i) {
|
|
||||||
case 8:
|
|
||||||
values.insert("inanimate", QString::fromStdString(v.string_value()));
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
values.insert("oam", QString::fromStdString(v.string_value()));
|
|
||||||
break;
|
|
||||||
case 12:
|
|
||||||
values.insert("subspriteTables", QString::fromStdString(v.string_value()));
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
values.insert("images", QString::fromStdString(v.string_value()));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
gfxInfos.insert(QString::fromStdString(it->first), values);
|
|
||||||
}
|
|
||||||
|
|
||||||
return gfxInfos;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Project::readSpeciesIconPaths() {
|
bool Project::readSpeciesIconPaths() {
|
||||||
speciesToIconPath.clear();
|
speciesToIconPath.clear();
|
||||||
QString srcfilename = projectConfig.getFilePath(ProjectFilePath::path_pokemon_icon_table);
|
QString srcfilename = projectConfig.getFilePath(ProjectFilePath::path_pokemon_icon_table);
|
||||||
|
|
Loading…
Reference in a new issue