1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
#include "Preprocessor.h"
#include <QStringList>
#include <QRegExp>
#include <QMap>
#include "../../SyntopiaCore/Exceptions/Exception.h"
#include "../../SyntopiaCore/Logging/Logging.h"
using namespace SyntopiaCore::Exceptions;
using namespace SyntopiaCore::Logging;
namespace StructureSynth {
namespace Parser {
QString Preprocessor::Process(QString input) {
QStringList in = input.split(QRegExp("\r\n|\r|\n"));
QMap<QString, QString> substitutions;
QRegExp ppCommand("^#"); // Look for #define varname value
QRegExp defineCommand("^#define\\s([^\\s]+)\\s(.*)*$"); // Look for #define varname value
QRegExp defineCommandWithGUI("^#define\\s([^\\s]+)\\s(.*)\\s\\(float:([^\\s]*)\\)$"); // Look for #define varname value
for (QStringList::iterator it = in.begin(); it != in.end(); ++it) {
if (ppCommand.indexIn(*it) != -1) {
// Preprocessor command
if (defineCommandWithGUI.indexIn(*it) != -1) {
//INFO(QString("Found ppC (%1)->(%2): ").arg(defineCommandWithGUI.cap(1)).arg(defineCommandWithGUI.cap(2)) + *it);
if (defineCommandWithGUI.cap(2).contains(defineCommandWithGUI.cap(1))) {
WARNING(QString("#define command is recursive - skipped: %1 -> %2")
.arg(defineCommandWithGUI.cap(1))
.arg(defineCommandWithGUI.cap(2)));
}
//substitutions[defineCommandWithGUI.cap(1)] = defineCommandWithGUI.cap(2);
QString defaultValue = defineCommandWithGUI.cap(2);
QString floatInterval = defineCommandWithGUI.cap(3);
QStringList fi = floatInterval.split("-");
if (fi.count() != 2) {
WARNING("Could not understand #define gui command: " + floatInterval);
continue;
}
bool succes = false;
double d1 = fi[0].toDouble(&succes);
bool succes2 = false;
double d2 = fi[1].toDouble(&succes2);
if (!succes || !succes2) {
WARNING("Could not parse float interval in #define gui command: " + floatInterval);
continue;
}
bool succes3 = false;
double d3 = defineCommandWithGUI.cap(2).toDouble(&succes3);
if (!succes3) {
WARNING("Could not parse default argumentin #define gui command: " + defineCommandWithGUI.cap(2));
continue;
}
FloatParameter* fp= new FloatParameter(defineCommandWithGUI.cap(1), d1, d2, d3);
//INFO(QString("Float: %1, %2").arg(d1).arg(d2));
params.append(fp);
} else if (defineCommand.indexIn(*it) != -1) {
//INFO(QString("Found ppC (%1)->(%2): ").arg(defineCommand.cap(1)).arg(defineCommand.cap(2)) + *it);
if (defineCommand.cap(2).contains(defineCommand.cap(1))) {
WARNING(QString("#define command is recursive - skipped: %1 -> %2")
.arg(defineCommand.cap(1))
.arg(defineCommand.cap(2)));
}
substitutions[defineCommand.cap(1)] = defineCommand.cap(2);
} else {
WARNING("Could not understand preprocessor command: " + *it);
}
} else {
// Non-preprocessor command
// Check for substitutions.
QMap<QString, QString>::const_iterator it2 = substitutions.constBegin();
int subst = 0;
while (it2 != substitutions.constEnd()) {
if (subst>100) {
WARNING("More than 100 recursive preprocessor substitutions... breaking.");
break;
}
if ((*it).contains(it2.key())) {
INFO("Replacing: " + it2.key() + " with " + it2.value());
(*it).replace(it2.key(), it2.value());
it2 = substitutions.constBegin();
subst++;
} else {
it2++;
}
}
}
}
QStringList out = in;
return out.join("\r\n");
}
}
}
|