5
#include "../../SyntopiaCore/Exceptions/Exception.h"
6
#include "../../SyntopiaCore/Logging/Logging.h"
8
using namespace SyntopiaCore::Exceptions;
9
using namespace SyntopiaCore::Logging;
12
namespace StructureSynth {
15
Tokenizer::~Tokenizer() {
18
Tokenizer::Tokenizer(QString input) {
20
QStringList operators;
21
operators << "c" << "color" << "a" << "alpha" << "matrix" << "h" << "hue" << "sat" << "b" << "brightness" << "v" << "x" << "y" << "z" << "rx" << "ry" << "rz" << "s" << "fx" << "fy" << "fz" << "maxdepth" << "weight" << "md" << "w";
25
// We will split on whitespace and line breaks
26
// TODO: Respect quotations ( file = "C:\Program Files\Test" )
28
QVector<int> positions;
30
// We will use our own split routine
33
input += " "; // to ensure last symbol gets parsed.
34
bool inMultiComment = false;
35
bool inComment = false;
37
for (int i = 0; i < input.length(); i++) {
39
if (input.at(i) == '\r') {
44
// Check if we found a preprocessor comment (there must occur at the beginning of a line.
45
if (input.at(i) == '#' && ((i == 0) || (input.at(i-1) == '\r') || (input.at(i-1) == '\n'))) {
46
inComment = true; i++; continue;
50
if (i < input.length()-1) {
51
if (input.at(i) == '*' && input.at(i+1) == '/') {
52
inMultiComment = false; i++; continue;
55
if (input.at(i) == '/' && input.at(i+1) == '/') {
56
inComment = true; i++; continue;
59
if (input.at(i) == '/' && input.at(i+1) == '*') {
60
inMultiComment = true; i++; continue;
64
if (inMultiComment || inComment) continue;
66
if (input.at(i) == '[') {
67
while (input.at(i) != ']' && i < input.length()) {
68
current += input.at(i);
73
if (input.at(i) != ']') {
74
throw ParseError("No matching ']' found for '['", startPos);
78
positions.append(startPos-newlines);
82
if (input.at(i) == '{' || input.at(i) == '}' || input.at(i) == ' ' || (input.at(i) == '\r') || (input.at(i) == '\n')) {
83
QString trimmed = current.remove(QRegExp("\\s|\\r|\\n"));
84
if (!current.trimmed().isEmpty()) { l.append(trimmed); positions.append(startPos-newlines); }
85
if (input.at(i) == '{' || input.at(i) == '}') { l.append(QString(input.at(i))); positions.append(i-newlines); }
89
current += input.at(i);
93
for (int i = 0; i < l.size(); i++) {
95
int pos = positions[i];
96
QString sl = l[i].toLower();
99
symbols.append(Symbol(pos, Symbol::Rule, s));
100
} else if (sl == "{") {
101
symbols.append(Symbol(pos, Symbol::LeftBracket, s));
102
} else if (sl == ">") {
103
symbols.append(Symbol(pos, Symbol::MoreThan, s));
104
}else if (sl == "}") {
105
symbols.append(Symbol(pos, Symbol::RightBracket, s));
106
} else if (sl == "*") {
107
symbols.append(Symbol(pos, Symbol::Multiply, s));
108
} else if (sl == "set") {
109
symbols.append(Symbol(pos, Symbol::Set, s));
110
} else if (QString("+-0123456789").contains(s[0])) {
111
// It is a number (hopefully)
113
if (s.count("/") == 1) {
114
QString s1 = s.section("/",0,0);
115
QString s2 = s.section("/",1,1);
116
bool succes1 = false;
117
int i1 = s1.toInt(&succes1);
118
bool succes2 = false;
119
int i2 = s2.toInt(&succes2);
121
if ((i1 && i2) && (i2 != 0)) {
122
Symbol ns(pos, Symbol::Number, s);
123
ns.isInteger = false;
124
ns.floatValue = ((double)i1)/i2;
129
throw ParseError("Invalid fraction found: " + s, pos);
134
int i = s.toInt(&succes);
137
Symbol ns(pos, Symbol::Number, s);
144
// the number was not an integer... Is it a floating-point value?
146
double d = s.toDouble(&succes);
149
Symbol ns(pos, Symbol::Number, s);
150
ns.isInteger = false;
152
//INFO(QString("Added float value:%1").arg(ns.floatValue));
157
throw ParseError("Invalid symbol found: " + s, pos);
158
} else if (operators.contains(sl) ) {
159
QString longName = sl;
161
// Resolve abbreviations
162
if (longName == "md") longName = "maxdepth";
163
if (longName == "w") longName = "weight";
164
if (longName == "h") longName = "hue";
165
if (longName == "b") longName = "brightness";
166
if (longName == "a") longName = "alpha";
167
if (longName == "c") longName = "color";
170
Symbol ns(pos, Symbol::Operator, longName);
174
// TODO: We should check syntax of userstring here... (we dont want strings like slk"{/})
175
Symbol ns(pos, Symbol::UserString, sl);
182
for (int i = 0; i < symbols.size(); i++) {
184
//INFO(QString("%1. Symbol: %2, Position: %3").arg(i).arg(symbols[i].text).arg(positions[i]));
191
Symbol Tokenizer::getSymbol() {
194
if (currentSymbol < symbols.size()) {
195
return symbols[currentSymbol];
198
return Symbol(-1, Symbol::End, "#END#");