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