ASTFactory.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include "antlr/CommonAST.hpp"
00009 #include "antlr/ANTLRException.hpp"
00010 #include "antlr/IOException.hpp"
00011 #include "antlr/ASTFactory.hpp"
00012 #include "antlr/ANTLRUtil.hpp"
00013
00014 #include <iostream>
00015
00016 using namespace std;
00017
00018 #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
00019 namespace antlr {
00020 #endif
00021
00037
00038 ASTFactory::ASTFactory()
00039 : default_factory_descriptor(ANTLR_USE_NAMESPACE(std)make_pair(static_cast<const char*>("CommonAST"),&CommonAST::factory))
00040 {
00041 nodeFactories.resize( Token::MIN_USER_TYPE, &default_factory_descriptor );
00042 }
00043
00048 ASTFactory::ASTFactory( const char* factory_node_name, factory_type fact )
00049 : default_factory_descriptor(ANTLR_USE_NAMESPACE(std)make_pair(factory_node_name, fact))
00050 {
00051 nodeFactories.resize( Token::MIN_USER_TYPE, &default_factory_descriptor );
00052 }
00053
00055 ASTFactory::~ASTFactory()
00056 {
00057 factory_descriptor_list::iterator i = nodeFactories.begin();
00058
00059 while( i != nodeFactories.end() )
00060 {
00061 if( *i != &default_factory_descriptor )
00062 delete *i;
00063 i++;
00064 }
00065 }
00066
00068 void ASTFactory::registerFactory( int type, const char* ast_name, factory_type factory )
00069 {
00070
00071 if( type < Token::MIN_USER_TYPE )
00072 throw ANTLRException("Internal parser error invalid type passed to RegisterFactory");
00073 if( factory == 0 )
00074 throw ANTLRException("Internal parser error 0 factory passed to RegisterFactory");
00075
00076
00077
00078 if( nodeFactories.size() < (static_cast<unsigned int>(type)+1) )
00079 nodeFactories.resize( type+1, &default_factory_descriptor );
00080
00081
00082 nodeFactories[type] = new ANTLR_USE_NAMESPACE(std)pair<const char*, factory_type>( ast_name, factory );
00083 }
00084
00085 void ASTFactory::setMaxNodeType( int type )
00086 {
00087 if( nodeFactories.size() < (static_cast<unsigned int>(type)+1) )
00088 nodeFactories.resize( type+1, &default_factory_descriptor );
00089 }
00090
00094 RefAST ASTFactory::create()
00095 {
00096 RefAST node = nodeFactories[0]->second();
00097 node->setType(Token::INVALID_TYPE);
00098 return node;
00099 }
00100
00101 RefAST ASTFactory::create(int type)
00102 {
00103 RefAST t = nodeFactories[type]->second();
00104 t->initialize(type,"");
00105 return t;
00106 }
00107
00108 RefAST ASTFactory::create(int type, const ANTLR_USE_NAMESPACE(std)string& txt)
00109 {
00110 RefAST t = nodeFactories[type]->second();
00111 t->initialize(type,txt);
00112 return t;
00113 }
00114
00115 #ifdef ANTLR_SUPPORT_XML
00116 RefAST ASTFactory::create(const ANTLR_USE_NAMESPACE(std)string& type_name, ANTLR_USE_NAMESPACE(std)istream& infile )
00117 {
00118 factory_descriptor_list::iterator fact = nodeFactories.begin();
00119
00120 while( fact != nodeFactories.end() )
00121 {
00122 if( type_name == (*fact)->first )
00123 {
00124 RefAST t = (*fact)->second();
00125 t->initialize(infile);
00126 return t;
00127 }
00128 fact++;
00129 }
00130
00131 string error = "ASTFactory::create: Unknown AST type '" + type_name + "'";
00132 throw ANTLRException(error);
00133 }
00134 #endif
00135
00139 RefAST ASTFactory::create(RefAST tr)
00140 {
00141 if (!tr)
00142 return nullAST;
00143
00144
00145
00146 RefAST t = nodeFactories[tr->getType()]->second();
00147 t->initialize(tr);
00148 return t;
00149 }
00150
00151 RefAST ASTFactory::create(RefToken tok)
00152 {
00153
00154 RefAST t = nodeFactories[tok->getType()]->second();
00155 t->initialize(tok);
00156 return t;
00157 }
00158
00160 void ASTFactory::addASTChild(ASTPair& currentAST, RefAST child)
00161 {
00162 if (child)
00163 {
00164 if (!currentAST.root)
00165 {
00166
00167 currentAST.root = child;
00168 }
00169 else
00170 {
00171 if (!currentAST.child)
00172 {
00173
00174 currentAST.root->setFirstChild(child);
00175 }
00176 else
00177 {
00178 currentAST.child->setNextSibling(child);
00179 }
00180 }
00181
00182 currentAST.child = child;
00183 currentAST.advanceChildToEnd();
00184 }
00185 }
00186
00190 RefAST ASTFactory::dup(RefAST t)
00191 {
00192 if( t )
00193 return t->clone();
00194 else
00195 return RefAST(nullASTptr);
00196 }
00197
00199 RefAST ASTFactory::dupList(RefAST t)
00200 {
00201 RefAST result = dupTree(t);
00202 RefAST nt = result;
00203
00204 while( t )
00205 {
00206 t = t->getNextSibling();
00207 nt->setNextSibling(dupTree(t));
00208 nt = nt->getNextSibling();
00209 }
00210 return result;
00211 }
00212
00216 RefAST ASTFactory::dupTree(RefAST t)
00217 {
00218 RefAST result = dup(t);
00219
00220 if( t )
00221 result->setFirstChild( dupList(t->getFirstChild()) );
00222 return result;
00223 }
00224
00231 RefAST ASTFactory::make(ANTLR_USE_NAMESPACE(std)vector<RefAST>& nodes)
00232 {
00233 if ( nodes.size() == 0 )
00234 return RefAST(nullASTptr);
00235
00236 RefAST root = nodes[0];
00237 RefAST tail = RefAST(nullASTptr);
00238
00239 if( root )
00240 root->setFirstChild(RefAST(nullASTptr));
00241
00242
00243 for( unsigned int i = 1; i < nodes.size(); i++ )
00244 {
00245 if ( nodes[i] == 0 )
00246 continue;
00247
00248 if ( root == 0 )
00249 root = tail = nodes[i];
00250 else if ( tail == 0 )
00251 {
00252 root->setFirstChild(nodes[i]);
00253 tail = root->getFirstChild();
00254 }
00255 else
00256 {
00257 tail->setNextSibling(nodes[i]);
00258 tail = tail->getNextSibling();
00259 }
00260
00261 if( tail )
00262 {
00263
00264 while (tail->getNextSibling())
00265 tail = tail->getNextSibling();
00266 }
00267 }
00268
00269 return root;
00270 }
00271
00275 RefAST ASTFactory::make(ASTArray* nodes)
00276 {
00277 RefAST ret = make(nodes->array);
00278 delete nodes;
00279 return ret;
00280 }
00281
00283 void ASTFactory::makeASTRoot( ASTPair& currentAST, RefAST root )
00284 {
00285 if (root)
00286 {
00287
00288 root->addChild(currentAST.root);
00289
00290 currentAST.child = currentAST.root;
00291 currentAST.advanceChildToEnd();
00292
00293 currentAST.root = root;
00294 }
00295 }
00296
00297 void ASTFactory::setASTNodeFactory( const char* factory_node_name,
00298 factory_type factory )
00299 {
00300 default_factory_descriptor.first = factory_node_name;
00301 default_factory_descriptor.second = factory;
00302 }
00303
00304 #ifdef ANTLR_SUPPORT_XML
00305 bool ASTFactory::checkCloseTag( ANTLR_USE_NAMESPACE(std)istream& in )
00306 {
00307 char ch;
00308
00309 if( in.get(ch) )
00310 {
00311 if( ch == '<' )
00312 {
00313 char ch2;
00314 if( in.get(ch2) )
00315 {
00316 if( ch2 == '/' )
00317 {
00318 in.putback(ch2);
00319 in.putback(ch);
00320 return true;
00321 }
00322 in.putback(ch2);
00323 in.putback(ch);
00324 return false;
00325 }
00326 }
00327 in.putback(ch);
00328 return false;
00329 }
00330 return false;
00331 }
00332
00333 void ASTFactory::loadChildren( ANTLR_USE_NAMESPACE(std)istream& infile,
00334 RefAST current )
00335 {
00336 char ch;
00337
00338 for(;;)
00339 {
00340 eatwhite(infile);
00341
00342 infile.get(ch);
00343 if( ch != '<' )
00344 {
00345 string error = "Invalid XML file... no '<' found (";
00346 error += ch + ")";
00347 throw IOException(error);
00348 }
00349
00350 infile.get(ch);
00351
00352 if( ch == '/' )
00353 {
00354 string temp;
00355
00356
00357 temp = read_identifier( infile );
00358
00359 if( strcmp(temp.c_str(), current->typeName() ) != 0 )
00360 {
00361 string error = "Invalid XML file... close tag does not match start tag: ";
00362 error += current->typeName();
00363 error += " closed by " + temp;
00364 throw IOException(error);
00365 }
00366
00367 infile.get(ch);
00368
00369 if( ch != '>' )
00370 {
00371 string error = "Invalid XML file... no '>' found (";
00372 error += ch + ")";
00373 throw IOException(error);
00374 }
00375
00376 break;
00377 }
00378
00379
00380 infile.putback(ch);
00381 infile.putback('<');
00382
00383
00384 RefAST child = LoadAST(infile);
00385
00386 current->addChild( child );
00387 }
00388 }
00389
00390 void ASTFactory::loadSiblings(ANTLR_USE_NAMESPACE(std)istream& infile,
00391 RefAST current )
00392 {
00393 for(;;)
00394 {
00395 eatwhite(infile);
00396
00397 if( infile.eof() )
00398 break;
00399
00400 if( checkCloseTag(infile) )
00401 break;
00402
00403 RefAST sibling = LoadAST(infile);
00404 current->setNextSibling(sibling);
00405 }
00406 }
00407
00408 RefAST ASTFactory::LoadAST( ANTLR_USE_NAMESPACE(std)istream& infile )
00409 {
00410 RefAST current = nullAST;
00411 char ch;
00412
00413 eatwhite(infile);
00414
00415 if( !infile.get(ch) )
00416 return nullAST;
00417
00418 if( ch != '<' )
00419 {
00420 string error = "Invalid XML file... no '<' found (";
00421 error += ch + ")";
00422 throw IOException(error);
00423 }
00424
00425 string ast_type = read_identifier(infile);
00426
00427
00428 current = create( ast_type, infile );
00429 if( current == nullAST )
00430 {
00431 string error = "Unsuported AST type: " + ast_type;
00432 throw IOException(error);
00433 }
00434
00435 eatwhite(infile);
00436
00437 infile.get(ch);
00438
00439
00440
00441
00442 if( ch == '/' )
00443 {
00444 infile.get(ch);
00445 if( ch != '>' )
00446 {
00447 string error = "Invalid XML file... no '>' found after '/' (";
00448 error += ch + ")";
00449 throw IOException(error);
00450 }
00451
00452
00453 loadSiblings( infile, current );
00454
00455 return current;
00456 }
00457
00458
00459 if( ch != '>' )
00460 {
00461 string error = "Invalid XML file... no '>' found (";
00462 error += ch + ")";
00463 throw IOException(error);
00464 }
00465
00466
00467 loadChildren( infile, current );
00468
00469
00470 loadSiblings( infile, current );
00471
00472 return current;
00473 }
00474 #endif // ANTLR_SUPPORT_XML
00475
00476 #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
00477 }
00478 #endif
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
This file is part of the documentation for KDevelop Version 3.1.2.