~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to tools/porting/src/rpp.h

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2004-2005 Trolltech AS. All rights reserved.
 
4
** Copyright (C) 2001-2004 Roberto Raggi
 
5
**
 
6
** This file is part of the porting application of the Qt Toolkit.
 
7
**
 
8
** This file may be distributed under the terms of the Q Public License
 
9
** as defined by Trolltech AS of Norway and appearing in the file
 
10
** LICENSE.QPL included in the packaging of this file.
 
11
**
 
12
** This file may be distributed and/or modified under the terms of the
 
13
** GNU General Public License version 2 as published by the Free Software
 
14
** Foundation and appearing in the file LICENSE.GPL included in the
 
15
** packaging of this file.
 
16
**
 
17
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
18
**   information about Qt Commercial License Agreements.
 
19
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
20
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
21
**
 
22
** Contact info@trolltech.com if any conditions of this licensing are
 
23
** not clear to you.
 
24
**
 
25
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
26
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
27
**
 
28
****************************************************************************/
 
29
#ifndef RPP_H
 
30
#define RPP_H
 
31
 
 
32
#include <iostream>
 
33
#include <cctype>
 
34
#include <QHash>
 
35
#include <QStringList>
 
36
#include <QFile>
 
37
#include <QByteArray>
 
38
#include <QDir>
 
39
#include <QMultiMap>
 
40
#include "tokenengine.h"
 
41
#include "rpplexer.h"
 
42
#include "tokens.h"
 
43
#include "smallobject.h"
 
44
 
 
45
using std::cout;
 
46
using std::endl;
 
47
namespace Rpp
 
48
{
 
49
 
 
50
struct Item;
 
51
struct ItemComposite;
 
52
 
 
53
struct Source;
 
54
 
 
55
struct Directive;
 
56
struct EmptyDirective;
 
57
struct ErrorDirective;
 
58
struct PragmaDirective;
 
59
struct IncludeDirective;
 
60
struct ConditionalDirective;
 
61
struct DefineDirective;
 
62
struct UndefDirective;
 
63
struct LineDirective;
 
64
struct NonDirective;
 
65
 
 
66
struct IfSection;
 
67
struct IfLikeDirective;
 
68
struct IfDirective;
 
69
struct ElifDirective;
 
70
struct IfdefLikeDirective;
 
71
struct IfdefDirective;
 
72
struct IfndefDirective;
 
73
struct ElseDirective;
 
74
struct EndifDirective;
 
75
 
 
76
struct Text;
 
77
struct Token;
 
78
struct TokenComposite;
 
79
struct IdToken;
 
80
struct NonIdToken;
 
81
struct PastingToken;
 
82
struct LineComment;
 
83
struct MultiLineComment;
 
84
struct WhiteSpace;
 
85
 
 
86
struct MacroDefinition;
 
87
struct MacroFunctionDefinition;
 
88
struct MacroParameters;
 
89
struct MacroParameter;
 
90
 
 
91
struct Expression;
 
92
struct UnaryExpression;
 
93
struct BinaryExpression;
 
94
struct ConditionalExpression;
 
95
 
 
96
struct StringLiteral;
 
97
struct IntLiteral;
 
98
struct MacroReference;
 
99
struct MacroFunctionReference;
 
100
struct MacroArguments;
 
101
struct MacroArgument;
 
102
 
 
103
struct Item
 
104
{
 
105
    virtual ~Item() {}
 
106
 
 
107
    virtual Item *parent() const = 0;
 
108
 
 
109
    virtual ItemComposite *toItemComposite() const
 
110
    { return 0; }
 
111
 
 
112
    virtual Item *toItem() const
 
113
    { return const_cast<Item *>(this); }
 
114
 
 
115
    virtual Directive *toDirective() const
 
116
    { return 0; }
 
117
 
 
118
    virtual Text *toText() const
 
119
    { return 0; }
 
120
 
 
121
    virtual Token *toToken() const
 
122
    { return 0; }
 
123
 
 
124
    virtual Source *toSource() const
 
125
    { return 0; }
 
126
 
 
127
    virtual Expression *toExpression() const
 
128
    { return 0; }
 
129
 
 
130
    virtual IfSection *toIfSection() const
 
131
    { return 0; }
 
132
 
 
133
    // Text returns the original text for an item, e.g.
 
134
    // the way it is found in the source
 
135
    virtual TokenEngine::TokenSection text() const
 
136
     { return TokenEngine::TokenSection(); }
 
137
 
 
138
protected:
 
139
    //using the defualt constructor for an item is
 
140
    //only allowded for subclasses.
 
141
    Item() {};
 
142
};
 
143
 
 
144
struct ItemComposite
 
145
{
 
146
    virtual ~ItemComposite() {}
 
147
    virtual int count() const = 0;
 
148
    virtual Item *item(int index) const = 0;
 
149
    virtual void add(Item *item) = 0;
 
150
/*
 
151
    Classes that inherit ItemComposite must implement this
 
152
    function themselves
 
153
    virtual ItemComposite *toItemComposite() const
 
154
    { return const_cast<ItemComposite *>(this); }
 
155
*/
 
156
};
 
157
 
 
158
struct Directive: public Item
 
159
{
 
160
    inline Directive(Item *parent = 0)
 
161
        : m_parent(parent), m_numLines(0) {}
 
162
 
 
163
    virtual Item *parent() const
 
164
    { return m_parent; }
 
165
 
 
166
    inline void setParent(Item *parent)
 
167
    { m_parent = parent;}
 
168
 
 
169
    void setNumLines(const int numLines)
 
170
    {m_numLines = numLines;}
 
171
 
 
172
    virtual Directive *toDirective() const
 
173
    { return const_cast<Directive *>(this); }
 
174
 
 
175
    virtual EmptyDirective *toEmptyDirective() const
 
176
    { return 0; }
 
177
 
 
178
    virtual ErrorDirective *toErrorDirective() const
 
179
    { return 0; }
 
180
 
 
181
    virtual PragmaDirective *toPragmaDirective() const
 
182
    { return 0; }
 
183
 
 
184
    virtual IncludeDirective *toIncludeDirective() const
 
185
    { return 0; }
 
186
 
 
187
    virtual ConditionalDirective *toConditionalDirective() const
 
188
    { return 0; }
 
189
 
 
190
    virtual DefineDirective *toDefineDirective() const
 
191
    { return 0; }
 
192
 
 
193
    virtual UndefDirective *toUndefDirective() const
 
194
    { return 0; }
 
195
 
 
196
    virtual LineDirective *toLineDirective() const
 
197
    { return 0; }
 
198
 
 
199
    virtual NonDirective *toNonDirective() const
 
200
    { return 0; }
 
201
 
 
202
    void setTokenSection(TokenEngine::TokenSection section)
 
203
    { m_tokenSection = section; }
 
204
 
 
205
    TokenEngine::TokenSection text() const
 
206
    { return m_tokenSection; }
 
207
 
 
208
protected:
 
209
    Item *m_parent;
 
210
    int m_numLines;
 
211
    TokenEngine::TokenSection m_tokenSection;
 
212
};
 
213
 
 
214
 
 
215
struct Token: public Item
 
216
{
 
217
    inline Token(Item *parent = 0)
 
218
        : m_parent(parent) {}
 
219
 
 
220
    virtual Item *parent() const
 
221
    { return m_parent; }
 
222
 
 
223
    virtual MacroArguments *toMacroArguments() const
 
224
    { return 0; }
 
225
 
 
226
    virtual IdToken *toIdToken() const
 
227
    { return 0; }
 
228
 
 
229
    virtual NonIdToken *toNonIdToken() const
 
230
    { return 0; }
 
231
 
 
232
    virtual LineComment *toLineComment() const
 
233
    { return 0; }
 
234
 
 
235
    virtual MultiLineComment *toMultiLineComment() const
 
236
    { return 0; }
 
237
 
 
238
    virtual WhiteSpace *toWhiteSpace() const
 
239
    { return 0; }
 
240
 
 
241
    virtual Token *toToken() const
 
242
    { return const_cast<Token *>(this); }
 
243
 
 
244
    void setToken(int tokenIndex)
 
245
    { m_tokenIndex = tokenIndex;}
 
246
 
 
247
    int index() const
 
248
    { return m_tokenIndex; }
 
249
 
 
250
protected:
 
251
    int m_tokenIndex;
 
252
    Item *m_parent;
 
253
};
 
254
 
 
255
struct Text: public Item
 
256
{
 
257
    inline Text(Item *parent = 0)
 
258
        : m_parent(parent) {}
 
259
 
 
260
    virtual Text *toText() const
 
261
    { return const_cast<Text *>(this); }
 
262
 
 
263
    virtual Item *parent() const
 
264
    { return m_parent; }
 
265
 
 
266
    void setTokenSection(TokenEngine::TokenSection tokenSection)
 
267
    {m_tokenSection = tokenSection; }
 
268
 
 
269
    TokenEngine::TokenSection text() const
 
270
    { return m_tokenSection; }
 
271
 
 
272
    QVector<TokenEngine::TokenSection> cleanedText() const
 
273
    { return m_cleanedSection; }
 
274
 
 
275
    void setTokens( const QVector<Token *> &tokens )
 
276
    { m_tokens = tokens; }
 
277
 
 
278
    void addToken(Token *token)
 
279
    {m_tokens.append(token);}
 
280
 
 
281
    Token *token(int index) const
 
282
    {return m_tokens.at(index);}
 
283
 
 
284
    inline int count() const
 
285
    {return m_tokens.count();}
 
286
 
 
287
    QVector<Token *> tokenList() const
 
288
    { return m_tokens; }
 
289
 
 
290
protected:
 
291
    Item *m_parent;
 
292
    TokenEngine::TokenSection m_tokenSection;    // all tokens
 
293
    QVector<TokenEngine::TokenSection> m_cleanedSection; //comments removed
 
294
    QVector<Token *> m_tokens;
 
295
};
 
296
 
 
297
struct IdToken: public Token
 
298
{
 
299
    inline IdToken(Item *parent = 0)
 
300
        : Token(parent) {}
 
301
 
 
302
    virtual IdToken *toIdToken() const
 
303
    { return const_cast<IdToken *>(this); }
 
304
};
 
305
 
 
306
struct NonIdToken: public Token
 
307
{
 
308
    inline  NonIdToken(Item *parent = 0)
 
309
        : Token(parent) {}
 
310
 
 
311
    virtual NonIdToken *toNonIdToken() const
 
312
    { return const_cast< NonIdToken *>(this); }
 
313
};
 
314
 
 
315
struct LineComment : public NonIdToken
 
316
{
 
317
    inline LineComment(Item *parent = 0)
 
318
       : NonIdToken(parent) {}
 
319
 
 
320
    virtual LineComment *toLineComment() const
 
321
    { return const_cast< LineComment *>(this); }
 
322
};
 
323
 
 
324
struct MultiLineComment: public NonIdToken
 
325
{
 
326
    inline MultiLineComment(Item *parent = 0)
 
327
        : NonIdToken(parent) {}
 
328
 
 
329
    virtual MultiLineComment *toMultiLineComment() const
 
330
    { return const_cast< MultiLineComment *>(this); }
 
331
protected:
 
332
};
 
333
 
 
334
struct WhiteSpace: public NonIdToken
 
335
{
 
336
    inline WhiteSpace(Item *parent = 0)
 
337
        : NonIdToken(parent) {}
 
338
 
 
339
    virtual WhiteSpace *toWhiteSpace() const
 
340
    { return const_cast<WhiteSpace *>(this); }
 
341
};
 
342
 
 
343
struct Source: public Item, public ItemComposite
 
344
{
 
345
    Source(Item *parent = 0)
 
346
        :m_parent(parent) {}
 
347
 
 
348
    virtual Source *toSource() const
 
349
    { return const_cast<Source *>(this); }
 
350
 
 
351
    ItemComposite *toItemComposite() const
 
352
    { return const_cast<Source *>(this); }
 
353
 
 
354
    virtual int count() const
 
355
    { return m_items.count(); }
 
356
 
 
357
    virtual Item *item(int index) const
 
358
    {  return m_items.at(index); }
 
359
 
 
360
    inline QString fileName() const
 
361
    { return m_fileName; }
 
362
 
 
363
    void setFileName(const QString &fileName);
 
364
 
 
365
    virtual Item *parent() const
 
366
    { return m_parent; }
 
367
 
 
368
    inline void add(Item *item)
 
369
    {  m_items.append(item); }
 
370
 
 
371
private:
 
372
    Item *m_parent;
 
373
    QVector<Item *> m_items;
 
374
    QString m_fileName;
 
375
};
 
376
 
 
377
struct EmptyDirective: public Directive
 
378
{
 
379
    EmptyDirective(Item *item)
 
380
    : Directive(item) {}
 
381
 
 
382
    virtual EmptyDirective *toEmptyDirective() const
 
383
    { return const_cast<EmptyDirective *>(this); }
 
384
};
 
385
 
 
386
struct ErrorDirective: public Directive
 
387
{
 
388
    ErrorDirective(Item *item)
 
389
    : Directive(item) {}
 
390
 
 
391
    virtual ErrorDirective *toErrorDirective() const
 
392
    { return const_cast<ErrorDirective *>(this); }
 
393
};
 
394
 
 
395
struct PragmaDirective: public Directive
 
396
{
 
397
    PragmaDirective(Item *item)
 
398
    : Directive(item) {}
 
399
 
 
400
    virtual PragmaDirective *toPragmaDirective() const
 
401
    { return const_cast<PragmaDirective *>(this); }
 
402
};
 
403
 
 
404
struct IncludeDirective: public Directive
 
405
{
 
406
    IncludeDirective(Item *item)
 
407
    : Directive(item), m_filenameToken(-1) {}
 
408
 
 
409
    IncludeDirective() : Directive(), m_filenameToken(-1) {}
 
410
 
 
411
    virtual IncludeDirective *toIncludeDirective() const
 
412
    { return const_cast<IncludeDirective *>(this); }
 
413
 
 
414
    enum IncludeType {QuoteInclude, AngleBracketInclude};
 
415
 
 
416
    void setFilenameToken(int filenameToken)
 
417
    { m_filenameToken = filenameToken; }
 
418
 
 
419
    int filenameToken() const
 
420
    { return m_filenameToken; }
 
421
 
 
422
    void setFilename(const QByteArray &filename)
 
423
    { m_filename = filename; }
 
424
 
 
425
    QByteArray filename() const
 
426
    { return m_filename;}
 
427
 
 
428
    void setIncludeType(IncludeType includeType)
 
429
    { m_includeType = includeType; }
 
430
 
 
431
    IncludeType includeType() const
 
432
    { return m_includeType; }
 
433
private:
 
434
    int m_filenameToken;
 
435
    QByteArray m_filename;
 
436
    IncludeType m_includeType;
 
437
};
 
438
 
 
439
struct ConditionalDirective: public Directive, public ItemComposite
 
440
{
 
441
    inline ConditionalDirective(Item *parent = 0)
 
442
    :Directive(parent) {}
 
443
 
 
444
    virtual ConditionalDirective *toConditionalDirective() const
 
445
    { return const_cast<ConditionalDirective *>(this); }
 
446
 
 
447
    ItemComposite *toItemComposite() const
 
448
    { return const_cast<ConditionalDirective *>(this); }
 
449
 
 
450
    virtual IfDirective *toIfDirective() const
 
451
    { return 0; }
 
452
 
 
453
    virtual IfdefDirective *toIfdefDirective() const
 
454
    { return 0; }
 
455
 
 
456
    virtual IfndefDirective *toIfndefDirective() const
 
457
    { return 0; }
 
458
 
 
459
    virtual ElifDirective *toElifDirective() const
 
460
    { return 0; }
 
461
 
 
462
    virtual ElseDirective *toElseDirective() const
 
463
    { return 0; }
 
464
 
 
465
    int count() const
 
466
    { return m_items.count(); }
 
467
 
 
468
    Item *item(int index) const
 
469
    { return m_items.at(index); }
 
470
 
 
471
    void add(Item *item)
 
472
    { m_items.append(item); }
 
473
protected:
 
474
    QVector<Item *> m_items;
 
475
};
 
476
 
 
477
struct IfSection: public Item, public ItemComposite
 
478
{
 
479
    IfSection(Item *parent)
 
480
    :m_parent(parent), m_ifGroup(0), m_elseGroup(0), m_endifLine(0) {}
 
481
 
 
482
    IfSection *toIfSection() const
 
483
    { return const_cast<IfSection *>(this); }
 
484
 
 
485
    ItemComposite *toItemComposite() const
 
486
    { return const_cast<IfSection *>(this); }
 
487
 
 
488
    void setParent(Item *parent)
 
489
    { m_parent = parent; }
 
490
 
 
491
    Item *parent() const
 
492
    { return m_parent; }
 
493
 
 
494
    void setIfGroup(ConditionalDirective *ifGroup)
 
495
    { m_ifGroup = ifGroup; m_items.append(ifGroup); }
 
496
 
 
497
    ConditionalDirective *ifGroup() const
 
498
    { return m_ifGroup; }
 
499
 
 
500
    void addElifGroup(ConditionalDirective *elifGroup)
 
501
    { m_elifGroups.append(elifGroup); m_items.append(elifGroup); }
 
502
 
 
503
    QVector<ConditionalDirective *> elifGroups() const
 
504
    { return m_elifGroups; }
 
505
 
 
506
    void setElseGroup(ConditionalDirective *elseGroup)
 
507
    { m_elseGroup = elseGroup; m_items.append(elseGroup); }
 
508
 
 
509
    ConditionalDirective *elseGroup() const
 
510
    { return m_elseGroup; }
 
511
 
 
512
    void setEndifLine(Directive *endifLine)
 
513
    { m_endifLine = endifLine; m_items.append(endifLine); }
 
514
 
 
515
    Directive *endifLine() const
 
516
    { return m_endifLine; }
 
517
 
 
518
    int count() const
 
519
    { return m_items.count(); }
 
520
 
 
521
    Item *item(int index) const
 
522
    { return m_items.at(index);}
 
523
 
 
524
 private:
 
525
    void add(Item *item)
 
526
    { Q_UNUSED(item); }
 
527
 
 
528
    Item *m_parent;
 
529
    QVector<Item *> m_items;
 
530
    ConditionalDirective *m_ifGroup;
 
531
    QVector<ConditionalDirective *> m_elifGroups;
 
532
    ConditionalDirective *m_elseGroup;
 
533
    Directive *m_endifLine;
 
534
};
 
535
 
 
536
struct Expression: public Item
 
537
{
 
538
    enum Operator
 
539
    {
 
540
        LtEqOp = 300,
 
541
        GtEqOp,
 
542
        LtOp,
 
543
        GtOp,
 
544
        EqOp,
 
545
        NotEqOp,
 
546
        OrOp,
 
547
        AndOp,
 
548
        LShiftOp,
 
549
        RShiftOp
 
550
    };
 
551
 
 
552
    inline Expression(Item *parent = 0)
 
553
        : m_parent(parent) {}
 
554
 
 
555
    inline Expression *parentExpression() const
 
556
    { return m_parent ? m_parent->toExpression() : 0; }
 
557
 
 
558
    virtual Item *parent() const
 
559
    { return m_parent; }
 
560
 
 
561
    virtual Expression *toExpression() const
 
562
    { return const_cast<Expression *>(this); }
 
563
 
 
564
    virtual UnaryExpression *toUnaryExpression() const
 
565
    { return 0; }
 
566
 
 
567
    virtual BinaryExpression *toBinaryExpression() const
 
568
    { return 0; }
 
569
 
 
570
    virtual StringLiteral *toStringLiteral() const
 
571
    { return 0; }
 
572
 
 
573
    virtual IntLiteral *toIntLiteral() const
 
574
    { return 0; }
 
575
 
 
576
    virtual MacroReference *toMacroReference() const
 
577
    { return 0; }
 
578
 
 
579
    virtual MacroFunctionReference *toMacroFunctionReference() const
 
580
    { return 0; }
 
581
 
 
582
    virtual ConditionalExpression *toConditionalExpression() const
 
583
    { return 0; }
 
584
 
 
585
    int evaluate(bool *ok = 0);
 
586
 
 
587
private:
 
588
    Item *m_parent;
 
589
};
 
590
 
 
591
struct StringLiteral: public Expression
 
592
{
 
593
    inline StringLiteral(const QByteArray &value, Item *parent)
 
594
        : Expression(parent), m_value(value) {}
 
595
 
 
596
    QByteArray value() const
 
597
    { return m_value; }
 
598
 
 
599
    virtual StringLiteral *toStringLiteral() const
 
600
    { return const_cast<StringLiteral *>(this); }
 
601
 
 
602
private:
 
603
    QByteArray m_value;
 
604
};
 
605
 
 
606
struct IntLiteral: public Expression
 
607
{
 
608
    inline IntLiteral(int value, Item *parent = 0)
 
609
        : Expression(parent), m_value(value) {}
 
610
 
 
611
    inline int value() const
 
612
    { return m_value; }
 
613
 
 
614
    virtual IntLiteral *toIntLiteral() const
 
615
    { return const_cast<IntLiteral *>(this); }
 
616
 
 
617
private:
 
618
    int m_value;
 
619
};
 
620
 
 
621
struct MacroReference: public Expression
 
622
{
 
623
    enum Type {
 
624
        DefinedRef,    //#if defined(foo)
 
625
        ValueRef
 
626
    };
 
627
 
 
628
    inline MacroReference(const TokenEngine::TokenList &name, Type type, Item *parent = 0)
 
629
        : Expression(parent), m_type(type), m_name(name) {}
 
630
 
 
631
    virtual MacroReference *toMacroReference() const
 
632
    { return const_cast<MacroReference *>(this); }
 
633
 
 
634
    inline TokenEngine::TokenList name() const
 
635
    { return m_name; }
 
636
 
 
637
    inline void setName(const TokenEngine::TokenList &name)
 
638
    { m_name = name; }
 
639
 
 
640
    inline int type() const
 
641
    { return m_type; }
 
642
 
 
643
private:
 
644
    int m_type;
 
645
    TokenEngine::TokenList m_name;
 
646
};
 
647
 
 
648
struct MacroFunctionReference: public Expression
 
649
{
 
650
    MacroFunctionReference(const QByteArray &name, Item *parent);
 
651
 
 
652
    inline QByteArray name() const
 
653
    { return m_name; }
 
654
 
 
655
    inline void setName(const QByteArray &name)
 
656
    { m_name = name; }
 
657
 
 
658
    inline MacroArguments *arguments() const
 
659
    { return m_arguments; }
 
660
 
 
661
    virtual MacroFunctionReference *toMacroFunctionReference() const
 
662
    { return const_cast<MacroFunctionReference *>(this); }
 
663
 
 
664
private:
 
665
    QByteArray m_name;
 
666
    MacroArguments *m_arguments;
 
667
};
 
668
 
 
669
struct UnaryExpression: public Expression
 
670
{
 
671
     inline UnaryExpression(int op, Expression *e, Expression *parent = 0)
 
672
        : Expression(parent), m_op(op), m_expression(e) {}
 
673
 
 
674
    inline int op() const
 
675
    { return m_op; }
 
676
 
 
677
    inline Expression *expression() const
 
678
    { return m_expression; }
 
679
 
 
680
    virtual UnaryExpression *toUnaryExpression() const
 
681
    { return const_cast<UnaryExpression *>(this); }
 
682
 
 
683
private:
 
684
    int m_op;
 
685
    Expression *m_expression;
 
686
};
 
687
 
 
688
struct BinaryExpression: public Expression
 
689
{
 
690
   inline BinaryExpression(int op, Expression *left, Expression *right, Expression *parent = 0)
 
691
        : Expression(parent),
 
692
          m_op(op),
 
693
          m_leftExpression(left),
 
694
          m_rightExpression(right) {}
 
695
 
 
696
    inline int op() const
 
697
    { return m_op; }
 
698
 
 
699
    inline Expression *leftExpression() const
 
700
    { return m_leftExpression; }
 
701
 
 
702
    inline Expression *rightExpression() const
 
703
    { return m_rightExpression; }
 
704
 
 
705
    virtual BinaryExpression *toBinaryExpression() const
 
706
    { return const_cast<BinaryExpression *>(this); }
 
707
 
 
708
private:
 
709
    int m_op;
 
710
    Expression *m_leftExpression;
 
711
    Expression *m_rightExpression;
 
712
};
 
713
 
 
714
struct ConditionalExpression: public Expression
 
715
{
 
716
    inline ConditionalExpression(Expression *condition, Expression *left, Expression *right, Expression *parent = 0)
 
717
        : Expression(parent),
 
718
          m_condition(condition),
 
719
          m_leftExpression(left),
 
720
          m_rightExpression(right) {}
 
721
 
 
722
    inline Expression *condition() const
 
723
    { return m_condition; }
 
724
 
 
725
    inline Expression *leftExpression() const
 
726
    { return m_leftExpression; }
 
727
 
 
728
    inline Expression *rightExpression() const
 
729
    { return m_rightExpression; }
 
730
 
 
731
    virtual ConditionalExpression *toConditionalExpression() const
 
732
    { return const_cast<ConditionalExpression *>(this); }
 
733
 
 
734
private:
 
735
    Expression *m_condition;
 
736
    Expression *m_leftExpression;
 
737
    Expression *m_rightExpression;
 
738
};
 
739
 
 
740
 
 
741
struct IfLikeDirective: public ConditionalDirective
 
742
{
 
743
    inline IfLikeDirective(Item *parent = 0)
 
744
        :ConditionalDirective(parent), m_expression(0) {}
 
745
 
 
746
    void setExpression(Expression *expression)
 
747
    { m_expression  = expression; }
 
748
 
 
749
    Expression *expression() const
 
750
    { return m_expression; }
 
751
 
 
752
protected:
 
753
    Expression *m_expression;
 
754
};
 
755
 
 
756
struct IfDirective: public IfLikeDirective
 
757
{
 
758
    inline IfDirective(Item *parent = 0)
 
759
        :IfLikeDirective(parent) {}
 
760
 
 
761
    virtual IfDirective *toIfDirective() const
 
762
    { return const_cast<IfDirective *>(this); }
 
763
};
 
764
 
 
765
 
 
766
struct ElifDirective: public IfLikeDirective
 
767
{
 
768
    inline ElifDirective(Item *parent = 0)
 
769
    :IfLikeDirective(parent) {}
 
770
 
 
771
    virtual ElifDirective *toElifDirective() const
 
772
    { return const_cast<ElifDirective *>(this); }
 
773
};
 
774
 
 
775
struct IfdefLikeDirective: public ConditionalDirective
 
776
{
 
777
    inline IfdefLikeDirective(Item *parent = 0)
 
778
    :ConditionalDirective(parent) {}
 
779
 
 
780
    inline TokenEngine::TokenList identifier() const
 
781
    { return m_identifier; }
 
782
 
 
783
    inline void setIdentifier(const TokenEngine::TokenList &identifier)
 
784
    { m_identifier = identifier; }
 
785
protected:
 
786
    TokenEngine::TokenList m_identifier;
 
787
};
 
788
 
 
789
struct IfdefDirective: public IfdefLikeDirective
 
790
{
 
791
    IfdefDirective(Item *parent)
 
792
    :IfdefLikeDirective(parent) {}
 
793
 
 
794
    virtual IfdefDirective *toIfdefDirective() const
 
795
    { return const_cast<IfdefDirective *>(this); }
 
796
};
 
797
 
 
798
struct IfndefDirective: public IfdefLikeDirective
 
799
{
 
800
    inline IfndefDirective(Item *parent)
 
801
    :IfdefLikeDirective(parent) {}
 
802
 
 
803
    virtual IfndefDirective *toIfndefDirective() const
 
804
    { return const_cast<IfndefDirective *>(this); }
 
805
};
 
806
 
 
807
struct ElseDirective: public ConditionalDirective
 
808
{
 
809
    ElseDirective(Item *parent)
 
810
    :ConditionalDirective(parent) {}
 
811
 
 
812
    virtual ElseDirective *toElseDirective() const
 
813
    { return const_cast<ElseDirective *>(this); }
 
814
};
 
815
 
 
816
struct EndifDirective : public Directive
 
817
{
 
818
    EndifDirective(Item *parent)
 
819
    :Directive(parent) {}
 
820
 
 
821
    EndifDirective *toEndifDirective() const
 
822
    { return const_cast<EndifDirective *>(this); }
 
823
};
 
824
 
 
825
struct DefineDirective: public Directive
 
826
{
 
827
    DefineDirective(Item *parent)
 
828
    : Directive(parent) {};
 
829
 
 
830
    inline TokenEngine::TokenList identifier() const
 
831
    { return m_identifier; }
 
832
 
 
833
    inline void setIdentifier(TokenEngine::TokenList identifier)
 
834
    { m_identifier = identifier; }
 
835
 
 
836
    inline void setReplacementList(TokenEngine::TokenList replacementList)
 
837
    { m_replacementList = replacementList; }
 
838
 
 
839
    inline TokenEngine::TokenList replacementList() const
 
840
    { return m_replacementList; }
 
841
 
 
842
    virtual DefineDirective *toDefineDirective() const
 
843
    { return const_cast<DefineDirective *>(this); }
 
844
 
 
845
    virtual MacroDefinition *toMacroDefinition() const
 
846
    { return 0; }
 
847
 
 
848
    virtual MacroFunctionDefinition *toMacroFunctionDefinition() const
 
849
    { return 0; }
 
850
private:
 
851
    TokenEngine::TokenList m_identifier;
 
852
    TokenEngine::TokenList m_replacementList;
 
853
};
 
854
 
 
855
struct MacroDefinition: public DefineDirective
 
856
{
 
857
    MacroDefinition(Item *parent)
 
858
    : DefineDirective(parent) {};
 
859
 
 
860
    virtual MacroDefinition *toMacroDefinition() const
 
861
    { return const_cast<MacroDefinition *>(this); }
 
862
};
 
863
 
 
864
struct MacroFunctionDefinition: public DefineDirective
 
865
{
 
866
    MacroFunctionDefinition(Item *parent)
 
867
    : DefineDirective(parent) {}
 
868
 
 
869
    virtual MacroFunctionDefinition *toMacroFunctionDefinition() const
 
870
    { return const_cast<MacroFunctionDefinition *>(this); }
 
871
 
 
872
    void setParameters(TokenEngine::TokenList macroParameters)
 
873
    { m_parameters = macroParameters;}
 
874
 
 
875
    inline TokenEngine::TokenList parameters() const
 
876
    { return m_parameters; }
 
877
 
 
878
private:
 
879
    TokenEngine::TokenList m_parameters;
 
880
};
 
881
 
 
882
struct MacroParameter: public Item
 
883
{
 
884
    inline MacroParameter(Item *parent)
 
885
        : m_parent(parent) {}
 
886
 
 
887
    inline QByteArray name() const
 
888
    { return m_name; }
 
889
 
 
890
    inline void setName(const QByteArray &name)
 
891
    { m_name = name; }
 
892
 
 
893
    virtual Item *parent() const
 
894
    { return m_parent; }
 
895
 
 
896
private:
 
897
    Item *m_parent;
 
898
    QByteArray m_name;
 
899
};
 
900
 
 
901
struct MacroParameters: public Item, public ItemComposite
 
902
{
 
903
    MacroParameters(MacroFunctionDefinition *parent)
 
904
        : m_parent(parent) {}
 
905
 
 
906
    ItemComposite *toItemComposite() const
 
907
    { return const_cast<MacroParameters *>(this); }
 
908
 
 
909
    virtual Item *parent() const
 
910
    { return m_parent; }
 
911
 
 
912
    virtual int count() const
 
913
    { return m_items.count(); }
 
914
 
 
915
    virtual Item *item(int index) const
 
916
    { return m_items.at(index); }
 
917
 
 
918
    void addParameter(MacroParameter *param)
 
919
    { Q_ASSERT(param->parent() == this); m_items.append(param); }
 
920
 
 
921
    int indexOf(const QByteArray &param) const
 
922
    {
 
923
        for (int i=0; i<m_items.count(); ++i) {
 
924
         //   cout <<"checking |" << param.constData() << "| against |" << m_items.at(i)->name().constData() <<"|" << endl;
 
925
            if (m_items.at(i)->name() == param)
 
926
                return i;
 
927
        }
 
928
        return -1;
 
929
    }
 
930
 
 
931
    inline bool contains(const QByteArray &param) const
 
932
    { return indexOf(param) != -1; }
 
933
/*
 
934
    void add(const QByteArray &param)
 
935
    {
 
936
        MacroParameter *p = createNode<MacroParameter>(this);
 
937
        p->setName(param);
 
938
        addParameter(p);
 
939
    }
 
940
*/
 
941
private:
 
942
    MacroFunctionDefinition *m_parent;
 
943
    QVector<MacroParameter*> m_items;
 
944
};
 
945
 
 
946
struct UndefDirective: public Directive
 
947
{
 
948
    UndefDirective(Item *parent)
 
949
    :Directive(parent) {}
 
950
 
 
951
    inline TokenEngine::TokenList identifier() const
 
952
    { return m_identifier; }
 
953
 
 
954
    inline void setIdentifier(const TokenEngine::TokenList &identifier)
 
955
    { m_identifier = identifier; }
 
956
 
 
957
    virtual UndefDirective *toUndefDirective() const
 
958
    { return const_cast<UndefDirective *>(this); }
 
959
private:
 
960
    TokenEngine::TokenList m_identifier;
 
961
};
 
962
 
 
963
struct LineDirective: public Directive
 
964
{
 
965
    LineDirective(Item *parent)
 
966
    :Directive(parent) {}
 
967
 
 
968
    virtual LineDirective *toLineDirective() const
 
969
    { return const_cast<LineDirective *>(this); }
 
970
};
 
971
 
 
972
struct NonDirective: public Directive
 
973
{
 
974
    NonDirective(Item *parent)
 
975
    :Directive(parent) {}
 
976
 
 
977
    virtual NonDirective *toNonDirective() const
 
978
    { return const_cast<NonDirective *>(this); }
 
979
};
 
980
 
 
981
class Preprocessor : public QObject
 
982
{
 
983
Q_OBJECT
 
984
public:
 
985
    Preprocessor();
 
986
    Source *parse(const TokenEngine::TokenContainer &tokenContainer,
 
987
                  const QVector<Type> &tokenTypeList, TypedPool<Item> *memoryPool);
 
988
signals:
 
989
    void error(const QString type, const QString message);
 
990
private:
 
991
    bool parseGroup(Item *node);
 
992
    bool parseGroupPart(Item *node);
 
993
 
 
994
    bool parseIfSection(Item *node);
 
995
    bool parseNonDirective(Item *node);
 
996
    bool parseTextLine(Item *node);
 
997
 
 
998
    bool parseIfGroup(IfSection *node);
 
999
    bool parseElifGroups(IfSection *node);
 
1000
    bool parseElifGroup(IfSection *node);
 
1001
    bool parseElseGroup(IfSection *node);
 
1002
    bool parseEndifLine(IfSection *node);
 
1003
 
 
1004
    bool parseIfdefLikeDirective(IfdefLikeDirective *node);
 
1005
    bool parseIfLikeDirective(IfLikeDirective *node);
 
1006
 
 
1007
    bool parseDefineDirective(Item *node);
 
1008
    bool parseUndefDirective(Item *node);
 
1009
    bool parseIncludeDirective(Item *node);
 
1010
    bool parseErrorDirective(Item *node);
 
1011
    bool parsePragmaDirective(Item*node);
 
1012
 
 
1013
    TokenEngine::TokenSection readLine();
 
1014
    inline bool isValidIndex(const int index) const;
 
1015
    inline bool isWhiteSpace(const int index) const;
 
1016
    Type lookAhead() const;
 
1017
    Type lookAheadSkipHash() const;
 
1018
    inline int skipWhiteSpaceAndComments() const;
 
1019
    inline int skipWhiteSpaceCommentsHash() const;
 
1020
    QVector<int> cleanEscapedNewLines(const TokenEngine::TokenSection &tokenSection) const;
 
1021
    QVector<int> cleanTokenRange(const TokenEngine::TokenSection &tokenSection) const;
 
1022
 
 
1023
    Source *m_source;
 
1024
    TokenEngine::TokenContainer m_tokenContainer;
 
1025
    QVector<Type> m_tokenTypeList;
 
1026
    TypedPool<Item> *m_memoryPool;
 
1027
    int lexerTokenIndex;
 
1028
    int numTokens;
 
1029
};
 
1030
 
 
1031
/*
 
1032
    T must be a subclass of Item, parent must implment
 
1033
    the ItemComposite interface
 
1034
*/
 
1035
template <typename T>
 
1036
T *createNode(TypedPool<Item> *memPool, Item *parent)
 
1037
{
 
1038
    Q_ASSERT(parent);
 
1039
    T* node = new (memPool->allocate(sizeof(T))) T(parent);
 
1040
    Q_ASSERT(node);
 
1041
    return node;
 
1042
}
 
1043
 
 
1044
template <typename T>
 
1045
T *createNode(TypedPool<Item> *memPool)
 
1046
{
 
1047
    T* node = new (memPool->allocate(sizeof(T))) T(0);
 
1048
    Q_ASSERT(node);
 
1049
    return node;
 
1050
}
 
1051
 
 
1052
 
 
1053
QByteArray visitGetText(Item *item);
 
1054
 
 
1055
} // namespace Rpp
 
1056
 
 
1057
#endif