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 QStringList splitShellCommand(QStringView command);
|
||||
static QMap<QString, QMap<QString, QString>> readCStructs(const QString &filePath, const QHash<int, QString> memberMap = { });
|
||||
|
||||
private:
|
||||
QString root;
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
#include <QJsonObject>
|
||||
#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_globalIncScriptLabel("\\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;
|
||||
}
|
||||
|
||||
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) {
|
||||
bool in_label = false;
|
||||
QList<QStringList> new_list;
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#include "map.h"
|
||||
|
||||
#include "orderedjson.h"
|
||||
#include "lib/fex/lexer.h"
|
||||
#include "lib/fex/parser.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QJsonArray>
|
||||
|
@ -2481,7 +2479,18 @@ bool Project::readEventGraphics() {
|
|||
qDeleteAll(eventGraphicsMap);
|
||||
eventGraphicsMap.clear();
|
||||
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) {
|
||||
EventGraphics * eventGraphics = new EventGraphics;
|
||||
|
||||
|
@ -2529,48 +2538,6 @@ bool Project::readEventGraphics() {
|
|||
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() {
|
||||
speciesToIconPath.clear();
|
||||
QString srcfilename = projectConfig.getFilePath(ProjectFilePath::path_pokemon_icon_table);
|
||||
|
|
Loading…
Reference in a new issue