1
/****************************************************************************
3
** Copyright (C) 2004-2005 Trolltech AS. All rights reserved.
4
** Copyright (C) 2001-2004 Roberto Raggi
6
** This file is part of the porting application of the Qt Toolkit.
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.
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.
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.
22
** Contact info@trolltech.com if any conditions of this licensing are
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.
28
****************************************************************************/
35
#include <QStringList>
40
#include "tokenengine.h"
43
#include "smallobject.h"
56
struct EmptyDirective;
57
struct ErrorDirective;
58
struct PragmaDirective;
59
struct IncludeDirective;
60
struct ConditionalDirective;
61
struct DefineDirective;
62
struct UndefDirective;
67
struct IfLikeDirective;
70
struct IfdefLikeDirective;
71
struct IfdefDirective;
72
struct IfndefDirective;
74
struct EndifDirective;
78
struct TokenComposite;
83
struct MultiLineComment;
86
struct MacroDefinition;
87
struct MacroFunctionDefinition;
88
struct MacroParameters;
89
struct MacroParameter;
92
struct UnaryExpression;
93
struct BinaryExpression;
94
struct ConditionalExpression;
98
struct MacroReference;
99
struct MacroFunctionReference;
100
struct MacroArguments;
101
struct MacroArgument;
107
virtual Item *parent() const = 0;
109
virtual ItemComposite *toItemComposite() const
112
virtual Item *toItem() const
113
{ return const_cast<Item *>(this); }
115
virtual Directive *toDirective() const
118
virtual Text *toText() const
121
virtual Token *toToken() const
124
virtual Source *toSource() const
127
virtual Expression *toExpression() const
130
virtual IfSection *toIfSection() const
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(); }
139
//using the defualt constructor for an item is
140
//only allowded for subclasses.
146
virtual ~ItemComposite() {}
147
virtual int count() const = 0;
148
virtual Item *item(int index) const = 0;
149
virtual void add(Item *item) = 0;
151
Classes that inherit ItemComposite must implement this
153
virtual ItemComposite *toItemComposite() const
154
{ return const_cast<ItemComposite *>(this); }
158
struct Directive: public Item
160
inline Directive(Item *parent = 0)
161
: m_parent(parent), m_numLines(0) {}
163
virtual Item *parent() const
166
inline void setParent(Item *parent)
167
{ m_parent = parent;}
169
void setNumLines(const int numLines)
170
{m_numLines = numLines;}
172
virtual Directive *toDirective() const
173
{ return const_cast<Directive *>(this); }
175
virtual EmptyDirective *toEmptyDirective() const
178
virtual ErrorDirective *toErrorDirective() const
181
virtual PragmaDirective *toPragmaDirective() const
184
virtual IncludeDirective *toIncludeDirective() const
187
virtual ConditionalDirective *toConditionalDirective() const
190
virtual DefineDirective *toDefineDirective() const
193
virtual UndefDirective *toUndefDirective() const
196
virtual LineDirective *toLineDirective() const
199
virtual NonDirective *toNonDirective() const
202
void setTokenSection(TokenEngine::TokenSection section)
203
{ m_tokenSection = section; }
205
TokenEngine::TokenSection text() const
206
{ return m_tokenSection; }
211
TokenEngine::TokenSection m_tokenSection;
215
struct Token: public Item
217
inline Token(Item *parent = 0)
218
: m_parent(parent) {}
220
virtual Item *parent() const
223
virtual MacroArguments *toMacroArguments() const
226
virtual IdToken *toIdToken() const
229
virtual NonIdToken *toNonIdToken() const
232
virtual LineComment *toLineComment() const
235
virtual MultiLineComment *toMultiLineComment() const
238
virtual WhiteSpace *toWhiteSpace() const
241
virtual Token *toToken() const
242
{ return const_cast<Token *>(this); }
244
void setToken(int tokenIndex)
245
{ m_tokenIndex = tokenIndex;}
248
{ return m_tokenIndex; }
255
struct Text: public Item
257
inline Text(Item *parent = 0)
258
: m_parent(parent) {}
260
virtual Text *toText() const
261
{ return const_cast<Text *>(this); }
263
virtual Item *parent() const
266
void setTokenSection(TokenEngine::TokenSection tokenSection)
267
{m_tokenSection = tokenSection; }
269
TokenEngine::TokenSection text() const
270
{ return m_tokenSection; }
272
QVector<TokenEngine::TokenSection> cleanedText() const
273
{ return m_cleanedSection; }
275
void setTokens( const QVector<Token *> &tokens )
276
{ m_tokens = tokens; }
278
void addToken(Token *token)
279
{m_tokens.append(token);}
281
Token *token(int index) const
282
{return m_tokens.at(index);}
284
inline int count() const
285
{return m_tokens.count();}
287
QVector<Token *> tokenList() const
292
TokenEngine::TokenSection m_tokenSection; // all tokens
293
QVector<TokenEngine::TokenSection> m_cleanedSection; //comments removed
294
QVector<Token *> m_tokens;
297
struct IdToken: public Token
299
inline IdToken(Item *parent = 0)
302
virtual IdToken *toIdToken() const
303
{ return const_cast<IdToken *>(this); }
306
struct NonIdToken: public Token
308
inline NonIdToken(Item *parent = 0)
311
virtual NonIdToken *toNonIdToken() const
312
{ return const_cast< NonIdToken *>(this); }
315
struct LineComment : public NonIdToken
317
inline LineComment(Item *parent = 0)
318
: NonIdToken(parent) {}
320
virtual LineComment *toLineComment() const
321
{ return const_cast< LineComment *>(this); }
324
struct MultiLineComment: public NonIdToken
326
inline MultiLineComment(Item *parent = 0)
327
: NonIdToken(parent) {}
329
virtual MultiLineComment *toMultiLineComment() const
330
{ return const_cast< MultiLineComment *>(this); }
334
struct WhiteSpace: public NonIdToken
336
inline WhiteSpace(Item *parent = 0)
337
: NonIdToken(parent) {}
339
virtual WhiteSpace *toWhiteSpace() const
340
{ return const_cast<WhiteSpace *>(this); }
343
struct Source: public Item, public ItemComposite
345
Source(Item *parent = 0)
348
virtual Source *toSource() const
349
{ return const_cast<Source *>(this); }
351
ItemComposite *toItemComposite() const
352
{ return const_cast<Source *>(this); }
354
virtual int count() const
355
{ return m_items.count(); }
357
virtual Item *item(int index) const
358
{ return m_items.at(index); }
360
inline QString fileName() const
361
{ return m_fileName; }
363
void setFileName(const QString &fileName);
365
virtual Item *parent() const
368
inline void add(Item *item)
369
{ m_items.append(item); }
373
QVector<Item *> m_items;
377
struct EmptyDirective: public Directive
379
EmptyDirective(Item *item)
382
virtual EmptyDirective *toEmptyDirective() const
383
{ return const_cast<EmptyDirective *>(this); }
386
struct ErrorDirective: public Directive
388
ErrorDirective(Item *item)
391
virtual ErrorDirective *toErrorDirective() const
392
{ return const_cast<ErrorDirective *>(this); }
395
struct PragmaDirective: public Directive
397
PragmaDirective(Item *item)
400
virtual PragmaDirective *toPragmaDirective() const
401
{ return const_cast<PragmaDirective *>(this); }
404
struct IncludeDirective: public Directive
406
IncludeDirective(Item *item)
407
: Directive(item), m_filenameToken(-1) {}
409
IncludeDirective() : Directive(), m_filenameToken(-1) {}
411
virtual IncludeDirective *toIncludeDirective() const
412
{ return const_cast<IncludeDirective *>(this); }
414
enum IncludeType {QuoteInclude, AngleBracketInclude};
416
void setFilenameToken(int filenameToken)
417
{ m_filenameToken = filenameToken; }
419
int filenameToken() const
420
{ return m_filenameToken; }
422
void setFilename(const QByteArray &filename)
423
{ m_filename = filename; }
425
QByteArray filename() const
426
{ return m_filename;}
428
void setIncludeType(IncludeType includeType)
429
{ m_includeType = includeType; }
431
IncludeType includeType() const
432
{ return m_includeType; }
435
QByteArray m_filename;
436
IncludeType m_includeType;
439
struct ConditionalDirective: public Directive, public ItemComposite
441
inline ConditionalDirective(Item *parent = 0)
442
:Directive(parent) {}
444
virtual ConditionalDirective *toConditionalDirective() const
445
{ return const_cast<ConditionalDirective *>(this); }
447
ItemComposite *toItemComposite() const
448
{ return const_cast<ConditionalDirective *>(this); }
450
virtual IfDirective *toIfDirective() const
453
virtual IfdefDirective *toIfdefDirective() const
456
virtual IfndefDirective *toIfndefDirective() const
459
virtual ElifDirective *toElifDirective() const
462
virtual ElseDirective *toElseDirective() const
466
{ return m_items.count(); }
468
Item *item(int index) const
469
{ return m_items.at(index); }
472
{ m_items.append(item); }
474
QVector<Item *> m_items;
477
struct IfSection: public Item, public ItemComposite
479
IfSection(Item *parent)
480
:m_parent(parent), m_ifGroup(0), m_elseGroup(0), m_endifLine(0) {}
482
IfSection *toIfSection() const
483
{ return const_cast<IfSection *>(this); }
485
ItemComposite *toItemComposite() const
486
{ return const_cast<IfSection *>(this); }
488
void setParent(Item *parent)
489
{ m_parent = parent; }
494
void setIfGroup(ConditionalDirective *ifGroup)
495
{ m_ifGroup = ifGroup; m_items.append(ifGroup); }
497
ConditionalDirective *ifGroup() const
498
{ return m_ifGroup; }
500
void addElifGroup(ConditionalDirective *elifGroup)
501
{ m_elifGroups.append(elifGroup); m_items.append(elifGroup); }
503
QVector<ConditionalDirective *> elifGroups() const
504
{ return m_elifGroups; }
506
void setElseGroup(ConditionalDirective *elseGroup)
507
{ m_elseGroup = elseGroup; m_items.append(elseGroup); }
509
ConditionalDirective *elseGroup() const
510
{ return m_elseGroup; }
512
void setEndifLine(Directive *endifLine)
513
{ m_endifLine = endifLine; m_items.append(endifLine); }
515
Directive *endifLine() const
516
{ return m_endifLine; }
519
{ return m_items.count(); }
521
Item *item(int index) const
522
{ return m_items.at(index);}
529
QVector<Item *> m_items;
530
ConditionalDirective *m_ifGroup;
531
QVector<ConditionalDirective *> m_elifGroups;
532
ConditionalDirective *m_elseGroup;
533
Directive *m_endifLine;
536
struct Expression: public Item
552
inline Expression(Item *parent = 0)
553
: m_parent(parent) {}
555
inline Expression *parentExpression() const
556
{ return m_parent ? m_parent->toExpression() : 0; }
558
virtual Item *parent() const
561
virtual Expression *toExpression() const
562
{ return const_cast<Expression *>(this); }
564
virtual UnaryExpression *toUnaryExpression() const
567
virtual BinaryExpression *toBinaryExpression() const
570
virtual StringLiteral *toStringLiteral() const
573
virtual IntLiteral *toIntLiteral() const
576
virtual MacroReference *toMacroReference() const
579
virtual MacroFunctionReference *toMacroFunctionReference() const
582
virtual ConditionalExpression *toConditionalExpression() const
585
int evaluate(bool *ok = 0);
591
struct StringLiteral: public Expression
593
inline StringLiteral(const QByteArray &value, Item *parent)
594
: Expression(parent), m_value(value) {}
596
QByteArray value() const
599
virtual StringLiteral *toStringLiteral() const
600
{ return const_cast<StringLiteral *>(this); }
606
struct IntLiteral: public Expression
608
inline IntLiteral(int value, Item *parent = 0)
609
: Expression(parent), m_value(value) {}
611
inline int value() const
614
virtual IntLiteral *toIntLiteral() const
615
{ return const_cast<IntLiteral *>(this); }
621
struct MacroReference: public Expression
624
DefinedRef, //#if defined(foo)
628
inline MacroReference(const TokenEngine::TokenList &name, Type type, Item *parent = 0)
629
: Expression(parent), m_type(type), m_name(name) {}
631
virtual MacroReference *toMacroReference() const
632
{ return const_cast<MacroReference *>(this); }
634
inline TokenEngine::TokenList name() const
637
inline void setName(const TokenEngine::TokenList &name)
640
inline int type() const
645
TokenEngine::TokenList m_name;
648
struct MacroFunctionReference: public Expression
650
MacroFunctionReference(const QByteArray &name, Item *parent);
652
inline QByteArray name() const
655
inline void setName(const QByteArray &name)
658
inline MacroArguments *arguments() const
659
{ return m_arguments; }
661
virtual MacroFunctionReference *toMacroFunctionReference() const
662
{ return const_cast<MacroFunctionReference *>(this); }
666
MacroArguments *m_arguments;
669
struct UnaryExpression: public Expression
671
inline UnaryExpression(int op, Expression *e, Expression *parent = 0)
672
: Expression(parent), m_op(op), m_expression(e) {}
674
inline int op() const
677
inline Expression *expression() const
678
{ return m_expression; }
680
virtual UnaryExpression *toUnaryExpression() const
681
{ return const_cast<UnaryExpression *>(this); }
685
Expression *m_expression;
688
struct BinaryExpression: public Expression
690
inline BinaryExpression(int op, Expression *left, Expression *right, Expression *parent = 0)
691
: Expression(parent),
693
m_leftExpression(left),
694
m_rightExpression(right) {}
696
inline int op() const
699
inline Expression *leftExpression() const
700
{ return m_leftExpression; }
702
inline Expression *rightExpression() const
703
{ return m_rightExpression; }
705
virtual BinaryExpression *toBinaryExpression() const
706
{ return const_cast<BinaryExpression *>(this); }
710
Expression *m_leftExpression;
711
Expression *m_rightExpression;
714
struct ConditionalExpression: public Expression
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) {}
722
inline Expression *condition() const
723
{ return m_condition; }
725
inline Expression *leftExpression() const
726
{ return m_leftExpression; }
728
inline Expression *rightExpression() const
729
{ return m_rightExpression; }
731
virtual ConditionalExpression *toConditionalExpression() const
732
{ return const_cast<ConditionalExpression *>(this); }
735
Expression *m_condition;
736
Expression *m_leftExpression;
737
Expression *m_rightExpression;
741
struct IfLikeDirective: public ConditionalDirective
743
inline IfLikeDirective(Item *parent = 0)
744
:ConditionalDirective(parent), m_expression(0) {}
746
void setExpression(Expression *expression)
747
{ m_expression = expression; }
749
Expression *expression() const
750
{ return m_expression; }
753
Expression *m_expression;
756
struct IfDirective: public IfLikeDirective
758
inline IfDirective(Item *parent = 0)
759
:IfLikeDirective(parent) {}
761
virtual IfDirective *toIfDirective() const
762
{ return const_cast<IfDirective *>(this); }
766
struct ElifDirective: public IfLikeDirective
768
inline ElifDirective(Item *parent = 0)
769
:IfLikeDirective(parent) {}
771
virtual ElifDirective *toElifDirective() const
772
{ return const_cast<ElifDirective *>(this); }
775
struct IfdefLikeDirective: public ConditionalDirective
777
inline IfdefLikeDirective(Item *parent = 0)
778
:ConditionalDirective(parent) {}
780
inline TokenEngine::TokenList identifier() const
781
{ return m_identifier; }
783
inline void setIdentifier(const TokenEngine::TokenList &identifier)
784
{ m_identifier = identifier; }
786
TokenEngine::TokenList m_identifier;
789
struct IfdefDirective: public IfdefLikeDirective
791
IfdefDirective(Item *parent)
792
:IfdefLikeDirective(parent) {}
794
virtual IfdefDirective *toIfdefDirective() const
795
{ return const_cast<IfdefDirective *>(this); }
798
struct IfndefDirective: public IfdefLikeDirective
800
inline IfndefDirective(Item *parent)
801
:IfdefLikeDirective(parent) {}
803
virtual IfndefDirective *toIfndefDirective() const
804
{ return const_cast<IfndefDirective *>(this); }
807
struct ElseDirective: public ConditionalDirective
809
ElseDirective(Item *parent)
810
:ConditionalDirective(parent) {}
812
virtual ElseDirective *toElseDirective() const
813
{ return const_cast<ElseDirective *>(this); }
816
struct EndifDirective : public Directive
818
EndifDirective(Item *parent)
819
:Directive(parent) {}
821
EndifDirective *toEndifDirective() const
822
{ return const_cast<EndifDirective *>(this); }
825
struct DefineDirective: public Directive
827
DefineDirective(Item *parent)
828
: Directive(parent) {};
830
inline TokenEngine::TokenList identifier() const
831
{ return m_identifier; }
833
inline void setIdentifier(TokenEngine::TokenList identifier)
834
{ m_identifier = identifier; }
836
inline void setReplacementList(TokenEngine::TokenList replacementList)
837
{ m_replacementList = replacementList; }
839
inline TokenEngine::TokenList replacementList() const
840
{ return m_replacementList; }
842
virtual DefineDirective *toDefineDirective() const
843
{ return const_cast<DefineDirective *>(this); }
845
virtual MacroDefinition *toMacroDefinition() const
848
virtual MacroFunctionDefinition *toMacroFunctionDefinition() const
851
TokenEngine::TokenList m_identifier;
852
TokenEngine::TokenList m_replacementList;
855
struct MacroDefinition: public DefineDirective
857
MacroDefinition(Item *parent)
858
: DefineDirective(parent) {};
860
virtual MacroDefinition *toMacroDefinition() const
861
{ return const_cast<MacroDefinition *>(this); }
864
struct MacroFunctionDefinition: public DefineDirective
866
MacroFunctionDefinition(Item *parent)
867
: DefineDirective(parent) {}
869
virtual MacroFunctionDefinition *toMacroFunctionDefinition() const
870
{ return const_cast<MacroFunctionDefinition *>(this); }
872
void setParameters(TokenEngine::TokenList macroParameters)
873
{ m_parameters = macroParameters;}
875
inline TokenEngine::TokenList parameters() const
876
{ return m_parameters; }
879
TokenEngine::TokenList m_parameters;
882
struct MacroParameter: public Item
884
inline MacroParameter(Item *parent)
885
: m_parent(parent) {}
887
inline QByteArray name() const
890
inline void setName(const QByteArray &name)
893
virtual Item *parent() const
901
struct MacroParameters: public Item, public ItemComposite
903
MacroParameters(MacroFunctionDefinition *parent)
904
: m_parent(parent) {}
906
ItemComposite *toItemComposite() const
907
{ return const_cast<MacroParameters *>(this); }
909
virtual Item *parent() const
912
virtual int count() const
913
{ return m_items.count(); }
915
virtual Item *item(int index) const
916
{ return m_items.at(index); }
918
void addParameter(MacroParameter *param)
919
{ Q_ASSERT(param->parent() == this); m_items.append(param); }
921
int indexOf(const QByteArray ¶m) const
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)
931
inline bool contains(const QByteArray ¶m) const
932
{ return indexOf(param) != -1; }
934
void add(const QByteArray ¶m)
936
MacroParameter *p = createNode<MacroParameter>(this);
942
MacroFunctionDefinition *m_parent;
943
QVector<MacroParameter*> m_items;
946
struct UndefDirective: public Directive
948
UndefDirective(Item *parent)
949
:Directive(parent) {}
951
inline TokenEngine::TokenList identifier() const
952
{ return m_identifier; }
954
inline void setIdentifier(const TokenEngine::TokenList &identifier)
955
{ m_identifier = identifier; }
957
virtual UndefDirective *toUndefDirective() const
958
{ return const_cast<UndefDirective *>(this); }
960
TokenEngine::TokenList m_identifier;
963
struct LineDirective: public Directive
965
LineDirective(Item *parent)
966
:Directive(parent) {}
968
virtual LineDirective *toLineDirective() const
969
{ return const_cast<LineDirective *>(this); }
972
struct NonDirective: public Directive
974
NonDirective(Item *parent)
975
:Directive(parent) {}
977
virtual NonDirective *toNonDirective() const
978
{ return const_cast<NonDirective *>(this); }
981
class Preprocessor : public QObject
986
Source *parse(const TokenEngine::TokenContainer &tokenContainer,
987
const QVector<Type> &tokenTypeList, TypedPool<Item> *memoryPool);
989
void error(const QString type, const QString message);
991
bool parseGroup(Item *node);
992
bool parseGroupPart(Item *node);
994
bool parseIfSection(Item *node);
995
bool parseNonDirective(Item *node);
996
bool parseTextLine(Item *node);
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);
1004
bool parseIfdefLikeDirective(IfdefLikeDirective *node);
1005
bool parseIfLikeDirective(IfLikeDirective *node);
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);
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;
1024
TokenEngine::TokenContainer m_tokenContainer;
1025
QVector<Type> m_tokenTypeList;
1026
TypedPool<Item> *m_memoryPool;
1027
int lexerTokenIndex;
1032
T must be a subclass of Item, parent must implment
1033
the ItemComposite interface
1035
template <typename T>
1036
T *createNode(TypedPool<Item> *memPool, Item *parent)
1039
T* node = new (memPool->allocate(sizeof(T))) T(parent);
1044
template <typename T>
1045
T *createNode(TypedPool<Item> *memPool)
1047
T* node = new (memPool->allocate(sizeof(T))) T(0);
1053
QByteArray visitGetText(Item *item);