File indexing completed on 2024-04-14 04:31:32

0001 /* This file is part of kdev-pg-qt
0002    Copyright (C) 2005 Roberto Raggi <roberto@kdevelop.org>
0003    Copyright (C) 2006 Jakob Petsovits <jpetso@gmx.at>
0004    Copyright (C) 2010 Jonathan Schmidt-Dominé <devel@the-user.org>
0005 
0006    This library is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU Library General Public
0008    License as published by the Free Software Foundation; either
0009    version 2 of the License, or (at your option) any later version.
0010 
0011    This library is distributed in the hope that it will be useful,
0012    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014    Library General Public License for more details.
0015 
0016    You should have received a copy of the GNU Library General Public License
0017    along with this library; see the file COPYING.LIB.  If not, write to
0018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019    Boston, MA 02110-1301, USA.
0020 */
0021 
0022 #ifndef KDEV_PG_AST_H
0023 #define KDEV_PG_AST_H
0024 
0025 #include "kdev-pg-allocator.h"
0026 #include "kdev-pg-memory-pool.h"
0027 
0028 #include <vector>
0029 #include <utility>
0030 using std::vector;
0031 using std::pair;
0032 using std::make_pair;
0033 
0034 #include <QString>
0035 
0036 #include <QDebug>
0037 
0038 #define PG_NODE(k) \
0039     enum { NodeKind = NodeKind##k };
0040 
0041 namespace KDevPG
0042 {
0043 
0044 // the kdev-pg calculus
0045 namespace Model
0046 {
0047 
0048   enum NodeKind {
0049     NodeKindItem = 0,
0050     NodeKindZero = 1,
0051     NodeKindPlus = 2,
0052     NodeKindStar = 3,
0053     NodeKindSymbol = 4,
0054     NodeKindAction = 5,
0055     NodeKindAlternative = 6,
0056     NodeKindCons = 7,
0057     NodeKindEvolve = 8,
0058     NodeKindTryCatch = 9,
0059     NodeKindAlias = 10,
0060     NodeKindTerminal = 11,
0061     NodeKindNonTerminal = 12,
0062     NodeKindAnnotation = 13,
0063     NodeKindCondition = 14,
0064     NodeKindVariableDeclaration = 15,
0065     NodeKindOperator = 16,
0066     NodeKindInlinedNonTerminal = 17,
0067 
0068     NodeKindLast
0069   };
0070 
0071   class Node
0072   {
0073   public:
0074     PG_NODE(Item)
0075 
0076     int kind;
0077   };
0078 
0079   class ZeroItem: public Node
0080   {
0081   public:
0082     PG_NODE(Zero)
0083   };
0084 
0085   class PlusItem: public Node
0086   {
0087   public:
0088     PG_NODE(Plus)
0089 
0090     Node *mItem;
0091   };
0092 
0093   class StarItem: public Node
0094   {
0095   public:
0096     PG_NODE(Star)
0097 
0098     Node *mItem;
0099   };
0100 
0101   class SymbolItem: public Node
0102   {
0103   public:
0104     PG_NODE(Symbol)
0105 
0106     QString mName;
0107     QString mCapitalizedName;
0108   };
0109 
0110   class ActionItem: public Node
0111   {
0112   public:
0113     PG_NODE(Action)
0114 
0115     Node *mItem;
0116     QString mCode;
0117   };
0118 
0119   class AlternativeItem: public Node
0120   {
0121   public:
0122     PG_NODE(Alternative)
0123 
0124     Node *mLeft;
0125     Node *mRight;
0126   };
0127 
0128   class ConsItem: public Node
0129   {
0130   public:
0131     PG_NODE(Cons)
0132 
0133     Node *mLeft;
0134     Node *mRight;
0135   };
0136 
0137   class TryCatchItem: public Node
0138   {
0139   public:
0140     PG_NODE(TryCatch)
0141 
0142     Node *mTryItem;
0143     Node *mCatchItem; // contains 0 for "catch(recover)"
0144     bool mUnsafe;
0145   };
0146 
0147   class AliasItem: public Node
0148   {
0149   public:
0150     PG_NODE(Alias)
0151 
0152     QString mCode;
0153     SymbolItem *mSymbol;
0154   };
0155   
0156   class InlinedNonTerminalItem: public Node
0157   {
0158   public:
0159     PG_NODE(InlinedNonTerminal)
0160     
0161     SymbolItem *mSymbol;
0162   };
0163 
0164   class TerminalItem: public Node
0165   {
0166   public:
0167     PG_NODE(Terminal)
0168 
0169     QString mName;
0170     QString mDescription;
0171   };
0172 
0173   class NonTerminalItem: public Node
0174   {
0175   public:
0176     PG_NODE(NonTerminal)
0177 
0178     SymbolItem *mSymbol;
0179     QString mArguments;
0180   };
0181   
0182   class Operator
0183   {
0184   public:
0185     Node *mTok;
0186     QString mCond, mCode;
0187   };
0188   
0189   class OperatorItem : public Node
0190   {
0191   public:
0192     PG_NODE(Operator)
0193     
0194     struct TernDescription
0195     {
0196       Operator first, second;
0197       QString left;
0198       QString priority;
0199     };
0200     struct BinDescription
0201     {
0202       Operator op;
0203       QString left;
0204       QString priority;
0205     };
0206     struct UnaryDescription
0207     {
0208       Operator op;
0209       QString priority;
0210     };
0211     struct ParenDescription
0212     {
0213       Operator first, second;
0214     };
0215     QString mName;
0216     NonTerminalItem *mBase;
0217     vector< ParenDescription > mParen;
0218     vector< TernDescription > mTern;
0219     vector< BinDescription > mBin, mPost;
0220     vector< UnaryDescription > mPre;
0221     
0222     inline void pushParen(const Operator& op1, const Operator& op2)
0223     {
0224       ParenDescription d;
0225       d.first = op1;
0226       d.second = op2;
0227       mParen.push_back(d);
0228     }
0229     inline void pushPre(const Operator& op, const QString& priority)
0230     {
0231       UnaryDescription d;
0232       d.op = op;
0233       d.priority = priority;
0234       mPre.push_back(d);
0235     }
0236     inline void pushPost(const Operator& op, const QString& left, const QString& priority)
0237     {
0238       BinDescription d;
0239       d.op = op;
0240       d.priority = priority;
0241       d.left = left;
0242       mPost.push_back(d);
0243     }
0244     inline void pushBin(const Operator& op, const QString& left, const QString& priority)
0245     {
0246       BinDescription d;
0247       d.op = op;
0248       d.left = left;
0249       d.priority = priority;
0250       mBin.push_back(d);
0251     }
0252     inline void pushTern(const Operator& op1, const Operator& op2, const QString& left, const QString& priority)
0253     {
0254       TernDescription d;
0255       d.first = op1;
0256       d.second = op2;
0257       d.left = left;
0258       d.priority = priority;
0259       mTern.push_back(d);
0260     }
0261   };
0262 
0263   class VariableDeclarationItem: public Node
0264   {
0265   public:
0266     PG_NODE(VariableDeclaration)
0267 
0268     enum DeclarationType {
0269       DeclarationArgument,
0270       DeclarationLocal
0271     };
0272 
0273     enum StorageType {
0274       StorageAstMember,
0275       StorageTemporary
0276     };
0277 
0278     enum VariableType {
0279       TypeNode,
0280       TypeToken,
0281       TypeVariable
0282     };
0283 
0284     QString mType;
0285     QString mCapitalizedType;
0286     QString mName;
0287 
0288     DeclarationType mDeclarationType;
0289     StorageType     mStorageType;
0290     VariableType    mVariableType;
0291     bool            mIsSequence;
0292 
0293     VariableDeclarationItem *mNext;
0294   };
0295 
0296   class AnnotationItem: public Node
0297   {
0298   public:
0299     PG_NODE(Annotation)
0300 
0301     Node *mItem;
0302     VariableDeclarationItem *mDeclaration;
0303   };
0304 
0305   class ConditionItem: public Node
0306   {
0307   public:
0308     PG_NODE(Condition)
0309 
0310     QString mCode;
0311     Node *mItem;
0312   };
0313 
0314   class EvolveItem: public Node
0315   {
0316   public:
0317     PG_NODE(Evolve)
0318 
0319     Node *mItem;
0320     SymbolItem *mSymbol;
0321     VariableDeclarationItem *mDeclarations;
0322     QString mCode;
0323   };
0324 
0325 } // namespace model
0326 
0327 
0328 // configuration stuff outside the model
0329 namespace Settings
0330 {
0331 
0332   enum NodeKind {
0333     NodeKindMember = 30,
0334 
0335     NodeKindLast
0336   };
0337 
0338   class MemberItem: public Model::Node
0339   {
0340   public:
0341     PG_NODE(Member)
0342 
0343     enum MemberKind {
0344       PublicDeclaration    = 1,
0345       ProtectedDeclaration = 2,
0346       PrivateDeclaration   = 4,
0347       ConstructorCode      = 8,
0348       DestructorCode       = 16
0349     };
0350 
0351     MemberKind mMemberKind;
0352     QString mCode;
0353   };
0354 
0355 } // namespace settings
0356 
0357 template<class T>
0358 struct StripPtr { typedef T Result; };
0359 template<class T>
0360 struct StripPtr<T*> { typedef T Result; };
0361 
0362 template <class _Tp>
0363 _Tp nodeCast(Model::Node *item)
0364 {
0365   if (StripPtr<_Tp>::Result::NodeKind == item->kind)
0366     return static_cast<_Tp>(item);
0367 
0368   return nullptr;
0369 }
0370 
0371 extern KDevPG::Allocator<char> globalMemoryPool;
0372 
0373 template <class _Tp>
0374 _Tp *createNode()
0375 {
0376   _Tp *node = new (globalMemoryPool.allocate(sizeof(_Tp)))_Tp();
0377   node->kind = _Tp::NodeKind;
0378   return node;
0379 }
0380 
0381 
0382 }
0383 
0384 
0385 #endif // KDEV_PG_AST_H