File indexing completed on 2024-04-28 08:27:18
0001 /* This file is part of kdev-pg-qt 0002 Copyright (C) 2010 Jonathan Schmidt-Dominé <devel@the-user.org> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "kdev-pg-bnf-visitor.h" 0021 0022 using namespace KDevPG; 0023 0024 bool BnfVisitor::isInternal(Model::Node* item) 0025 { 0026 return localMemoryPool.contains(item); 0027 } 0028 0029 template<typename _Tp> 0030 inline _Tp* BnfVisitor::localCreateNode() 0031 { 0032 _Tp *node = new (localMemoryPool.allocate(sizeof(_Tp)))_Tp(); 0033 node->kind = _Tp::NodeKind; 0034 return node; 0035 } 0036 0037 template<typename _Tp> 0038 inline _Tp* BnfVisitor::createArray(qint64 size) 0039 { 0040 return reinterpret_cast<_Tp*>(localMemoryPool.allocate(size * sizeof(_Tp))); 0041 } 0042 0043 template<typename _Tp> 0044 inline _Tp* BnfVisitor::getSubArray(void* mem, qint64 s) 0045 { 0046 _Tp *arr = reinterpret_cast<_Tp*>(mem); 0047 for(qint64 i = 0; i != s; ++i) 0048 arr[i].kind = _Tp::NodeKind; 0049 return arr; 0050 } 0051 0052 KDevPG::Allocator<char> KDevPG::BnfVisitor::localMemoryPool; 0053 0054 QHash<Model::OperatorItem*, Model::Node*> KDevPG::BnfVisitor::mOpStuff; 0055 QHash<Model::StarItem*, Model::Node*> KDevPG::BnfVisitor::mStarStuff; 0056 QHash<Model::PlusItem*, Model::Node*> KDevPG::BnfVisitor::mPlusStuff; 0057 0058 void KDevPG::BnfVisitor::visitInlinedNonTerminal(Model::InlinedNonTerminalItem* node) 0059 { 0060 Model::EvolveItem *rule = globalSystem.searchRule(node->mSymbol); 0061 0062 preCopy(rule, node); 0063 preCopy(node->mSymbol, node); 0064 0065 // visitNode(rule); 0066 0067 copy(node->mSymbol, node); 0068 copy(rule, node); 0069 } 0070 0071 void KDevPG::BnfVisitor::visitNonTerminal(Model::NonTerminalItem* node) 0072 { 0073 Model::EvolveItem *rule = globalSystem.searchRule(node->mSymbol); 0074 0075 preCopy(rule, node); 0076 preCopy(node->mSymbol, node); 0077 0078 // visitNode(rule); 0079 0080 copy(node->mSymbol, node); 0081 copy(rule, node); 0082 } 0083 0084 void KDevPG::BnfVisitor::visitPlus(Model::PlusItem* node) 0085 { 0086 if(mPlusStuff.contains(node)) 0087 { 0088 preCopy(mPlusStuff[node], node); 0089 DefaultVisitor::visitNode(mPlusStuff[node]); 0090 copy(mPlusStuff[node], node); 0091 return; 0092 } 0093 Model::ConsItem *c = localCreateNode<Model::ConsItem>(); 0094 Model::AlternativeItem *a = localCreateNode<Model::AlternativeItem>(); 0095 c->mLeft = node->mItem; 0096 c->mRight = a; 0097 a->mLeft = globalSystem.zero(); 0098 a->mRight = c; 0099 0100 preCopy(c, node); 0101 0102 DefaultVisitor::visitNode(c); 0103 0104 mPlusStuff[node] = c; 0105 0106 copy(c, node); 0107 } 0108 0109 void KDevPG::BnfVisitor::visitStar(Model::StarItem* node) 0110 { 0111 if(mStarStuff.contains(node)) 0112 { 0113 preCopy(mStarStuff[node], node); 0114 DefaultVisitor::visitNode(mStarStuff[node]); 0115 copy(mStarStuff[node], node); 0116 return; 0117 } 0118 Model::ConsItem *c = localCreateNode<Model::ConsItem>(); 0119 Model::AlternativeItem *a = localCreateNode<Model::AlternativeItem>(); 0120 c->mLeft = node->mItem; 0121 c->mRight = a; 0122 a->mLeft = globalSystem.zero(); 0123 a->mRight = c; 0124 0125 preCopy(a, node); 0126 0127 DefaultVisitor::visitNode(a); 0128 0129 mStarStuff[node] = a; 0130 0131 copy(a, node); 0132 } 0133 0134 void KDevPG::BnfVisitor::visitOperator(Model::OperatorItem* node) 0135 { 0136 if(mOpStuff.contains(node)) 0137 { 0138 preCopy(mOpStuff[node], node); 0139 DefaultVisitor::visitNode(mOpStuff[node]); 0140 copy(mOpStuff[node], node); 0141 } 0142 else 0143 { 0144 void *mem = localMemoryPool.allocate( 0145 (node->mPre.size() * 1 0146 + node->mBin.size() * 2 0147 + node->mPost.size() * 1 0148 + node->mParen.size() * 2 0149 + node->mTern.size() * 4) * sizeof(Model::ConsItem) 0150 + (node->mPre.size() * 1 0151 + node->mBin.size() * 1 0152 + node->mPost.size() * 1 0153 + node->mParen.size() * 1 0154 + node->mTern.size() * 1) * sizeof(Model::AlternativeItem) 0155 ); 0156 Model::ConsItem *tmpPre = getSubArray<Model::ConsItem>(mem, node->mPre.size()); 0157 Model::ConsItem *tmpBinRight = getSubArray<Model::ConsItem>(tmpPre + node->mPre.size(), node->mBin.size()); 0158 Model::ConsItem *tmpBin = getSubArray<Model::ConsItem>(tmpBinRight + node->mBin.size(), node->mBin.size()); 0159 Model::ConsItem *tmpPost = getSubArray<Model::ConsItem>(tmpBin + node->mBin.size(), node->mPost.size()); 0160 Model::ConsItem *tmpParenRight = getSubArray<Model::ConsItem>(tmpPost + node->mPost.size(), node->mParen.size()); 0161 Model::ConsItem *tmpParen = getSubArray<Model::ConsItem>(tmpParenRight + node->mParen.size(), node->mParen.size()); 0162 Model::ConsItem *tmpTern3 = getSubArray<Model::ConsItem>(tmpParen + node->mParen.size(), node->mTern.size()); 0163 Model::ConsItem *tmpTern2 = getSubArray<Model::ConsItem>(tmpTern3 + node->mTern.size(), node->mTern.size()); 0164 Model::ConsItem *tmpTern1 = getSubArray<Model::ConsItem>(tmpTern2 + node->mTern.size(), node->mTern.size()); 0165 Model::ConsItem *tmpTern = getSubArray<Model::ConsItem>(tmpTern1 + node->mTern.size(), node->mTern.size()); 0166 int i = node->mPre.size() + node->mPost.size() + node->mBin.size() + node->mTern.size() + node->mParen.size(); 0167 Model::AlternativeItem *tmp = getSubArray<Model::AlternativeItem>(tmpTern + node->mTern.size(), i); 0168 Model::Node *last = node->mBase; 0169 for(size_t j = 0; j != node->mPre.size(); ++j) 0170 { 0171 tmpPre[j].mLeft = node->mPre[j].op.mTok; 0172 tmpPre[j].mRight = tmp+0; 0173 tmpPre[j].kind = Model::NodeKindCons; 0174 0175 --i; 0176 tmp[i].kind = Model::NodeKindAlternative; 0177 tmp[i].mRight = last; 0178 tmp[i].mLeft = tmpPre+j; 0179 last = tmp+i; 0180 } 0181 for(size_t j = 0; j != node->mPost.size(); ++j) 0182 { 0183 tmpPost[j].mLeft = tmp+0; 0184 tmpPost[j].mRight = node->mPost[j].op.mTok; 0185 tmpPost[j].kind = Model::NodeKindCons; 0186 0187 --i; 0188 tmp[i].kind = Model::NodeKindAlternative; 0189 tmp[i].mRight = last; 0190 tmp[i].mLeft = tmpPost+j; 0191 last = tmp+i; 0192 } 0193 for(size_t j = 0; j != node->mBin.size(); ++j) 0194 { 0195 tmpBinRight[j].mLeft = node->mBin[j].op.mTok; 0196 tmpBinRight[j].mRight = tmp+0; 0197 tmpBinRight[j].kind = Model::NodeKindCons; 0198 tmpBin[j].mLeft = tmp+0; 0199 tmpBin[j].mRight = tmpBinRight+j; 0200 tmpBin[j].kind = Model::NodeKindCons; 0201 0202 --i; 0203 tmp[i].kind = Model::NodeKindAlternative; 0204 tmp[i].mRight = last; 0205 tmp[i].mLeft = tmpBin+j; 0206 last = tmp+i; 0207 } 0208 for(size_t j = 0; j != node->mTern.size(); ++j) 0209 { 0210 tmpTern3[j].mLeft = node->mTern[j].second.mTok; 0211 tmpTern3[j].mRight = tmp+0; 0212 tmpTern3[j].kind = Model::NodeKindCons; 0213 tmpTern2[j].mLeft = tmp+0; 0214 tmpTern2[j].mRight = tmpTern3+j; 0215 tmpTern2[j].kind = Model::NodeKindCons; 0216 tmpTern1[j].mLeft = node->mTern[j].first.mTok; 0217 tmpTern1[j].mRight = tmpTern2+j; 0218 tmpTern1[j].kind = Model::NodeKindCons; 0219 tmpTern[j].mLeft = tmp+0; 0220 tmpTern[j].mRight = tmpTern1+j; 0221 tmpTern[j].kind = Model::NodeKindCons; 0222 0223 --i; 0224 tmp[i].kind = Model::NodeKindAlternative; 0225 tmp[i].mRight = last; 0226 tmp[i].mLeft = tmpTern+j; 0227 last = tmp+i; 0228 } 0229 for(size_t j = 0; j != node->mParen.size(); ++j) 0230 { 0231 tmpParenRight[j].mLeft = tmp+0; 0232 tmpParenRight[j].mRight = node->mParen[j].second.mTok; 0233 tmpParenRight[j].kind = Model::NodeKindCons; 0234 tmpParen[j].mLeft = node->mParen[j].first.mTok; 0235 tmpParen[j].mRight = tmpParenRight+j; 0236 tmpParen[j].kind = Model::NodeKindCons; 0237 0238 --i; 0239 tmp[i].kind = Model::NodeKindAlternative; 0240 tmp[i].mRight = last; 0241 tmp[i].mLeft = tmpParen+j; 0242 last = tmp+i; 0243 } 0244 0245 mOpStuff[node] = last; 0246 0247 preCopy(last, node); 0248 0249 DefaultVisitor::visitNode(last); 0250 0251 copy(last, node); 0252 } 0253 } 0254 0255 void BnfVisitor::visitAnnotation(Model::AnnotationItem* node) 0256 { 0257 preCopy(node->mItem, node); 0258 0259 KDevPG::DefaultVisitor::visitAnnotation(node); 0260 0261 copy(node->mItem, node); 0262 } 0263 0264 void BnfVisitor::visitCondition(Model::ConditionItem* node) 0265 { 0266 preCopy(node->mItem, node); 0267 0268 KDevPG::DefaultVisitor::visitCondition(node); 0269 0270 copy(node->mItem, node); 0271 } 0272 0273 void BnfVisitor::visitAction(Model::ActionItem* node) 0274 { 0275 preCopy(node->mItem, node); 0276 0277 KDevPG::DefaultVisitor::visitNode(node->mItem); 0278 0279 copy(node->mItem, node); 0280 } 0281 0282 void BnfVisitor::visitTryCatch(Model::TryCatchItem* node) 0283 { 0284 if(node->mCatchItem == nullptr) 0285 { 0286 preCopy(node->mTryItem, node); 0287 0288 DefaultVisitor::visitNode(node->mTryItem); 0289 0290 copy(node->mTryItem, node); 0291 } 0292 else // A little bit dirty, please do not change the layout ;) 0293 visitAlternative(reinterpret_cast<Model::AlternativeItem*>(node)); 0294 } 0295 0296 void BnfVisitor::visitEvolve(Model::EvolveItem* node) 0297 { 0298 preCopy(node, node->mSymbol); 0299 preCopy(node->mItem, node); 0300 0301 visitNode(node->mItem); 0302 0303 copy(node->mItem, node); 0304 copy(node, node->mSymbol); 0305 } 0306 0307 void KDevPG::BnfVisitor::finished() 0308 { 0309 // localMemoryPool.~Allocator(); 0310 // new (&localMemoryPool) Allocator<char>; 0311 }