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