00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <string>
00025 #include <vector>
00026 #include <map>
00027 #include "Parse.h"
00028 #include <assert.h>
00029 #include <ctype.h>
00030 #include "BlackAdder.h"
00031
00032 #include "SimpleParser.h"
00033 #include "dp.h"
00034
00035 #define DEB(x)
00036
00037
00038
00039 SimpleParser::SimpleParser(const std::string &path,BlackAdder *pAdder)
00040 :BaseParser()
00041 ,the_ptr(0)
00042 ,m_state(0)
00043 ,m_currentfile("")
00044 ,m_path(path)
00045 ,m_line(0)
00046 ,m_namespace("")
00047 ,m_current(0)
00048 ,m_pAdder(pAdder)
00049 ,m_plevelm(0)
00050 ,m_stfile("")
00051 ,m_stline(0)
00052 ,m_extern(false)
00053 {
00054 *the_str = 0;
00055 }
00056
00057
00058 SimpleParser::~SimpleParser()
00059 {
00060 }
00061
00062
00063 void SimpleParser::error(const std::string &str)
00064 {
00065 DEB( fprintf(stderr,"%s line %d: %s\n",m_currentfile.c_str(),m_line,str.c_str());)
00066 }
00067
00068
00069 void SimpleParser::include_file(const std::string &filename)
00070 {
00071 char tmp[4000];
00072
00073 strcpy(tmp,filename.c_str() + 1);
00074 while (*tmp == ' ' || *tmp == '\t')
00075 memmove(tmp,tmp + 1,strlen(tmp + 1));
00076 for (size_t i = 0; i < strlen(tmp); i++)
00077 if (tmp[i] == '"' || tmp[i] == '>')
00078 tmp[i] = 0;
00079
00080
00081
00082 if (filename[0] == 34)
00083 {
00084 FILE *fil;
00085 char tmp2[4000];
00086
00087 sprintf(tmp2,"%s/%s",m_path.c_str(),tmp);
00088 if ((fil = fopen(tmp2,"rt")) != NULL)
00089 {
00090 int line = 0;
00091 Parser(fil,line,tmp);
00092 fclose(fil);
00093 }
00094 else
00095 {
00096 sprintf(tmp2,"Couldn't open '%s'...",tmp);
00097 error( tmp2 );
00098 }
00099 }
00100 else
00101 {
00102 FILE *fil;
00103 char tmp2[4000];
00104
00105 sprintf(tmp2,"/usr/include/%s",tmp);
00106 fil = fopen(tmp2,"rt");
00107 if (!fil)
00108 {
00109 sprintf(tmp2,"/usr/include/linux/%s",tmp);
00110 fil = fopen(tmp2,"rt");
00111 }
00112 if (!fil)
00113 {
00114 sprintf(tmp2,"/usr/include/g++-3/%s",tmp);
00115 fil = fopen(tmp2,"rt");
00116 }
00117 if (!fil)
00118 {
00119 sprintf(tmp2,"/usr/local/include/%s",tmp);
00120 fil = fopen(tmp2,"rt");
00121 }
00122 if (!fil)
00123 {
00124 sprintf(tmp2,"/usr/devel/include/%s",tmp);
00125 fil = fopen(tmp2,"rt");
00126 }
00127 if (!fil)
00128 {
00129 sprintf(tmp2,"%s/../%s",m_path.c_str(),tmp);
00130 fil = fopen(tmp2,"rt");
00131 }
00132 if (fil)
00133 {
00134 int line = 0;
00135 Parser(fil,line,tmp2);
00136 fclose(fil);
00137 }
00138 else
00139 {
00140 sprintf(tmp2,"Couldn't open '%s'...",tmp);
00141 error( tmp2 );
00142 }
00143 }
00144 }
00145
00146
00147 void SimpleParser::preprocessor(std::string &val,int &line)
00148 {
00149 if (!strncmp(val.c_str(),"#include ",9))
00150 {
00151 include_file(val.c_str() + 9);
00152 }
00153 else
00154 {
00155 Parse pa( (char *)val.c_str() );
00156 char slask[200];
00157
00158 strcpy(slask,pa.getword().c_str());
00159 assert(*slask == '#');
00160 strcpy(slask,pa.getword().c_str());
00161 line = atoi(slask);
00162 m_line = line;
00163 strcpy(slask,pa.getword().c_str());
00164 if (*slask == 34)
00165 {
00166 memmove(slask,slask + 1,strlen(slask + 1) + 1);
00167 slask[strlen(slask) - 1] = 0;
00168 }
00169 m_currentfile = slask;
00170 if (*slask == '/')
00171 m_extern = true;
00172 else
00173 m_extern = false;
00174 }
00175 }
00176
00177
00178 int SimpleParser::ReadLine(FILE *fil,int &line)
00179 {
00180 fgets(the_str,5000,fil);
00181 line++;
00182 m_line = line;
00183 if (feof(fil))
00184 return 0;
00185 while (strlen(the_str) && (Cx == 13 || Cx == 10))
00186 Cx = 0;
00187 while (Cx == '\\')
00188 {
00189 fgets(the_str + strlen(the_str) - 1,5000 - strlen(the_str),fil);
00190 line++;
00191 m_line = line;
00192 if (feof(fil))
00193 return 0;
00194 while (strlen(the_str) && (Cx == 13 || Cx == 10))
00195 Cx = 0;
00196 }
00197 the_ptr = 0;
00198 return 1;
00199 }
00200
00201
00202 int SimpleParser::GetToken(FILE *fil,int &line,std::string &val)
00203 {
00204 while (C == ' ' || C == '\t')
00205 the_ptr++;
00206 while (!C)
00207 {
00208 if (!ReadLine(fil,line))
00209 return 0;
00210 if (C == '#')
00211 {
00212 val = the_str;
00213 C = 0;
00214 return CPP;
00215 }
00216 while (C == ' ' || C == '\t')
00217 the_ptr++;
00218 }
00219 if (isdigit(C))
00220 {
00221 while (isdigit(C) || C == '.')
00222 {
00223 val += C;
00224 the_ptr++;
00225 }
00226 return NUMBER;
00227 }
00228 if (isalpha(C) || C == '_' || C == '~' || (C == ':' && C1 == ':' && (isalpha(C2) || C2 == '_')) )
00229 {
00230 if (C == '~')
00231 {
00232 val += C;
00233 the_ptr++;
00234 }
00235 while (isalnum(C) || C == '_' || (C == ':' && C1 == ':'))
00236 {
00237 if (C == ':' && C1 == ':')
00238 {
00239 val += C;
00240 the_ptr++;
00241 }
00242 val += C;
00243 the_ptr++;
00244 }
00245 {
00246 int id = GetWord(val);
00247 if (id >= 256)
00248 {
00249 return id;
00250 }
00251 }
00252 return IDENTIFIER;
00253 }
00254 if (C == '/' && C1 == '*')
00255 {
00256 while (C != '*' || C1 != '/')
00257 {
00258 val += C;
00259 the_ptr++;
00260 while (!C)
00261 {
00262 if (!ReadLine(fil,line))
00263 return 0;
00264 val += '\n';
00265 }
00266 }
00267 val += C;
00268 the_ptr++;
00269 val += C;
00270 the_ptr++;
00271 return COMMENT;
00272 }
00273 if (C == '/' && C1 == '/')
00274 {
00275 val = the_str + the_ptr;
00276 C = 0;
00277 return COMMENT;
00278 }
00279 if (C == 34)
00280 {
00281 val += C;
00282 the_ptr++;
00283 while (C != 34 && C)
00284 {
00285 if (C == '\\')
00286 {
00287 val += C;
00288 the_ptr++;
00289 }
00290 val += C;
00291 the_ptr++;
00292 }
00293 if (C == 34)
00294 {
00295 val += C;
00296 the_ptr++;
00297 }
00298 else
00299 {
00300 error("Unterminated string constant");
00301 }
00302 return STRING;
00303 }
00304 if (C == '\'')
00305 {
00306 val += C;
00307 the_ptr++;
00308 while (C != '\'' && C)
00309 {
00310 if (C == '\\')
00311 {
00312 val += C;
00313 the_ptr++;
00314 }
00315 val += C;
00316 the_ptr++;
00317 }
00318 if (C == '\'')
00319 {
00320 val += C;
00321 the_ptr++;
00322 }
00323 else
00324 {
00325 error("Unterminated char constant");
00326 }
00327 return CHAR;
00328 }
00329
00330 #define dblcheck(x1,x2,y) \
00331 if (C == x1 && C1 == x2) \
00332 { \
00333 val = x1; \
00334 val += x2; \
00335 the_ptr += 2; \
00336 return y; \
00337 }
00338
00339 dblcheck(':',':',CC);
00340 dblcheck('<','<',LTLT);
00341 dblcheck('>','>',GTGT);
00342 dblcheck('*','*',DPTR);
00343 dblcheck('<','=',LTEQ);
00344 dblcheck('!','=',NEQ);
00345 dblcheck('>','=',GTEQ);
00346 dblcheck('=','=',EQ);
00347 dblcheck('|','|',OR);
00348 dblcheck('&','&',AND);
00349 dblcheck('+','+',PP);
00350 dblcheck('-','-',MM);
00351 dblcheck('-','>',POINTER);
00352
00353 val += C;
00354 if (C == '{')
00355 {
00356 m_namesave[m_level] = m_namespace;
00357 m_level++;
00358 }
00359 if (C == '(')
00360 m_plevel++;
00361 return the_str[the_ptr++];
00362 }
00363
00364
00365 void SimpleParser::Parser(FILE *fil,int &line,const std::string &name)
00366 {
00367 CLS *cls = NULL;
00368 int c;
00369 std::string val;
00370 std::string old = m_currentfile;
00371 std::string strClass;
00372 bool func = false;
00373 bool ptr = false;
00374 std::string prev;
00375
00376 m_currentfile = name;
00377
00378 if (!old.size())
00379 {
00380
00381 }
00382
00383 for (;;)
00384 {
00385 val = "";
00386 c = GetToken(fil,line,val);
00387 if (!c)
00388 {
00389 break;
00390 }
00391 if (c == IDENTIFIER && strstr(val.c_str(), "::"))
00392 {
00393 fprintf(stderr, "%s\n", val.c_str());
00394 }
00395 if (c == CPP)
00396 {
00397 preprocessor( val, line );
00398 m_line = line;
00399 }
00400 else
00401
00402
00403 switch (m_state)
00404 {
00405 case 0:
00406 if (m_vec.size())
00407 {
00408 while (m_vec.size())
00409 m_vec.erase(m_vec.begin());
00410 }
00411 switch (c)
00412 {
00413 case Class:
00414 m_state = 1;
00415 break;
00416 case Namespace:
00417 m_state = 2;
00418 break;
00419 case Using:
00420 m_state = 3;
00421 break;
00422 case Template:
00423 m_state = 4;
00424 break;
00425 case Friend:
00426 m_state = 5;
00427 break;
00428 case Typedef:
00429 m_state = 6;
00430 m_levelm = m_level;
00431 break;
00432 }
00433 if (m_state)
00434 {
00435 m_vec.push_back( val );
00436 }
00437 break;
00438 case 1:
00439 if (c != COMMENT)
00440 m_vec.push_back(val);
00441 if (c == ';')
00442 {
00443 m_state = 0;
00444 }
00445 else
00446 if (c == '{')
00447 {
00448
00449 cls = m_pAdder -> add_class(m_namespace,m_vec,m_stfile,m_stline,m_extern);
00450 if (m_namespace.size())
00451 m_namespace += "::" + m_vec[1];
00452 else
00453 m_namespace = m_vec[1];
00454 m_current = Class;
00455 m_state = 10;
00456 m_levelm = m_level;
00457 strClass = m_vec[1];
00458
00459 while (m_vec.size())
00460 m_vec.erase(m_vec.begin());
00461 func = false;
00462 ptr = false;
00463
00464 }
00465 break;
00466 case 2:
00467 if (c != COMMENT)
00468 m_vec.push_back(val);
00469 if (c == ';')
00470 m_state = 0;
00471 else
00472 if (c == '{')
00473 m_state = 0;
00474 if (!m_state && m_vec[1] != "{")
00475 {
00476 if (m_namespace.size())
00477 m_namespace += "::" + m_vec[1];
00478 else
00479 m_namespace = m_vec[1];
00480 m_current = Namespace;
00481 }
00482 break;
00483 case 3:
00484 if (c != COMMENT)
00485 m_vec.push_back(val);
00486 if (c == ';')
00487 m_state = 0;
00488 else
00489 if (c == '{')
00490 m_state = 0;
00491 if (!m_state)
00492 {
00493 m_pAdder -> add_using(m_vec[1]);
00494 }
00495 break;
00496 case 4:
00497 if (c != COMMENT)
00498 m_vec.push_back(val);
00499 if (c == ';')
00500 m_state = 0;
00501 else
00502 if (c == '{')
00503 m_state = 0;
00504 break;
00505 case 5:
00506 if (c != COMMENT)
00507 m_vec.push_back(val);
00508 if (c == ';')
00509 m_state = 0;
00510 else
00511 if (c == '{')
00512 m_state = 0;
00513 break;
00514 case 6:
00515 if (c != COMMENT)
00516 m_vec.push_back(val);
00517 if (c == ';' && m_level == m_levelm)
00518 m_state = 0;
00519 if (!m_state)
00520 {
00521 std::string prev;
00522 std::string prev2;
00523 string_v::iterator it = m_vec.begin();
00524 string_v def;
00525 while (it != m_vec.end())
00526 {
00527 std::string tmp = *it;
00528 it++;
00529 if (prev2.size() && prev2 != "typedef")
00530 {
00531 def.push_back(prev2);
00532 }
00533 prev2 = prev;
00534 if (it != m_vec.end())
00535 {
00536 prev = tmp;
00537 }
00538 }
00539 m_pAdder -> set_typedef(m_namespace, prev, def);
00540 }
00541 break;
00542 case 10:
00543 if (m_level < m_levelm)
00544 m_state = 0;
00545 else
00546 if (m_level == m_levelm)
00547 {
00548 if (c != COMMENT)
00549 m_vec.push_back(val);
00550 switch (val[0])
00551 {
00552 case ';':
00553 if (!func)
00554 {
00555 if (0)
00556 {
00557 printf("HEADER");
00558 for (size_t i = 0; i < m_vec.size(); i++)
00559 printf(" %s", m_vec[i].c_str());
00560 printf("\n");
00561 }
00562 if (m_vec[0] != "typedef" && m_vec[0] != "friend" )
00563 {
00564 std::string prev;
00565 std::string typ;
00566 find_types(cls, m_vec);
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608 }
00609 }
00610
00611 while (m_vec.size())
00612 m_vec.erase(m_vec.begin());
00613 func = false;
00614 ptr = false;
00615
00616 break;
00617 case ':':
00618 if (m_vec[0] == "public")
00619 {
00620 }
00621 if (m_vec[0] == "protected")
00622 {
00623 }
00624 if (m_vec[0] == "private")
00625 {
00626 }
00627
00628 while (m_vec.size())
00629 m_vec.erase(m_vec.begin());
00630 func = false;
00631 ptr = false;
00632
00633 break;
00634 case '(':
00635 func = true;
00636 break;
00637 case '*':
00638 if (!func)
00639 ptr = true;
00640 break;
00641 default:
00642 break;
00643 }
00644 }
00645 break;
00646 }
00647
00648 if (c == '}')
00649 {
00650 m_level--;
00651 m_namespace = m_namesave[m_level];
00652 }
00653 else
00654 {
00655 EndToken(c);
00656 }
00657 prev = val;
00658 }
00659 m_currentfile = old;
00660 }
00661
00662
00663 void SimpleParser::find_types(CLS *cls,string_v& vec,int l)
00664 {
00665 std::string typ;
00666 for (string_v::iterator it = vec.begin(); it != vec.end(); it++)
00667 {
00668 string_v translated;
00669 NSP *nsp;
00670 bool is_type = m_pAdder -> type_lookup(cls, *it, translated, nsp);
00671 if (*it == "&")
00672 typ += *it;
00673 else
00674 if (*it == "*")
00675 typ += *it;
00676 else
00677 if (*it == "[")
00678 typ += *it;
00679 else
00680 if (is_type)
00681 {
00682 if (translated.size())
00683 {
00684 fprintf(stderr,"TYPE*<%s, %s>", nsp -> name.c_str(), (*it).c_str());
00685 for (size_t i = 0; i < translated.size(); i++)
00686 fprintf(stderr," %s", translated[i].c_str());
00687 fprintf(stderr,"\n");
00688 if (l < 5)
00689 find_types(cls, translated, l + 1);
00690 }
00691 else
00692 {
00693 fprintf(stderr,"TYPE<%s> %s\n", nsp -> name.c_str(), (*it).c_str());
00694 if (typ.size())
00695 m_pAdder -> add_type(cls, typ);
00696 typ = *it;
00697 }
00698 }
00699 }
00700 if (typ.size())
00701 m_pAdder -> add_type(cls, typ);
00702 }
00703
00704