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

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 }