~ubuntu-branches/ubuntu/oneiric/structure-synth/oneiric

« back to all changes in this revision

Viewing changes to StructureSynth/Parser/Tokenizer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Miriam Ruiz
  • Date: 2009-04-13 13:28:45 UTC
  • Revision ID: james.westby@ubuntu.com-20090413132845-d7d42t4llxjxq0ez
Tags: upstream-0.9
ImportĀ upstreamĀ versionĀ 0.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "Tokenizer.h"
 
2
 
 
3
#include <QStringList>
 
4
 
 
5
#include "../../SyntopiaCore/Exceptions/Exception.h"
 
6
#include "../../SyntopiaCore/Logging/Logging.h"
 
7
 
 
8
using namespace SyntopiaCore::Exceptions;
 
9
using namespace SyntopiaCore::Logging;
 
10
 
 
11
 
 
12
namespace StructureSynth {
 
13
        namespace Parser {      
 
14
 
 
15
                Tokenizer::~Tokenizer() {
 
16
                }
 
17
 
 
18
                Tokenizer::Tokenizer(QString input) {
 
19
 
 
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";
 
22
 
 
23
                        currentSymbol = -1;
 
24
 
 
25
                        // We will split on whitespace and line breaks
 
26
                        // TODO: Respect quotations ( file = "C:\Program Files\Test" )
 
27
                        QStringList l;
 
28
                        QVector<int> positions;
 
29
 
 
30
                        // We will use our own split routine
 
31
                        QString current;
 
32
                        int startPos = 0;
 
33
                        input += " "; // to ensure last symbol gets parsed.
 
34
                        bool inMultiComment = false;
 
35
                        bool inComment = false;
 
36
                        int newlines = 0;
 
37
                        for (int i = 0; i < input.length(); i++) {
 
38
                                
 
39
                                if (input.at(i) == '\r') {
 
40
                                        inComment = false;
 
41
                                    newlines++;
 
42
                            }
 
43
 
 
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;
 
47
                                }
 
48
 
 
49
 
 
50
                                if (i < input.length()-1) {
 
51
                                        if (input.at(i) == '*' && input.at(i+1) == '/') {
 
52
                                                inMultiComment = false; i++; continue;
 
53
                                        }
 
54
 
 
55
                                        if (input.at(i) == '/' && input.at(i+1) == '/') {
 
56
                                                inComment = true; i++; continue;
 
57
                                        }
 
58
 
 
59
                                        if (input.at(i) == '/' && input.at(i+1) == '*') {
 
60
                                                inMultiComment = true; i++; continue;
 
61
                                        }
 
62
                                }
 
63
 
 
64
                                if (inMultiComment || inComment) continue;
 
65
 
 
66
                                if (input.at(i) == '[') {
 
67
                                        while (input.at(i) != ']' && i < input.length()) {
 
68
                                                current += input.at(i);
 
69
                                                i++;
 
70
                                        }
 
71
                                        current += ']';
 
72
 
 
73
                                        if (input.at(i) != ']') {
 
74
                                                throw ParseError("No matching ']' found for '['", startPos);
 
75
                                        }
 
76
 
 
77
                                        l.append(current);
 
78
                                        positions.append(startPos-newlines);
 
79
                                        startPos = i;
 
80
                                        current = "";
 
81
                                } else 
 
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);   }
 
86
                                        current = "";
 
87
                                        startPos = i;
 
88
                                } else {
 
89
                                        current += input.at(i);
 
90
                                }
 
91
                        }
 
92
                
 
93
                        for (int i = 0; i < l.size(); i++) {
 
94
                                QString s = l[i];
 
95
                                int pos = positions[i];
 
96
                                QString sl = l[i].toLower();
 
97
 
 
98
                                if (sl == "rule") {
 
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)
 
112
 
 
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);
 
120
 
 
121
                                                if ((i1 && i2) && (i2 != 0)) {
 
122
                                                        Symbol ns(pos, Symbol::Number, s);
 
123
                                                        ns.isInteger = false;
 
124
                                                        ns.floatValue = ((double)i1)/i2;
 
125
                                                        symbols.append(ns);
 
126
                                                        continue;
 
127
 
 
128
                                                } else {
 
129
                                                        throw ParseError("Invalid fraction found: " + s, pos);
 
130
                                                }
 
131
                                        }
 
132
 
 
133
                                        bool succes = false;
 
134
                                        int i = s.toInt(&succes);
 
135
 
 
136
                                        if (succes) {
 
137
                                                Symbol ns(pos, Symbol::Number, s);
 
138
                                                ns.isInteger = true;
 
139
                                                ns.intValue = i;
 
140
                                                symbols.append(ns);
 
141
                                                continue;
 
142
                                        }
 
143
 
 
144
                                        // the number was not an integer... Is it a floating-point value?
 
145
 
 
146
                                        double d = s.toDouble(&succes);
 
147
 
 
148
                                        if (succes) {
 
149
                                                Symbol ns(pos, Symbol::Number, s);
 
150
                                                ns.isInteger = false;
 
151
                                                ns.floatValue = d;
 
152
                                                //INFO(QString("Added float value:%1").arg(ns.floatValue));
 
153
                                                symbols.append(ns);
 
154
                                                continue;
 
155
                                        }
 
156
 
 
157
                                        throw ParseError("Invalid symbol found: " + s, pos);
 
158
                                } else if (operators.contains(sl) ) {
 
159
                                        QString longName = sl;
 
160
                                        
 
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";
 
168
                                        
 
169
                                        
 
170
                                        Symbol ns(pos, Symbol::Operator, longName);
 
171
                                        symbols.append(ns);
 
172
 
 
173
                                } else {
 
174
                                        // TODO: We should check syntax of userstring here... (we dont want strings like slk"{/})
 
175
                                        Symbol ns(pos, Symbol::UserString, sl);
 
176
                                        symbols.append(ns);
 
177
                                }
 
178
                        }
 
179
 
 
180
 
 
181
 
 
182
                        for (int i = 0; i < symbols.size(); i++) {
 
183
 
 
184
                                //INFO(QString("%1. Symbol: %2, Position: %3").arg(i).arg(symbols[i].text).arg(positions[i]));
 
185
                        }
 
186
 
 
187
 
 
188
 
 
189
                }
 
190
 
 
191
                Symbol Tokenizer::getSymbol() {
 
192
                        currentSymbol++;
 
193
 
 
194
                        if (currentSymbol < symbols.size()) {
 
195
                                return symbols[currentSymbol];
 
196
                        }       
 
197
 
 
198
                        return Symbol(-1, Symbol::End, "#END#");
 
199
                }
 
200
        }
 
201
}
 
202