| /**************************************************************************** |
| ** |
| ** Copyright (C) 2001-2004 Roberto Raggi |
| ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). |
| ** All rights reserved. |
| ** Contact: Nokia Corporation (qt-info@nokia.com) |
| ** |
| ** This file is part of the qt3to4 porting application of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** GNU Lesser General Public License Usage |
| ** This file may be used under the terms of the GNU Lesser General Public |
| ** License version 2.1 as published by the Free Software Foundation and |
| ** appearing in the file LICENSE.LGPL included in the packaging of this |
| ** file. Please review the following information to ensure the GNU Lesser |
| ** General Public License version 2.1 requirements will be met: |
| ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
| ** |
| ** In addition, as a special exception, Nokia gives you certain additional |
| ** rights. These rights are described in the Nokia Qt LGPL Exception |
| ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU General |
| ** Public License version 3.0 as published by the Free Software Foundation |
| ** and appearing in the file LICENSE.GPL included in the packaging of this |
| ** file. Please review the following information to ensure the GNU General |
| ** Public License version 3.0 requirements will be met: |
| ** http://www.gnu.org/copyleft/gpl.html. |
| ** |
| ** Other Usage |
| ** Alternatively, this file may be used in accordance with the terms and |
| ** conditions contained in a signed written agreement between you and Nokia. |
| ** |
| ** |
| ** |
| ** |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #ifndef RPP_H |
| #define RPP_H |
| |
| #include "tokenengine.h" |
| #include "rpplexer.h" |
| #include "tokens.h" |
| #include "smallobject.h" |
| #include <QHash> |
| #include <QStringList> |
| #include <QFile> |
| #include <QByteArray> |
| #include <QDir> |
| #include <QMultiMap> |
| #include <ctype.h> |
| |
| QT_BEGIN_NAMESPACE |
| |
| namespace Rpp |
| { |
| |
| struct Item; |
| struct ItemComposite; |
| |
| struct Source; |
| |
| struct Directive; |
| struct EmptyDirective; |
| struct ErrorDirective; |
| struct PragmaDirective; |
| struct IncludeDirective; |
| struct ConditionalDirective; |
| struct DefineDirective; |
| struct UndefDirective; |
| struct LineDirective; |
| struct NonDirective; |
| |
| struct IfSection; |
| struct IfLikeDirective; |
| struct IfDirective; |
| struct ElifDirective; |
| struct IfdefLikeDirective; |
| struct IfdefDirective; |
| struct IfndefDirective; |
| struct ElseDirective; |
| struct EndifDirective; |
| |
| struct Text; |
| struct Token; |
| struct TokenComposite; |
| struct IdToken; |
| struct NonIdToken; |
| struct PastingToken; |
| struct LineComment; |
| struct MultiLineComment; |
| struct WhiteSpace; |
| |
| struct MacroDefinition; |
| struct MacroFunctionDefinition; |
| struct MacroParameters; |
| struct MacroParameter; |
| |
| struct Expression; |
| struct UnaryExpression; |
| struct BinaryExpression; |
| struct ConditionalExpression; |
| |
| struct StringLiteral; |
| struct IntLiteral; |
| struct MacroReference; |
| struct MacroFunctionReference; |
| struct MacroArguments; |
| struct MacroArgument; |
| |
| struct Item |
| { |
| virtual ~Item() {} |
| |
| virtual Item *parent() const = 0; |
| |
| virtual ItemComposite *toItemComposite() const |
| { return 0; } |
| |
| virtual Item *toItem() const |
| { return const_cast<Item *>(this); } |
| |
| virtual Directive *toDirective() const |
| { return 0; } |
| |
| virtual Text *toText() const |
| { return 0; } |
| |
| virtual Token *toToken() const |
| { return 0; } |
| |
| virtual Source *toSource() const |
| { return 0; } |
| |
| virtual Expression *toExpression() const |
| { return 0; } |
| |
| virtual IfSection *toIfSection() const |
| { return 0; } |
| |
| // Text returns the original text for an item, e.g. |
| // the way it is found in the source |
| virtual TokenEngine::TokenSection text() const |
| { return TokenEngine::TokenSection(); } |
| |
| protected: |
| //using the default constructor for an item is |
| //only allowded for subclasses. |
| Item() {}; |
| }; |
| |
| struct ItemComposite |
| { |
| virtual ~ItemComposite() {} |
| virtual int count() const = 0; |
| virtual Item *item(int index) const = 0; |
| virtual void add(Item *item) = 0; |
| /* |
| Classes that inherit ItemComposite must implement this |
| function themselves |
| virtual ItemComposite *toItemComposite() const |
| { return const_cast<ItemComposite *>(this); } |
| */ |
| }; |
| |
| struct Directive: public Item |
| { |
| inline Directive(Item *parent = 0) |
| : m_parent(parent), m_numLines(0) {} |
| |
| virtual Item *parent() const |
| { return m_parent; } |
| |
| inline void setParent(Item *parent) |
| { m_parent = parent;} |
| |
| void setNumLines(const int numLines) |
| {m_numLines = numLines;} |
| |
| virtual Directive *toDirective() const |
| { return const_cast<Directive *>(this); } |
| |
| virtual EmptyDirective *toEmptyDirective() const |
| { return 0; } |
| |
| virtual ErrorDirective *toErrorDirective() const |
| { return 0; } |
| |
| virtual PragmaDirective *toPragmaDirective() const |
| { return 0; } |
| |
| virtual IncludeDirective *toIncludeDirective() const |
| { return 0; } |
| |
| virtual ConditionalDirective *toConditionalDirective() const |
| { return 0; } |
| |
| virtual DefineDirective *toDefineDirective() const |
| { return 0; } |
| |
| virtual UndefDirective *toUndefDirective() const |
| { return 0; } |
| |
| virtual LineDirective *toLineDirective() const |
| { return 0; } |
| |
| virtual NonDirective *toNonDirective() const |
| { return 0; } |
| |
| void setTokenSection(TokenEngine::TokenSection section) |
| { m_tokenSection = section; } |
| |
| TokenEngine::TokenSection text() const |
| { return m_tokenSection; } |
| |
| protected: |
| Item *m_parent; |
| int m_numLines; |
| TokenEngine::TokenSection m_tokenSection; |
| }; |
| |
| |
| struct Token: public Item |
| { |
| inline Token(Item *parent = 0) |
| : m_tokenIndex(0), m_parent(parent) {} |
| |
| virtual Item *parent() const |
| { return m_parent; } |
| |
| virtual MacroArguments *toMacroArguments() const |
| { return 0; } |
| |
| virtual IdToken *toIdToken() const |
| { return 0; } |
| |
| virtual NonIdToken *toNonIdToken() const |
| { return 0; } |
| |
| virtual LineComment *toLineComment() const |
| { return 0; } |
| |
| virtual MultiLineComment *toMultiLineComment() const |
| { return 0; } |
| |
| virtual WhiteSpace *toWhiteSpace() const |
| { return 0; } |
| |
| virtual Token *toToken() const |
| { return const_cast<Token *>(this); } |
| |
| void setToken(int tokenIndex) |
| { m_tokenIndex = tokenIndex;} |
| |
| int index() const |
| { return m_tokenIndex; } |
| |
| protected: |
| int m_tokenIndex; |
| Item *m_parent; |
| }; |
| |
| struct Text: public Item |
| { |
| inline Text(Item *parent = 0) |
| : m_parent(parent) {} |
| |
| virtual Text *toText() const |
| { return const_cast<Text *>(this); } |
| |
| virtual Item *parent() const |
| { return m_parent; } |
| |
| void setTokenSection(TokenEngine::TokenSection tokenSection) |
| {m_tokenSection = tokenSection; } |
| |
| TokenEngine::TokenSection text() const |
| { return m_tokenSection; } |
| |
| QVector<TokenEngine::TokenSection> cleanedText() const |
| { return m_cleanedSection; } |
| |
| void setTokens( const QVector<Token *> &tokens ) |
| { m_tokens = tokens; } |
| |
| void addToken(Token *token) |
| {m_tokens.append(token);} |
| |
| Token *token(int index) const |
| {return m_tokens.at(index);} |
| |
| inline int count() const |
| {return m_tokens.count();} |
| |
| QVector<Token *> tokenList() const |
| { return m_tokens; } |
| |
| protected: |
| Item *m_parent; |
| TokenEngine::TokenSection m_tokenSection; // all tokens |
| QVector<TokenEngine::TokenSection> m_cleanedSection; //comments removed |
| QVector<Token *> m_tokens; |
| }; |
| |
| struct IdToken: public Token |
| { |
| inline IdToken(Item *parent = 0) |
| : Token(parent) {} |
| |
| virtual IdToken *toIdToken() const |
| { return const_cast<IdToken *>(this); } |
| }; |
| |
| struct NonIdToken: public Token |
| { |
| inline NonIdToken(Item *parent = 0) |
| : Token(parent) {} |
| |
| virtual NonIdToken *toNonIdToken() const |
| { return const_cast< NonIdToken *>(this); } |
| }; |
| |
| struct LineComment : public NonIdToken |
| { |
| inline LineComment(Item *parent = 0) |
| : NonIdToken(parent) {} |
| |
| virtual LineComment *toLineComment() const |
| { return const_cast< LineComment *>(this); } |
| }; |
| |
| struct MultiLineComment: public NonIdToken |
| { |
| inline MultiLineComment(Item *parent = 0) |
| : NonIdToken(parent) {} |
| |
| virtual MultiLineComment *toMultiLineComment() const |
| { return const_cast< MultiLineComment *>(this); } |
| protected: |
| }; |
| |
| struct WhiteSpace: public NonIdToken |
| { |
| inline WhiteSpace(Item *parent = 0) |
| : NonIdToken(parent) {} |
| |
| virtual WhiteSpace *toWhiteSpace() const |
| { return const_cast<WhiteSpace *>(this); } |
| }; |
| |
| struct Source: public Item, public ItemComposite |
| { |
| Source(Item *parent = 0) |
| :m_parent(parent) {} |
| |
| virtual Source *toSource() const |
| { return const_cast<Source *>(this); } |
| |
| ItemComposite *toItemComposite() const |
| { return const_cast<Source *>(this); } |
| |
| virtual int count() const |
| { return m_items.count(); } |
| |
| virtual Item *item(int index) const |
| { return m_items.at(index); } |
| |
| inline QString fileName() const |
| { return m_fileName; } |
| |
| void setFileName(const QString &fileName); |
| |
| virtual Item *parent() const |
| { return m_parent; } |
| |
| inline void add(Item *item) |
| { m_items.append(item); } |
| |
| private: |
| Item *m_parent; |
| QVector<Item *> m_items; |
| QString m_fileName; |
| }; |
| |
| struct EmptyDirective: public Directive |
| { |
| EmptyDirective(Item *item) |
| : Directive(item) {} |
| |
| virtual EmptyDirective *toEmptyDirective() const |
| { return const_cast<EmptyDirective *>(this); } |
| }; |
| |
| struct ErrorDirective: public Directive |
| { |
| ErrorDirective(Item *item) |
| : Directive(item) {} |
| |
| virtual ErrorDirective *toErrorDirective() const |
| { return const_cast<ErrorDirective *>(this); } |
| }; |
| |
| struct PragmaDirective: public Directive |
| { |
| PragmaDirective(Item *item) |
| : Directive(item) {} |
| |
| virtual PragmaDirective *toPragmaDirective() const |
| { return const_cast<PragmaDirective *>(this); } |
| }; |
| |
| struct IncludeDirective: public Directive |
| { |
| enum IncludeType {QuoteInclude, AngleBracketInclude}; |
| |
| IncludeDirective(Item *item) |
| : Directive(item), m_includeType(QuoteInclude) {} |
| |
| IncludeDirective() : Directive() {} |
| |
| virtual IncludeDirective *toIncludeDirective() const |
| { return const_cast<IncludeDirective *>(this); } |
| |
| void setFilenameTokens(const TokenEngine::TokenList &filenameTokens) |
| { m_filenameTokens = filenameTokens; } |
| |
| TokenEngine::TokenList filenameTokens() const |
| { return m_filenameTokens; } |
| |
| void setFilename(const QByteArray &filename) |
| { m_filename = filename; } |
| |
| QByteArray filename() const |
| { return m_filename;} |
| |
| void setIncludeType(IncludeType includeType) |
| { m_includeType = includeType; } |
| |
| IncludeType includeType() const |
| { return m_includeType; } |
| private: |
| TokenEngine::TokenList m_filenameTokens; |
| QByteArray m_filename; |
| IncludeType m_includeType; |
| }; |
| |
| struct ConditionalDirective: public Directive, public ItemComposite |
| { |
| inline ConditionalDirective(Item *parent = 0) |
| :Directive(parent) {} |
| |
| virtual ConditionalDirective *toConditionalDirective() const |
| { return const_cast<ConditionalDirective *>(this); } |
| |
| ItemComposite *toItemComposite() const |
| { return const_cast<ConditionalDirective *>(this); } |
| |
| virtual IfDirective *toIfDirective() const |
| { return 0; } |
| |
| virtual IfdefDirective *toIfdefDirective() const |
| { return 0; } |
| |
| virtual IfndefDirective *toIfndefDirective() const |
| { return 0; } |
| |
| virtual ElifDirective *toElifDirective() const |
| { return 0; } |
| |
| virtual ElseDirective *toElseDirective() const |
| { return 0; } |
| |
| int count() const |
| { return m_items.count(); } |
| |
| Item *item(int index) const |
| { return m_items.at(index); } |
| |
| void add(Item *item) |
| { m_items.append(item); } |
| protected: |
| QVector<Item *> m_items; |
| }; |
| |
| struct IfSection: public Item, public ItemComposite |
| { |
| IfSection(Item *parent) |
| :m_parent(parent), m_ifGroup(0), m_elseGroup(0), m_endifLine(0) {} |
| |
| IfSection *toIfSection() const |
| { return const_cast<IfSection *>(this); } |
| |
| ItemComposite *toItemComposite() const |
| { return const_cast<IfSection *>(this); } |
| |
| void setParent(Item *parent) |
| { m_parent = parent; } |
| |
| Item *parent() const |
| { return m_parent; } |
| |
| void setIfGroup(ConditionalDirective *ifGroup) |
| { m_ifGroup = ifGroup; m_items.append(ifGroup); } |
| |
| ConditionalDirective *ifGroup() const |
| { return m_ifGroup; } |
| |
| void addElifGroup(ConditionalDirective *elifGroup) |
| { m_elifGroups.append(elifGroup); m_items.append(elifGroup); } |
| |
| QVector<ConditionalDirective *> elifGroups() const |
| { return m_elifGroups; } |
| |
| void setElseGroup(ConditionalDirective *elseGroup) |
| { m_elseGroup = elseGroup; m_items.append(elseGroup); } |
| |
| ConditionalDirective *elseGroup() const |
| { return m_elseGroup; } |
| |
| void setEndifLine(Directive *endifLine) |
| { m_endifLine = endifLine; m_items.append(endifLine); } |
| |
| Directive *endifLine() const |
| { return m_endifLine; } |
| |
| int count() const |
| { return m_items.count(); } |
| |
| Item *item(int index) const |
| { return m_items.at(index);} |
| |
| private: |
| void add(Item *item) |
| { Q_UNUSED(item); } |
| |
| Item *m_parent; |
| QVector<Item *> m_items; |
| ConditionalDirective *m_ifGroup; |
| QVector<ConditionalDirective *> m_elifGroups; |
| ConditionalDirective *m_elseGroup; |
| Directive *m_endifLine; |
| }; |
| |
| struct Expression: public Item |
| { |
| enum Operator |
| { |
| LtEqOp = 300, |
| GtEqOp, |
| LtOp, |
| GtOp, |
| EqOp, |
| NotEqOp, |
| OrOp, |
| AndOp, |
| LShiftOp, |
| RShiftOp |
| }; |
| |
| inline Expression(Item *parent = 0) |
| : m_parent(parent) {} |
| |
| inline Expression *parentExpression() const |
| { return m_parent ? m_parent->toExpression() : 0; } |
| |
| virtual Item *parent() const |
| { return m_parent; } |
| |
| virtual Expression *toExpression() const |
| { return const_cast<Expression *>(this); } |
| |
| virtual UnaryExpression *toUnaryExpression() const |
| { return 0; } |
| |
| virtual BinaryExpression *toBinaryExpression() const |
| { return 0; } |
| |
| virtual StringLiteral *toStringLiteral() const |
| { return 0; } |
| |
| virtual IntLiteral *toIntLiteral() const |
| { return 0; } |
| |
| virtual MacroReference *toMacroReference() const |
| { return 0; } |
| |
| virtual MacroFunctionReference *toMacroFunctionReference() const |
| { return 0; } |
| |
| virtual ConditionalExpression *toConditionalExpression() const |
| { return 0; } |
| |
| int evaluate(bool *ok = 0); |
| |
| private: |
| Item *m_parent; |
| }; |
| |
| struct StringLiteral: public Expression |
| { |
| inline StringLiteral(const QByteArray &value, Item *parent) |
| : Expression(parent), m_value(value) {} |
| |
| QByteArray value() const |
| { return m_value; } |
| |
| virtual StringLiteral *toStringLiteral() const |
| { return const_cast<StringLiteral *>(this); } |
| |
| private: |
| QByteArray m_value; |
| }; |
| |
| struct IntLiteral: public Expression |
| { |
| inline IntLiteral(int value, Item *parent = 0) |
| : Expression(parent), m_value(value) {} |
| |
| inline int value() const |
| { return m_value; } |
| |
| virtual IntLiteral *toIntLiteral() const |
| { return const_cast<IntLiteral *>(this); } |
| |
| private: |
| int m_value; |
| }; |
| |
| struct MacroReference: public Expression |
| { |
| enum Type { |
| DefinedRef, //#if defined(foo) |
| ValueRef |
| }; |
| |
| inline MacroReference(const TokenEngine::TokenList &name, Type type, Item *parent = 0) |
| : Expression(parent), m_type(type), m_name(name) {} |
| |
| virtual MacroReference *toMacroReference() const |
| { return const_cast<MacroReference *>(this); } |
| |
| inline TokenEngine::TokenList name() const |
| { return m_name; } |
| |
| inline void setName(const TokenEngine::TokenList &name) |
| { m_name = name; } |
| |
| inline int type() const |
| { return m_type; } |
| |
| private: |
| int m_type; |
| TokenEngine::TokenList m_name; |
| }; |
| |
| struct MacroFunctionReference: public Expression |
| { |
| MacroFunctionReference(const QByteArray &name, Item *parent); |
| |
| inline QByteArray name() const |
| { return m_name; } |
| |
| inline void setName(const QByteArray &name) |
| { m_name = name; } |
| |
| inline MacroArguments *arguments() const |
| { return m_arguments; } |
| |
| virtual MacroFunctionReference *toMacroFunctionReference() const |
| { return const_cast<MacroFunctionReference *>(this); } |
| |
| private: |
| QByteArray m_name; |
| MacroArguments *m_arguments; |
| }; |
| |
| struct UnaryExpression: public Expression |
| { |
| inline UnaryExpression(int op, Expression *e, Expression *parent = 0) |
| : Expression(parent), m_op(op), m_expression(e) {} |
| |
| inline int op() const |
| { return m_op; } |
| |
| inline Expression *expression() const |
| { return m_expression; } |
| |
| virtual UnaryExpression *toUnaryExpression() const |
| { return const_cast<UnaryExpression *>(this); } |
| |
| private: |
| int m_op; |
| Expression *m_expression; |
| }; |
| |
| struct BinaryExpression: public Expression |
| { |
| inline BinaryExpression(int op, Expression *left, Expression *right, Expression *parent = 0) |
| : Expression(parent), |
| m_op(op), |
| m_leftExpression(left), |
| m_rightExpression(right) {} |
| |
| inline int op() const |
| { return m_op; } |
| |
| inline Expression *leftExpression() const |
| { return m_leftExpression; } |
| |
| inline Expression *rightExpression() const |
| { return m_rightExpression; } |
| |
| virtual BinaryExpression *toBinaryExpression() const |
| { return const_cast<BinaryExpression *>(this); } |
| |
| private: |
| int m_op; |
| Expression *m_leftExpression; |
| Expression *m_rightExpression; |
| }; |
| |
| struct ConditionalExpression: public Expression |
| { |
| inline ConditionalExpression(Expression *condition, Expression *left, Expression *right, Expression *parent = 0) |
| : Expression(parent), |
| m_condition(condition), |
| m_leftExpression(left), |
| m_rightExpression(right) {} |
| |
| inline Expression *condition() const |
| { return m_condition; } |
| |
| inline Expression *leftExpression() const |
| { return m_leftExpression; } |
| |
| inline Expression *rightExpression() const |
| { return m_rightExpression; } |
| |
| virtual ConditionalExpression *toConditionalExpression() const |
| { return const_cast<ConditionalExpression *>(this); } |
| |
| private: |
| Expression *m_condition; |
| Expression *m_leftExpression; |
| Expression *m_rightExpression; |
| }; |
| |
| |
| struct IfLikeDirective: public ConditionalDirective |
| { |
| inline IfLikeDirective(Item *parent = 0) |
| :ConditionalDirective(parent), m_expression(0) {} |
| |
| void setExpression(Expression *expression) |
| { m_expression = expression; } |
| |
| Expression *expression() const |
| { return m_expression; } |
| |
| protected: |
| Expression *m_expression; |
| }; |
| |
| struct IfDirective: public IfLikeDirective |
| { |
| inline IfDirective(Item *parent = 0) |
| :IfLikeDirective(parent) {} |
| |
| virtual IfDirective *toIfDirective() const |
| { return const_cast<IfDirective *>(this); } |
| }; |
| |
| |
| struct ElifDirective: public IfLikeDirective |
| { |
| inline ElifDirective(Item *parent = 0) |
| :IfLikeDirective(parent) {} |
| |
| virtual ElifDirective *toElifDirective() const |
| { return const_cast<ElifDirective *>(this); } |
| }; |
| |
| struct IfdefLikeDirective: public ConditionalDirective |
| { |
| inline IfdefLikeDirective(Item *parent = 0) |
| :ConditionalDirective(parent) {} |
| |
| inline TokenEngine::TokenList identifier() const |
| { return m_identifier; } |
| |
| inline void setIdentifier(const TokenEngine::TokenList &identifier) |
| { m_identifier = identifier; } |
| protected: |
| TokenEngine::TokenList m_identifier; |
| }; |
| |
| struct IfdefDirective: public IfdefLikeDirective |
| { |
| IfdefDirective(Item *parent) |
| :IfdefLikeDirective(parent) {} |
| |
| virtual IfdefDirective *toIfdefDirective() const |
| { return const_cast<IfdefDirective *>(this); } |
| }; |
| |
| struct IfndefDirective: public IfdefLikeDirective |
| { |
| inline IfndefDirective(Item *parent) |
| :IfdefLikeDirective(parent) {} |
| |
| virtual IfndefDirective *toIfndefDirective() const |
| { return const_cast<IfndefDirective *>(this); } |
| }; |
| |
| struct ElseDirective: public ConditionalDirective |
| { |
| ElseDirective(Item *parent) |
| :ConditionalDirective(parent) {} |
| |
| virtual ElseDirective *toElseDirective() const |
| { return const_cast<ElseDirective *>(this); } |
| }; |
| |
| struct EndifDirective : public Directive |
| { |
| EndifDirective(Item *parent) |
| :Directive(parent) {} |
| |
| EndifDirective *toEndifDirective() const |
| { return const_cast<EndifDirective *>(this); } |
| }; |
| |
| struct DefineDirective: public Directive |
| { |
| DefineDirective(Item *parent) |
| : Directive(parent) {}; |
| |
| inline TokenEngine::TokenList identifier() const |
| { return m_identifier; } |
| |
| inline void setIdentifier(TokenEngine::TokenList identifier) |
| { m_identifier = identifier; } |
| |
| inline void setReplacementList(TokenEngine::TokenList replacementList) |
| { m_replacementList = replacementList; } |
| |
| inline TokenEngine::TokenList replacementList() const |
| { return m_replacementList; } |
| |
| virtual DefineDirective *toDefineDirective() const |
| { return const_cast<DefineDirective *>(this); } |
| |
| virtual MacroDefinition *toMacroDefinition() const |
| { return 0; } |
| |
| virtual MacroFunctionDefinition *toMacroFunctionDefinition() const |
| { return 0; } |
| private: |
| TokenEngine::TokenList m_identifier; |
| TokenEngine::TokenList m_replacementList; |
| }; |
| |
| struct MacroDefinition: public DefineDirective |
| { |
| MacroDefinition(Item *parent) |
| : DefineDirective(parent) {}; |
| |
| virtual MacroDefinition *toMacroDefinition() const |
| { return const_cast<MacroDefinition *>(this); } |
| }; |
| |
| struct MacroFunctionDefinition: public DefineDirective |
| { |
| MacroFunctionDefinition(Item *parent) |
| : DefineDirective(parent) {} |
| |
| virtual MacroFunctionDefinition *toMacroFunctionDefinition() const |
| { return const_cast<MacroFunctionDefinition *>(this); } |
| |
| void setParameters(TokenEngine::TokenList macroParameters) |
| { m_parameters = macroParameters;} |
| |
| inline TokenEngine::TokenList parameters() const |
| { return m_parameters; } |
| |
| private: |
| TokenEngine::TokenList m_parameters; |
| }; |
| |
| struct MacroParameter: public Item |
| { |
| inline MacroParameter(Item *parent) |
| : m_parent(parent) {} |
| |
| inline QByteArray name() const |
| { return m_name; } |
| |
| inline void setName(const QByteArray &name) |
| { m_name = name; } |
| |
| virtual Item *parent() const |
| { return m_parent; } |
| |
| private: |
| Item *m_parent; |
| QByteArray m_name; |
| }; |
| |
| struct MacroParameters: public Item, public ItemComposite |
| { |
| MacroParameters(MacroFunctionDefinition *parent) |
| : m_parent(parent) {} |
| |
| ItemComposite *toItemComposite() const |
| { return const_cast<MacroParameters *>(this); } |
| |
| virtual Item *parent() const |
| { return m_parent; } |
| |
| virtual int count() const |
| { return m_items.count(); } |
| |
| virtual Item *item(int index) const |
| { return m_items.at(index); } |
| |
| void addParameter(MacroParameter *param) |
| { Q_ASSERT(param->parent() == this); m_items.append(param); } |
| |
| int indexOf(const QByteArray ¶m) const |
| { |
| for (int i=0; i<m_items.count(); ++i) { |
| // cout <<"checking |" << param.constData() << "| against |" << m_items.at(i)->name().constData() <<"|" << endl; |
| if (m_items.at(i)->name() == param) |
| return i; |
| } |
| return -1; |
| } |
| |
| inline bool contains(const QByteArray ¶m) const |
| { return indexOf(param) != -1; } |
| /* |
| void add(const QByteArray ¶m) |
| { |
| MacroParameter *p = createNode<MacroParameter>(this); |
| p->setName(param); |
| addParameter(p); |
| } |
| */ |
| private: |
| MacroFunctionDefinition *m_parent; |
| QVector<MacroParameter*> m_items; |
| }; |
| |
| struct UndefDirective: public Directive |
| { |
| UndefDirective(Item *parent) |
| :Directive(parent) {} |
| |
| inline TokenEngine::TokenList identifier() const |
| { return m_identifier; } |
| |
| inline void setIdentifier(const TokenEngine::TokenList &identifier) |
| { m_identifier = identifier; } |
| |
| virtual UndefDirective *toUndefDirective() const |
| { return const_cast<UndefDirective *>(this); } |
| private: |
| TokenEngine::TokenList m_identifier; |
| }; |
| |
| struct LineDirective: public Directive |
| { |
| LineDirective(Item *parent) |
| :Directive(parent) {} |
| |
| virtual LineDirective *toLineDirective() const |
| { return const_cast<LineDirective *>(this); } |
| }; |
| |
| struct NonDirective: public Directive |
| { |
| NonDirective(Item *parent) |
| :Directive(parent) {} |
| |
| virtual NonDirective *toNonDirective() const |
| { return const_cast<NonDirective *>(this); } |
| }; |
| |
| class Preprocessor : public QObject |
| { |
| Q_OBJECT |
| public: |
| Preprocessor(); |
| Source *parse(const TokenEngine::TokenContainer &tokenContainer, |
| const QVector<Type> &tokenTypeList, TypedPool<Item> *memoryPool); |
| signals: |
| void error(const QString type, const QString message); |
| private: |
| bool parseGroup(Item *node); |
| bool parseGroupPart(Item *node); |
| |
| bool parseIfSection(Item *node); |
| bool parseNonDirective(Item *node); |
| bool parseTextLine(Item *node); |
| |
| bool parseIfGroup(IfSection *node); |
| bool parseElifGroups(IfSection *node); |
| bool parseElifGroup(IfSection *node); |
| bool parseElseGroup(IfSection *node); |
| bool parseEndifLine(IfSection *node); |
| |
| bool parseIfdefLikeDirective(IfdefLikeDirective *node); |
| bool parseIfLikeDirective(IfLikeDirective *node); |
| |
| bool parseDefineDirective(Item *node); |
| bool parseUndefDirective(Item *node); |
| bool parseIncludeDirective(Item *node); |
| bool parseErrorDirective(Item *node); |
| bool parsePragmaDirective(Item*node); |
| |
| TokenEngine::TokenSection readLine(); |
| inline bool isValidIndex(const int index) const; |
| inline bool isWhiteSpace(const int index) const; |
| Type lookAhead() const; |
| Type lookAheadSkipHash() const; |
| inline int skipWhiteSpaceAndComments() const; |
| inline int skipWhiteSpaceCommentsHash() const; |
| QVector<int> cleanEscapedNewLines(const TokenEngine::TokenSection &tokenSection) const; |
| QVector<int> cleanTokenRange(const TokenEngine::TokenSection &tokenSection) const; |
| |
| Source *m_source; |
| TokenEngine::TokenContainer m_tokenContainer; |
| QVector<Type> m_tokenTypeList; |
| TypedPool<Item> *m_memoryPool; |
| int lexerTokenIndex; |
| int numTokens; |
| }; |
| |
| /* |
| T must be a subclass of Item, parent must implment |
| the ItemComposite interface |
| */ |
| template <typename T> |
| T *createNode(TypedPool<Item> *memPool, Item *parent) |
| { |
| Q_ASSERT(parent); |
| T* node = new (memPool->allocate(sizeof(T))) T(parent); |
| Q_ASSERT(node); |
| return node; |
| } |
| |
| template <typename T> |
| T *createNode(TypedPool<Item> *memPool) |
| { |
| T* node = new (memPool->allocate(sizeof(T))) T(0); |
| Q_ASSERT(node); |
| return node; |
| } |
| |
| |
| QByteArray visitGetText(Item *item); |
| |
| } // namespace Rpp |
| |
| QT_END_NAMESPACE |
| |
| #endif |