SNAP Library 2.1, User Reference  2013-09-25 10:47:25
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
lx.cpp
Go to the documentation of this file.
00001 
00002 // Lexical-Chars
00003 void TLxChDef::SetUcCh(const TStr& Str){
00004   for (int CC=1; CC<Str.Len(); CC++){
00005     UcChV[Str[CC]-TCh::Mn]=TCh(Str[0]);}
00006 }
00007 
00008 void TLxChDef::SetChTy(const TLxChTy& ChTy, const TStr& Str){
00009   for (int CC=0; CC<Str.Len(); CC++){
00010     ChTyV[Str[CC]-TCh::Mn]=TInt(ChTy);}
00011 }
00012 
00013 TLxChDef::TLxChDef(const TLxChDefTy& ChDefTy):
00014   ChTyV(TCh::Vals), UcChV(TCh::Vals){
00015 
00016   if (ChDefTy==lcdtUsAscii){
00017     // Character-Types
00018     ChTyV.PutAll(TInt(lctSpace));
00019     SetChTy(lctNum, "0123456789");
00020     SetChTy(lctAlpha, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
00021     SetChTy(lctAlpha, "abcdefghijklmnopqrstuvwxyz");
00022     SetChTy(lctAlpha, "@_");
00023     SetChTy(lctSSym, "\"'.,:;+-*/%!#|&<=>?()[]{}");
00024     SetChTy(lctTerm, TStr(TCh::CrCh));
00025     SetChTy(lctTerm, TStr(TCh::LfCh));
00026     SetChTy(lctTerm, TStr(TCh::EofCh));
00027 
00028     // Upper-Case
00029     for (int Ch=TCh::Mn; Ch<=TCh::Mx; Ch++){UcChV[Ch-TCh::Mn]=TCh(char(Ch));}
00030     SetUcCh("Aa"); SetUcCh("Bb"); SetUcCh("Cc"); SetUcCh("Dd"); SetUcCh("Ee");
00031     SetUcCh("Ff"); SetUcCh("Gg"); SetUcCh("Hh"); SetUcCh("Ii"); SetUcCh("Jj");
00032     SetUcCh("Kk"); SetUcCh("Ll"); SetUcCh("Mm"); SetUcCh("Nn"); SetUcCh("Oo");
00033     SetUcCh("Pp"); SetUcCh("Qq"); SetUcCh("Rr"); SetUcCh("Ss"); SetUcCh("Tt");
00034     SetUcCh("Uu"); SetUcCh("Vv"); SetUcCh("Ww"); SetUcCh("Xx"); SetUcCh("Yy");
00035     SetUcCh("Zz");
00036   } else
00037   if (ChDefTy==lcdtYuAscii){
00038     // Character-Types
00039     ChTyV.PutAll(TInt(lctSpace));
00040     SetChTy(lctNum, "0123456789");
00041     SetChTy(lctAlpha, "ABC^]D\\EFGHIJKLMNOPQRS[TUVWXYZ@");
00042     SetChTy(lctAlpha, "abc~}d|efghijklmnopqrs{tuvwxyz`");
00043     SetChTy(lctAlpha, "_");
00044     SetChTy(lctSSym, "\".,:;+-*/%!#&<=>?()");
00045     SetChTy(lctTerm, TStr(TCh::CrCh));
00046     SetChTy(lctTerm, TStr(TCh::LfCh));
00047     SetChTy(lctTerm, TStr(TCh::EofCh));
00048 
00049     // Upper-Case
00050     for (int Ch=TCh::Mn; Ch<=TCh::Mx; Ch++){UcChV[Ch-TCh::Mn]=TCh(char(Ch));}
00051     SetUcCh("Aa"); SetUcCh("Bb"); SetUcCh("Cc"); SetUcCh("^~"); SetUcCh("]}");
00052     SetUcCh("Dd"); SetUcCh("\\|"); SetUcCh("Ee"); SetUcCh("Ff"); SetUcCh("Gg");
00053     SetUcCh("Hh"); SetUcCh("Ii"); SetUcCh("Jj"); SetUcCh("Kk"); SetUcCh("Ll");
00054     SetUcCh("Mm"); SetUcCh("Nn"); SetUcCh("Oo"); SetUcCh("Pp"); SetUcCh("Qq");
00055     SetUcCh("Rr"); SetUcCh("Ss"); SetUcCh("[{"); SetUcCh("Tt"); SetUcCh("Uu");
00056     SetUcCh("Vv"); SetUcCh("Ww"); SetUcCh("Xx"); SetUcCh("Yy"); SetUcCh("Zz");
00057     SetUcCh("@`");
00058   } else {
00059     Fail;
00060   }
00061 }
00062 
00063 bool TLxChDef::IsNmStr(const TStr& Str) const {
00064   if (Str.Len()==0){return false;}
00065   if (!IsAlpha(Str.GetCh(0))){return false;}
00066   for (int ChN=1; ChN<Str.Len(); ChN++){
00067     if (!IsAlNum(Str.GetCh(ChN))){return false;}}
00068   return true;
00069 }
00070 
00071 TStr TLxChDef::GetUcStr(const TStr& Str) const {
00072   TChA UcStr;
00073   for (int ChN=0; ChN<Str.Len(); ChN++){
00074     UcStr.AddCh(GetUc(Str.GetCh(ChN)));}
00075   return UcStr;
00076 }
00077 
00078 
00079 PLxChDef TLxChDef::GetChDef(const TLxChDefTy& ChDefTy){
00080   static PLxChDef UsAsciiChDef=NULL;
00081   static PLxChDef YuAsciiChDef=NULL;
00082   switch (ChDefTy){
00083     case lcdtUsAscii:
00084       if (UsAsciiChDef.Empty()){UsAsciiChDef=TLxChDef::New(lcdtUsAscii);}
00085       return UsAsciiChDef;
00086     case lcdtYuAscii:
00087       if (YuAsciiChDef.Empty()){YuAsciiChDef=TLxChDef::New(lcdtYuAscii);}
00088       return YuAsciiChDef;
00089     default: Fail; return NULL;
00090   }
00091 }
00092 
00093 //TLxChDef& TLxChDef::GetChDefRef(const TLxChDefTy& ChDefTy){
00094 //  switch (ChDefTy){
00095 //    case lcdtUsAscii: return *UsAsciiChDef;
00096 //    case lcdtYuAscii: return *YuAsciiChDef;
00097 //    default: Fail; return *UsAsciiChDef;;
00098 //  }
00099 //}
00100 
00102 // Lexical-Symbols
00103 const TStr TLxSymStr::UndefStr="<undefined>";
00104 const TStr TLxSymStr::LnStr="<line>";
00105 const TStr TLxSymStr::TabStr="<tab>";
00106 const TStr TLxSymStr::IntStr="<integer>";
00107 const TStr TLxSymStr::FltStr="<float>";
00108 const TStr TLxSymStr::StrStr="<string>";
00109 const TStr TLxSymStr::IdStrStr="<id-string>";
00110 const TStr TLxSymStr::QStrStr="<q-string>";
00111 const TStr TLxSymStr::PeriodStr=".";
00112 const TStr TLxSymStr::DPeriodStr="..";
00113 const TStr TLxSymStr::CommaStr=",";
00114 const TStr TLxSymStr::ColonStr=":";
00115 const TStr TLxSymStr::DColonStr="::";
00116 const TStr TLxSymStr::SemicolonStr=";";
00117 const TStr TLxSymStr::PlusStr="+";
00118 const TStr TLxSymStr::MinusStr="-";
00119 const TStr TLxSymStr::AsteriskStr="*";
00120 const TStr TLxSymStr::SlashStr="/";
00121 const TStr TLxSymStr::PercentStr="%";
00122 const TStr TLxSymStr::ExclamationStr="!";
00123 const TStr TLxSymStr::VBarStr="|";
00124 const TStr TLxSymStr::AmpersandStr="&";
00125 const TStr TLxSymStr::QuestionStr="?";
00126 const TStr TLxSymStr::HashStr="#";
00127 const TStr TLxSymStr::EqStr="=";
00128 const TStr TLxSymStr::NEqStr="<>";
00129 const TStr TLxSymStr::LssStr="<";
00130 const TStr TLxSymStr::GtrStr=">";
00131 const TStr TLxSymStr::LEqStr="<=";
00132 const TStr TLxSymStr::GEqStr=">=";
00133 const TStr TLxSymStr::LParenStr="(";
00134 const TStr TLxSymStr::RParenStr=")";
00135 const TStr TLxSymStr::LBracketStr="[";
00136 const TStr TLxSymStr::RBracketStr="]";
00137 const TStr TLxSymStr::LBraceStr="{";
00138 const TStr TLxSymStr::RBraceStr="}";
00139 const TStr TLxSymStr::EolnStr="<end-of-line>";
00140 const TStr TLxSymStr::EofStr="<end-of-file>";
00141 
00142 TStr TLxSymStr::GetSymStr(const TLxSym& Sym){
00143   switch (Sym){
00144     case syUndef: return UndefStr;
00145     case syLn: return LnStr;
00146     case syTab: return TabStr;
00147     case syInt: return IntStr;
00148     case syFlt: return FltStr;
00149     case syStr: return StrStr;
00150     case syIdStr: return IdStrStr;
00151     case syQStr: return QStrStr;
00152     case syPeriod: return PeriodStr;
00153     case syDPeriod: return DPeriodStr;
00154     case syComma: return CommaStr;
00155     case syColon: return ColonStr;
00156     case syDColon: return DColonStr;
00157     case sySemicolon: return SemicolonStr;
00158     case syPlus: return PlusStr;
00159     case syMinus: return MinusStr;
00160     case syAsterisk: return AsteriskStr;
00161     case sySlash: return SlashStr;
00162     case syPercent: return PercentStr;
00163     case syExclamation: return ExclamationStr;
00164     case syVBar: return VBarStr;
00165     case syAmpersand: return AmpersandStr;
00166     case syQuestion: return QuestionStr;
00167     case syHash: return HashStr;
00168     case syEq: return EqStr;
00169     case syNEq: return NEqStr;
00170     case syLss: return LssStr;
00171     case syGtr: return GtrStr;
00172     case syLEq: return LEqStr;
00173     case syGEq: return GEqStr;
00174     case syLParen: return LParenStr;
00175     case syRParen: return RParenStr;
00176     case syLBracket: return LBracketStr;
00177     case syRBracket: return RBracketStr;
00178     case syLBrace: return LBraceStr;
00179     case syRBrace: return RBraceStr;
00180     case syEoln: return EolnStr;
00181     case syEof: return EofStr;
00182     default: Fail; return TStr();
00183   }
00184 }
00185 
00186 TLxSym TLxSymStr::GetSSym(const TStr& Str){
00187   static TStrIntH StrToLxSymH(100);
00188   if (StrToLxSymH.Len()==0){
00189     StrToLxSymH.AddDat(PeriodStr, syPeriod);
00190     StrToLxSymH.AddDat(DPeriodStr, syDPeriod);
00191     StrToLxSymH.AddDat(CommaStr, syComma);
00192     StrToLxSymH.AddDat(ColonStr, syColon);
00193     StrToLxSymH.AddDat(DColonStr, syDColon);
00194     StrToLxSymH.AddDat(SemicolonStr, sySemicolon);
00195     StrToLxSymH.AddDat(PlusStr, syPlus);
00196     StrToLxSymH.AddDat(MinusStr, syMinus);
00197     StrToLxSymH.AddDat(AsteriskStr, syAsterisk);
00198     StrToLxSymH.AddDat(SlashStr, sySlash);
00199     StrToLxSymH.AddDat(PercentStr, syPercent);
00200     StrToLxSymH.AddDat(ExclamationStr, syExclamation);
00201     StrToLxSymH.AddDat(VBarStr, syVBar);
00202     StrToLxSymH.AddDat(AmpersandStr, syAmpersand);
00203     StrToLxSymH.AddDat(QuestionStr, syQuestion);
00204     StrToLxSymH.AddDat(HashStr, syHash);
00205     StrToLxSymH.AddDat(EqStr, syEq);
00206     StrToLxSymH.AddDat(NEqStr, syNEq);
00207     StrToLxSymH.AddDat(LssStr, syLss);
00208     StrToLxSymH.AddDat(GtrStr, syGtr);
00209     StrToLxSymH.AddDat(LEqStr, syLEq);
00210     StrToLxSymH.AddDat(GEqStr, syGEq);
00211     StrToLxSymH.AddDat(LParenStr, syLParen);
00212     StrToLxSymH.AddDat(RParenStr, syRParen);
00213     StrToLxSymH.AddDat(LBracketStr, syLBracket);
00214     StrToLxSymH.AddDat(RBracketStr, syRBracket);
00215     StrToLxSymH.AddDat(LBraceStr, syLBrace);
00216     StrToLxSymH.AddDat(RBraceStr, syRBrace);
00217   }
00218   int KeyId=StrToLxSymH.GetKeyId(Str);
00219   if (KeyId==-1){
00220     return syUndef;
00221   } else {
00222     return TLxSym(int(StrToLxSymH[KeyId]));
00223   }
00224 }
00225 
00226 bool TLxSymStr::IsSep(const TLxSym& PrevSym, const TLxSym& Sym){
00227   static TFSet SepPrevSymSet=TFSet()|
00228     syUndef|syColon|syDColon|syEq|
00229     syLParen|syRParen|syLBracket|syRBracket|syLBrace|syRBrace|
00230     syEoln|syEof;
00231 
00232   static TFSet SepSymSet=TFSet()|
00233     syPeriod|syComma|syColon|syDColon|sySemicolon|
00234     syEq|
00235     syExclamation|syQuestion|
00236     syLParen|syRParen|syLBracket|syRBracket|syLBrace|syRBrace|
00237     syEoln|syEof;
00238 
00239   return !SepPrevSymSet.In(PrevSym) && !SepSymSet.In(Sym);
00240 }
00241 
00243 // Lexical-Symbol-State
00244 TILxSymSt::TILxSymSt():
00245   Sym(syUndef),
00246   Str(), UcStr(), CmtStr(),
00247   Bool(false), Int(0), Flt(0),
00248   SymLnN(-1), SymLnChN(-1), SymChN(-1){}
00249 
00250 TILxSymSt::TILxSymSt(const TILxSymSt& SymSt):
00251   Sym(SymSt.Sym),
00252   Str(SymSt.Str), UcStr(SymSt.UcStr), CmtStr(SymSt.CmtStr),
00253   Bool(SymSt.Bool), Int(SymSt.Int), Flt(SymSt.Flt),
00254   SymLnN(SymSt.SymLnN), SymLnChN(SymSt.SymLnChN), SymChN(SymSt.SymChN){Fail;}
00255 
00256 TILxSymSt::TILxSymSt(TILx& Lx):
00257   Sym(Lx.Sym),
00258   Str(Lx.Str), UcStr(Lx.UcStr), CmtStr(Lx.CmtStr),
00259   Bool(Lx.Bool), Int(Lx.Int), Flt(Lx.Flt),
00260   SymLnN(Lx.SymLnN), SymLnChN(Lx.SymLnChN), SymChN(Lx.SymChN){}
00261 
00262 void TILxSymSt::Restore(TILx& Lx){
00263   Lx.Sym=Sym;
00264   Lx.Str=Str; Lx.UcStr=UcStr; Lx.CmtStr=CmtStr;
00265   Lx.Bool=Bool; Lx.Int=Int; Lx.Flt=Flt;
00266   Lx.SymLnN=SymLnN; Lx.SymLnChN=SymLnChN; Lx.SymChN=Lx.SymChN;}
00267 
00269 // Lexical-Input
00270 TILx::TILx(const PSIn& _SIn, const TFSet& OptSet, const TLxChDefTy& ChDefTy):
00271   ChDef(TLxChDef::GetChDef(ChDefTy)),
00272   SIn(_SIn), RSIn(*SIn),
00273   PrevCh(' '), Ch(' '), LnN(0), LnChN(0-1), ChN(0-1),
00274   PrevSymStStack(), RwStrH(50),
00275   IsCmtAlw(false), IsRetEoln(false), IsSigNum(false),
00276   IsUniStr(false), IsCsSens(false), IsExcept(false),
00277   IsTabSep(false), IsList(false),
00278   Sym(syUndef),
00279   Str(), UcStr(), CmtStr(),
00280   Bool(false), Int(0), Flt(0),
00281   SymLnN(-1), SymLnChN(-1), SymChN(-1){
00282   for (int Opt=0; Opt<iloMx; Opt++){
00283     if (OptSet.In(Opt)){SetOpt(Opt, true);}}
00284 }
00285 
00286 void TILx::SetOpt(const int& Opt, const bool& Val){
00287   switch (Opt){
00288     case iloCmtAlw: IsCmtAlw=Val; break;
00289     case iloRetEoln: IsRetEoln=Val; break;
00290     case iloSigNum: IsSigNum=Val; break;
00291     case iloUniStr: IsUniStr=Val; break;
00292     case iloCsSens: IsCsSens=Val; break;
00293     case iloExcept: IsExcept=Val; break;
00294     case iloTabSep: IsTabSep=Val; break;
00295     case iloList: IsList=Val; break;
00296     default: Fail;
00297   }
00298 }
00299 
00300 TLxSym TILx::AddRw(const TStr& Str){
00301   IAssert(RwStrH.Len()<syMxRw-syMnRw+1);
00302   TStr UcStr=ChDef->GetUcStr(Str);
00303   IAssert(!RwStrH.IsKey(UcStr));
00304   TLxSym RwSym=TLxSym(syMnRw+RwStrH.Len());
00305   RwStrH.AddDat(Str, TInt(int(RwSym)));
00306   return RwSym;
00307 }
00308 
00309 PSIn TILx::GetSIn(const char& SepCh){
00310   IAssert(PrevSymStStack.Empty());
00311   while ((Ch!=TCh::EofCh)&&(Ch!=SepCh)){GetCh();}
00312   return SIn;
00313 }
00314 
00315 TLxSym TILx::GetSym(const TFSet& Expect){
00316   CmtStr.Clr();
00317   if (!PrevSymStStack.Empty()){
00318     // symbols already on the stack
00319     PrevSymStStack.Top().Restore(*this); PrevSymStStack.Pop();
00320   } else
00321   if (Expect.In(syLn)){
00322     // symbol is the whole line string
00323     if (Ch==TCh::EofCh){
00324       Sym=syEof;
00325     } else {
00326       Str.Clr();
00327       if (IsBof()){GetCh();}
00328       while (!ChDef->IsTerm(Ch)){Str.AddCh(Ch); GetCh();}
00329       bool _IsRetEoln=IsRetEoln; IsRetEoln=true;
00330       GetSym(TFSet()|syEoln|syEof); Sym=syLn;
00331       IsRetEoln=_IsRetEoln;
00332     }
00333   } else
00334   if (IsTabSep){
00335     // symbol is between tab characters
00336     if (IsBof()){GetCh();}
00337     if (Ch==TCh::TabCh){ // tab character
00338       Sym=syTab; GetCh();
00339     } else
00340     if (ChDef->IsTerm(Ch)){ // eoln & eof characters
00341       bool _IsRetEoln=IsRetEoln; IsRetEoln=true; IsTabSep=false;
00342       GetSym(TFSet()|syEoln|syEof);
00343       IsRetEoln=_IsRetEoln; IsTabSep=true;
00344     } else {
00345       Str.Clr();
00346       while ((!ChDef->IsTerm(Ch))&&(Ch!=TCh::TabCh)){
00347         Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh();}
00348       Sym=syStr; QuoteP=false;
00349     }
00350   } else {
00351     // usual symbol
00352     while (ChDef->IsSpace(Ch)){GetCh();}
00353     SymLnN=LnN; SymLnChN=LnChN; SymChN=ChN;
00354 
00355     if (ChDef->IsAlpha(Ch)){
00356       if (IsUniStr){Sym=syStr;} else {Sym=syIdStr;}
00357       Str.Clr(); UcStr.Clr(); QuoteP=false;
00358       do {Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch));}
00359       while (ChDef->IsAlNum(GetCh()));
00360       if (!RwStrH.Empty()){
00361         TStr RwStr=Str; if (!IsCsSens){RwStr=UcStr;}
00362         int SymKeyId=RwStrH.GetKeyId(RwStr);
00363         if (SymKeyId!=-1){Sym=TLxSym(int(RwStrH[SymKeyId]));}
00364       }
00365       if (Expect.In(syBool)){
00366         Sym=syBool; IAssert(TBool::IsValStr(Str));
00367         Bool=TBool::GetValFromStr(Str);
00368       }
00369     } else
00370     if ((Ch=='"')||(Ch=='\'')){
00371       if (IsUniStr){Sym=syStr;} else {Sym=syQStr;}
00372       Str.Clr(); UcStr.Clr(); QuoteP=true; QuoteCh=Ch;
00373       GetCh();
00374       forever{
00375         while ((Ch!=QuoteCh)&&(Ch!='\\')&&(Ch!=TCh::EofCh)){
00376           Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh();}
00377         if (Ch==TCh::EofCh){
00378           Sym=syUndef; break;
00379         } else if (Ch==QuoteCh){
00380           GetCh(); break;
00381         } else {
00382           GetCh();
00383           switch (Ch){
00384             case '"': Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh(); break;
00385             case '\\': Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh(); break;
00386             case '\'': Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh(); break;
00387             case '/': Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh(); break;
00388             case 'b': Str.AddCh('\b'); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh(); break;
00389             case 'f': Str.AddCh('\f'); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh(); break;
00390             case 'n': Str.AddCh('\n'); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh(); break;
00391             case 'r': Str.AddCh('\r'); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh(); break;
00392             case 't': Str.AddCh('\t'); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh(); break;
00393             case 'u': {
00394               // unicode character, represented using 4 hexadecimal digits
00395               GetCh(); EAssertR(TCh::IsHex(Ch), "Invalid hexadecimal digit in unicode escape");
00396               int UChCd = TCh::GetHex(Ch);
00397               GetCh(); EAssertR(TCh::IsHex(Ch), "Invalid hexadecimal digit in unicode escape");
00398               UChCd = 16 * UChCd + TCh::GetHex(Ch);
00399               GetCh(); EAssertR(TCh::IsHex(Ch), "Invalid hexadecimal digit in unicode escape");
00400               UChCd = 16 * UChCd + TCh::GetHex(Ch);
00401               GetCh(); EAssertR(TCh::IsHex(Ch), "Invalid hexadecimal digit in unicode escape");
00402               UChCd = 16 * UChCd + TCh::GetHex(Ch);
00403               // get as UTF8 encoded characters
00404               TUnicode::EncodeUtf8(UChCd, Str);
00405                           TUnicode::EncodeUtf8(UChCd, UcStr); }
00406               GetCh(); break; 
00407             default: Sym=syUndef; break;
00408           }
00409           if (Sym==syUndef){
00410             throw PExcept(new TExcept("Invalid Escape Sequence in Quoted String"));}
00411         }
00412       }
00413     } else
00414     if ((ChDef->IsNum(Ch))||(IsSigNum&&((Ch=='+')||(Ch=='-')))){
00415       Str.Clr(); bool IntP=true;
00416       do {Str.AddCh(Ch);} while (ChDef->IsNum(GetCh()));
00417       if (Expect.In(syFlt)){
00418         if (Ch=='.'){
00419           Str.AddCh(Ch); IntP=false;
00420           while (ChDef->IsNum(GetCh())){Str.AddCh(Ch);}
00421         }
00422         if ((Ch=='e')||(Ch=='E')){
00423           Str.AddCh(Ch); GetCh(); IntP=false;
00424           if ((Ch=='+')||(Ch=='-')){Str.AddCh(Ch); GetCh();}
00425           while (ChDef->IsNum(Ch)){Str.AddCh(Ch); GetCh();}
00426         }
00427       }
00428       UcStr=Str;
00429       if (IntP&&(Expect.In(syInt))){
00430         Sym=syInt; Int=atoi(Str.CStr());
00431       } else {
00432         Sym=syFlt; Flt=atof(Str.CStr());
00433       }
00434     } else
00435     if ((Ch==TCh::CrCh)||(Ch==TCh::LfCh)){
00436       Sym=syEoln;
00437       if (Ch==TCh::CrCh){if (GetCh()==TCh::LfCh){GetCh();}} else
00438       if (Ch==TCh::LfCh){if (GetCh()==TCh::CrCh){GetCh();}}
00439       LnN++; LnChN=0; if (!IsRetEoln){GetSym(Expect);}
00440     } else
00441     if (Ch=='/'){
00442       GetCh();
00443       if ((IsCmtAlw)&&(Ch=='/')){
00444         TChA _CmtStr;
00445         do {_CmtStr+=GetCh();} while (!ChDef->IsTerm(Ch));
00446         _CmtStr.Pop(); _CmtStr.Trunc();
00447         if (Ch==TCh::CrCh){
00448           if (GetCh()==TCh::LfCh){GetCh();}
00449         } else
00450         if (Ch==TCh::LfCh){
00451           if (GetCh()==TCh::CrCh){GetCh();}
00452         }
00453         if (IsRetEoln){Sym=syEoln;} else {GetSym(Expect);}
00454         CmtStr=_CmtStr;
00455       } else
00456       if (Ch=='*'){
00457         TChA _CmtStr;
00458         do {
00459           while (GetCh()!='*'){_CmtStr+=Ch;}
00460           _CmtStr+=GetCh();
00461         } while (Ch!='/');
00462         _CmtStr.Pop(); _CmtStr.Pop(); _CmtStr.Trunc();
00463         GetCh(); GetSym(Expect);
00464         CmtStr=_CmtStr;
00465       } else {
00466         Sym=sySlash;
00467       }
00468     } else
00469     if (Ch==TCh::EofCh){
00470       Sym=syEof;
00471     } else {
00472       switch (Ch){
00473         case '.':
00474           if (GetCh()=='.'){Sym=syDPeriod; GetCh();}
00475           else {Sym=syPeriod;} break;
00476         case ',': Sym=syComma; GetCh(); break;
00477         case ':':
00478           if (GetCh()==':'){Sym=syDColon; GetCh();}
00479           else {Sym=syColon;} break;
00480         case ';': Sym=sySemicolon; GetCh(); break;
00481         case '+': Sym=syPlus; GetCh(); break;
00482         case '-': Sym=syMinus; GetCh(); break;
00483         case '*': Sym=syAsterisk; GetCh(); break;
00484         case '/': Sym=sySlash; GetCh(); break;
00485         case '%': Sym=syPercent; GetCh(); break;
00486         case '!': Sym=syExclamation; GetCh(); break;
00487         case '|': Sym=syVBar; GetCh(); break;
00488         case '&': Sym=syAmpersand; GetCh(); break;
00489         case '=': Sym=syEq; GetCh(); break;
00490         case '<':
00491           GetCh();
00492           if (Ch=='='){Sym=syLEq; GetCh();}
00493           else if (Ch=='>'){Sym=syNEq; GetCh();}
00494           else {Sym=syLss;} break;
00495         case '>':
00496           if (GetCh()=='='){Sym=syGEq; GetCh();}
00497           else {Sym=syGtr;} break;
00498         case '?': Sym=syQuestion; GetCh(); break;
00499         case '#':
00500           if (IsCmtAlw){
00501             TChA _CmtStr;
00502             do {_CmtStr+=GetCh();} while (!ChDef->IsTerm(Ch));
00503             _CmtStr.Pop(); _CmtStr.Trunc();
00504             if (Ch==TCh::CrCh){
00505               if (GetCh()==TCh::LfCh){GetCh();}
00506             } else
00507             if (Ch==TCh::LfCh){
00508               if (GetCh()==TCh::CrCh){GetCh();}
00509             }
00510             if (IsRetEoln){Sym=syEoln;} else {GetSym(Expect);}
00511             CmtStr=_CmtStr;
00512           } else {
00513             Sym=syHash; GetCh();
00514           }
00515           break;
00516         case '(': Sym=syLParen; GetCh(); break;
00517         case ')': Sym=syRParen; GetCh(); break;
00518         case '[': Sym=syLBracket; GetCh(); break;
00519         case ']': Sym=syRBracket; GetCh(); break;
00520         case '{': Sym=syLBrace; GetCh(); break;
00521         case '}': Sym=syRBrace; GetCh(); break;
00522         default: Sym=syUndef; GetCh(); break;
00523       }
00524     }
00525   }
00526 
00527   if ((!Expect.In(Sym))&&(!Expect.Empty())){
00528     if (IsExcept){
00529      TStr MsgStr=
00530       TStr("Unexpected symbol (")+GetSymStr()+") ["+GetFPosStr()+"]";
00531      throw PExcept(new TExcept(MsgStr));
00532     } else {
00533       Fail;
00534     }
00535   }
00536   return Sym;
00537 }
00538 
00539 TStr TILx::GetStrToCh(const char& ToCh){
00540   Sym=syStr; Str.Clr(); UcStr.Clr();
00541   while ((Ch!=ToCh)&&(Ch!=TCh::EofCh)){
00542     Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh();}
00543   return Str;
00544 }
00545 
00546 TStr TILx::GetStrToEolnOrCh(const char& ToCh){
00547   Sym=syStr; Str.Clr(); UcStr.Clr();
00548   while ((Ch!=ToCh)&&(Ch!=TCh::CrCh)&&(Ch!=TCh::LfCh)&&(Ch!=TCh::EofCh)){
00549     Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh();}
00550   return Str;
00551 }
00552 
00553 TStr TILx::GetStrToEoln(const bool& DoTrunc){
00554   Sym=syStr; Str.Clr(); UcStr.Clr();
00555   while ((Ch!=TCh::CrCh)&&(Ch!=TCh::LfCh)&&(Ch!=TCh::EofCh)){
00556     Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh();}
00557   if (DoTrunc){Str.ToTrunc(); UcStr.ToTrunc();}
00558   return Str;
00559 }
00560 
00561 TStr TILx::GetStrToEolnAndCh(const char& ToCh){
00562   Sym=syStr; Str.Clr(); UcStr.Clr();
00563   if (IsBof()){GetCh();}
00564   forever {
00565     if (Ch==TCh::EofCh){break;}
00566     if (((ChN==0)||(PrevCh==TCh::CrCh)||(PrevCh==TCh::LfCh))&&(Ch==ToCh)){
00567       GetCh(); break;}
00568     else {Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh();}
00569   }
00570   return Str;
00571 }
00572 
00573 void TILx::SkipToEoln(){
00574   while ((Ch!=TCh::CrCh)&&(Ch!=TCh::LfCh)&&(Ch!=TCh::EofCh)){
00575     GetCh();}
00576   if (Ch==TCh::CrCh){if (GetCh()==TCh::LfCh){GetCh();}} else
00577   if (Ch==TCh::LfCh){if (GetCh()==TCh::CrCh){GetCh();}}
00578 }
00579 
00580 TLxSym TILx::PeekSym(const int& Syms){
00581   TILxSymSt CurSymSt(*this);
00582   TSStack<TILxSymSt> SymStStack;
00583   for (int SymN=0; SymN<Syms; SymN++){
00584     GetSym(); SymStStack.Push(TILxSymSt(*this));}
00585   TLxSym PeekedSym=Sym;
00586   while (!SymStStack.Empty()){
00587     SymStStack.Top().Restore(*this); SymStStack.Pop();
00588     PutSym();
00589   }
00590   CurSymSt.Restore(*this);
00591   return PeekedSym;
00592 }
00593 
00594 TStr TILx::GetSymStr() const {
00595   switch (Sym){
00596     case syInt: return Str;
00597     case syFlt: return Str;
00598     case syStr: return Str;
00599     case syIdStr: return Str;
00600     case syQStr: return Str;
00601     default:
00602       if ((syMnRw<=Sym)&&(Sym<=syMxRw)){return Str;}
00603       else {return TLxSymStr::GetSymStr(Sym);}
00604   }
00605 }
00606 
00607 TStr TILx::GetFPosStr() const {
00608   TChA ChA;
00609   ChA+="File:"; ChA+=SIn->GetSNm();
00610   ChA+=" Line:"; ChA+=TInt::GetStr(LnN+1);
00611   ChA+=" Char:"; ChA+=TInt::GetStr(LnChN);
00612   return ChA;
00613 }
00614 
00615 TStr TILx::GetQStr(const TStr& Str, const bool& QuoteP, const char& QuoteCh){
00616   if (QuoteP){
00617     TChA ChA;
00618     ChA+=QuoteCh;
00619     int StrLen=Str.Len();
00620     for (int ChN=0; ChN<StrLen; ChN++){
00621       char Ch=Str.CStr()[ChN];
00622       if (Ch==QuoteCh){ChA+=QuoteCh; ChA+=QuoteCh;}
00623       else {ChA+=Ch;}
00624     }
00625     ChA+=QuoteCh;
00626     return ChA;
00627   } else {
00628     return Str;
00629   }
00630 }
00631 
00632 void TILx::GetVarBoolV(const TStr& VarNm, TBoolV& BoolV, const bool& NewLn){
00633   BoolV.Clr();
00634   GetVar(VarNm, true, NewLn);
00635   while (GetSym(syRBracket, syBool)==syQStr){
00636     BoolV.Add(Bool); if (NewLn){GetEoln();}}
00637   if (NewLn){GetEoln();}
00638 }
00639 
00640 void TILx::GetVarIntV(const TStr& VarNm, TIntV& IntV, const bool& NewLn){
00641   IntV.Clr();
00642   GetVar(VarNm, true, NewLn);
00643   while (GetSym(syRBracket, syInt)==syInt){
00644     IntV.Add(Int); if (NewLn){GetEoln();}}
00645   if (NewLn){GetEoln();}
00646 }
00647 
00648 void TILx::GetVarFltV(const TStr& VarNm, TFltV& FltV, const bool& NewLn){
00649   FltV.Clr();
00650   GetVar(VarNm, true, NewLn);
00651   while (GetSym(syRBracket, syFlt)==syFlt){
00652     FltV.Add(Flt); if (NewLn){GetEoln();}}
00653   if (NewLn){GetEoln();}
00654 }
00655 
00656 void TILx::GetVarStrV(const TStr& VarNm, TStrV& StrV, const bool& NewLn){
00657   StrV.Clr();
00658   GetVar(VarNm, true, NewLn);
00659   while (GetSym(syRBracket, syQStr)==syQStr){
00660     StrV.Add(Str); if (NewLn){GetEoln();}}
00661   if (NewLn){GetEoln();}
00662 }
00663 
00664 void TILx::GetVarStrPrV(const TStr& VarNm, TStrPrV& StrPrV, const bool& NewLn){
00665   StrPrV.Clr();
00666   GetVar(VarNm, true, NewLn);
00667   while (GetSym(syRBracket, syLBracket)==syLBracket){
00668     TStr Str1=GetQStr(); TStr Str2=GetQStr();
00669     GetSym(syRBracket);
00670     StrPrV.Add(TStrPr(Str1, Str2)); if (NewLn){GetEoln();}
00671   }
00672   if (NewLn){GetEoln();}
00673 }
00674 
00675 void TILx::GetVarStrVV(const TStr& VarNm, TVec<TStrV>& StrVV, const bool& NewLn){
00676   StrVV.Clr();
00677   GetVar(VarNm, true, NewLn);
00678   while (GetSym(syRBracket, syLBracket)==syLBracket){
00679     StrVV.Add();
00680     while (GetSym(syQStr, syRBracket)==syQStr){
00681       StrVV.Last().Add(Str);}
00682     if (NewLn){GetEoln();}
00683   }
00684   if (NewLn){GetEoln();}
00685 }
00686 
00687 void TILx::GetLnV(const TStr& FNm, TStrV& LnV){
00688   TFIn SIn(FNm); LnV.Clr(); TChA Ln;
00689   if (!SIn.Eof()){
00690     char Ch=SIn.GetCh();
00691     while (!SIn.Eof()){
00692       if ((Ch==TCh::CrCh)||(Ch==TCh::LfCh)){
00693         if (!SIn.Eof()){
00694           char PrevCh=Ch; Ch=SIn.GetCh();
00695           if (!SIn.Eof()){
00696             if (PrevCh==TCh::CrCh){if (Ch==TCh::LfCh){Ch=SIn.GetCh();}} else
00697             if (PrevCh==TCh::LfCh){if (Ch==TCh::CrCh){Ch=SIn.GetCh();}}
00698           }
00699         }
00700         LnV.Add(Ln); Ln.Clr();
00701       } else {
00702         Ln+=Ch; Ch=SIn.GetCh();
00703       }
00704     }
00705     if (!Ln.Empty()){
00706       LnV.Add(Ln);}
00707   }
00708 }
00709 
00711 // Lexical-Output
00712 void TOLx::PutSep(const TLxSym& Sym){
00713   if (TLxSymStr::IsSep(PrevSym, Sym)){
00714     if (IsTabSep){RSOut.PutCh(TCh::TabCh);} else {RSOut.PutCh(' ');}}
00715   PrevSym=Sym;
00716 }
00717 
00718 TOLx::TOLx(const PSOut& _SOut, const TFSet& OptSet, const TLxChDefTy& ChDefTy):
00719   ChDef(TLxChDef::GetChDef(ChDefTy)), SOut(_SOut), RSOut(*SOut),
00720   IsCmtAlw(false), IsFrcEoln(false), IsSigNum(false),
00721   IsUniStr(false), IsCsSens(false), IsTabSep(false), IsVarIndent(false),
00722   VarIndentLev(0),
00723   RwStrH(50), RwSymH(50), PrevSym(syUndef){
00724   for (int Opt=0; Opt<oloMx; Opt++){
00725     if (OptSet.In(Opt)){SetOpt(Opt, true);}}
00726 }
00727 
00728 void TOLx::SetOpt(const int& Opt, const bool& Val){
00729   switch (Opt){
00730     case oloCmtAlw: IsCmtAlw=Val; break;
00731     case oloFrcEoln: IsFrcEoln=Val; break;
00732     case oloSigNum: IsSigNum=Val; break;
00733     case oloUniStr: IsUniStr=Val; break;
00734     case oloCsSens: IsCsSens=Val; break;
00735     case oloTabSep: IsTabSep=Val; break;
00736     case oloVarIndent: IsVarIndent=Val; break;
00737     default: Fail;
00738   }
00739 }
00740 
00741 TLxSym TOLx::AddRw(const TStr& Str){
00742   IAssert(RwStrH.Len()<syMxRw-syMnRw+1);
00743   TStr UcStr=ChDef->GetUcStr(Str);
00744   IAssert(!RwStrH.IsKey(UcStr));
00745   TLxSym RwSym=TLxSym(syMnRw+RwStrH.Len());
00746   RwStrH.AddDat(Str, TInt(int(RwSym)));
00747   RwSymH.AddDat(TInt(int(RwSym)), Str);
00748   return RwSym;
00749 }
00750 
00751 void TOLx::PutSym(const TLxSym& Sym){
00752   TStr Str;
00753   if ((syMnRw<=Sym)&&(Sym<=syMxRw)){
00754     Str=Str=RwSymH[Sym];
00755   } else {
00756     Str=TLxSymStr::GetSymStr(Sym);
00757   }
00758   PutSep(Sym); RSOut.PutStr(Str);
00759 }
00760 
00761 void TOLx::PutVarBoolV(const TStr& VarNm, const TBoolV& BoolV,
00762  const bool& NewLn, const bool& CheckIdStr){
00763   PutVar(VarNm, true, NewLn, CheckIdStr);
00764   for (int BoolN=0; BoolN<BoolV.Len(); BoolN++){
00765     if (IsVarIndent){PutIndent(VarIndentLev);}
00766     PutBool(BoolV[BoolN]);
00767     if (NewLn){PutLn();}
00768   }
00769   PutVarEnd(true, NewLn);
00770 }
00771 
00772 void TOLx::PutVarIntV(const TStr& VarNm, const TIntV& IntV,
00773  const bool& NewLn, const bool& CheckIdStr){
00774   PutVar(VarNm, true, NewLn, CheckIdStr);
00775   for (int IntN=0; IntN<IntV.Len(); IntN++){
00776     if (IsVarIndent){PutIndent(VarIndentLev);}
00777     PutInt(IntV[IntN]);
00778     if (NewLn){PutLn();}
00779   }
00780   PutVarEnd(true, NewLn);
00781 }
00782 
00783 void TOLx::PutVarFltV(const TStr& VarNm, const TFltV& FltV,
00784  const bool& NewLn, const bool& CheckIdStr){
00785   PutVar(VarNm, true, NewLn, CheckIdStr);
00786   for (int FltN=0; FltN<FltV.Len(); FltN++){
00787     if (IsVarIndent){PutIndent(VarIndentLev);}
00788     PutFlt(FltV[FltN]);
00789     if (NewLn){PutLn();}
00790   }
00791   PutVarEnd(true, NewLn);
00792 }
00793 
00794 void TOLx::PutVarStrV(const TStr& VarNm, const TStrV& StrV,
00795  const bool& NewLn, const bool& CheckIdStr){
00796   PutVar(VarNm, true, NewLn, CheckIdStr);
00797   for (int StrN=0; StrN<StrV.Len(); StrN++){
00798     if (IsVarIndent){PutIndent(VarIndentLev);}
00799     PutQStr(StrV[StrN]);
00800     if (NewLn){PutLn();}
00801   }
00802   PutVarEnd(true, NewLn);
00803 }
00804 
00805 void TOLx::PutVarStrPrV(const TStr& VarNm, const TStrPrV& StrPrV,
00806  const bool& NewLn, const bool& CheckIdStr){
00807   PutVar(VarNm, true, NewLn, CheckIdStr);
00808   for (int StrPrN=0; StrPrN<StrPrV.Len(); StrPrN++){
00809     if (IsVarIndent){PutIndent(VarIndentLev);}
00810     PutSym(syLBracket);
00811     PutQStr(StrPrV[StrPrN].Val1); PutQStr(StrPrV[StrPrN].Val2);
00812     PutSym(syRBracket);
00813     if (NewLn){PutLn();}
00814   }
00815   PutVarEnd(true, NewLn);
00816 }
00817 
00818 void TOLx::PutVarStrVV(const TStr& VarNm, const TVec<TStrV>& StrVV,
00819  const bool& NewLn, const bool& CheckIdStr){
00820   PutVar(VarNm, true, NewLn, CheckIdStr);
00821   for (int StrVN=0; StrVN<StrVV.Len(); StrVN++){
00822     if (IsVarIndent){PutIndent(VarIndentLev);}
00823     PutSym(syLBracket);
00824     for (int StrN=0; StrN<StrVV[StrVN].Len(); StrN++){
00825       PutQStr(StrVV[StrVN][StrN]);}
00826     PutSym(syRBracket);
00827     if (NewLn){PutLn();}
00828   }
00829   PutVarEnd(true, NewLn);
00830 }
00831 
00833 // Preprocessor
00834 char TPreproc::GetCh(){
00835   Assert(Ch!=TCh::EofCh);
00836   PrevCh=Ch;
00837   Ch=((SIn->Eof()) ? TCh::EofCh : SIn->GetCh());
00838   //putchar(Ch);
00839   return Ch;
00840 }
00841 
00842 bool TPreproc::IsSubstId(const TStr& SubstId, TStr& SubstValStr) const {
00843   if (SubstIdToKeyIdValPrVH.IsKey(SubstId)){
00844     const TStrPrV& KeyIdValPrV=SubstIdToKeyIdValPrVH.GetDat(SubstId);
00845     for (int KeyN=0; KeyN<KeyIdValPrV.Len(); KeyN++){
00846       if (SubstKeyIdV.IsIn(KeyIdValPrV[KeyN].Val1)){
00847         SubstValStr=KeyIdValPrV[KeyN].Val2;
00848         return true;
00849       }
00850     }
00851     return false;
00852   } else {
00853     return false;
00854   }
00855 }
00856 
00857 TPreproc::TPreproc(const TStr& InFNm, const TStr& OutFNm,
00858  const TStr& SubstFNm, const TStrV& _SubstKeyIdV):
00859   SIn(), SubstKeyIdV(_SubstKeyIdV),
00860   PrevCh('\0'), Ch('\0'){
00861   // load substitution file
00862   if (!SubstFNm.Empty()){
00863     PXmlDoc XmlDoc=TXmlDoc::LoadTxt(SubstFNm);
00864     // get list of substitutions
00865     TXmlTokV SubstTokV; XmlDoc->GetTok()->GetTagTokV("Subst", SubstTokV);
00866     for (int SubstTokN=0; SubstTokN<SubstTokV.Len(); SubstTokN++){
00867       PXmlTok SubstTok=SubstTokV[SubstTokN];
00868       // get substitution-id
00869       TStr SubstId=SubstTok->GetArgVal("Id", "");
00870       if (!SubstId.Empty()){
00871         // create substitution
00872         TStrPrV& KeyIdValPrV=SubstIdToKeyIdValPrVH.AddDat(SubstId);
00873         // get list of substitution-strings
00874         TXmlTokV StrTokV; SubstTok->GetTagTokV("Str", StrTokV);
00875         for (int StrTokN=0; StrTokN<StrTokV.Len(); StrTokN++){
00876           PXmlTok StrTok=StrTokV[StrTokN];
00877           // get key-value pair
00878           TStr KeyId=StrTok->GetArgVal("Key", "");
00879           TStr ValStr=StrTok->GetTokStr(false);
00880           // assign key-value-pair
00881           if (!KeyId.Empty()){
00882             KeyIdValPrV.Add(TStrPr(KeyId, ValStr));
00883           }
00884         }
00885       }
00886     }
00887   }
00888   // substitution
00889   // open files
00890   SIn=TFIn::New(InFNm);
00891   PSOut SOut=TFOut::New(OutFNm);
00892   // set copy & ignore mode
00893   bool CopyModeP=false; bool IgnoreModeP=false;
00894   GetCh();
00895   while (Ch!=TCh::EofCh){
00896     if (isalpha(Ch)||(((PrevCh=='\0')||(PrevCh=='\r')||(PrevCh=='\n'))&&(Ch=='#'))){
00897       // collect identifier
00898       TChA IdChA;
00899       do {
00900         IdChA+=Ch; GetCh();
00901       } while ((Ch!=TCh::EofCh)&&(isalnum(Ch)));
00902       // check identifier
00903       if (IdChA=="#ifdef"){
00904         // collect condition-key-id
00905         TChA CondKeyIdChA;
00906         while ((Ch!=TCh::EofCh)&&(Ch!='\n')&&(Ch!='\r')){
00907           CondKeyIdChA+=Ch; GetCh();}
00908         // skip eoln
00909         if (Ch=='\n'){GetCh(); if (Ch=='\r'){GetCh();}}
00910         else if (Ch=='\r'){GetCh(); if (Ch=='\n'){GetCh();}}
00911         // check for key
00912         CondKeyIdChA.Trunc();
00913         IAssert(CopyModeP==false);
00914         IAssert(IgnoreModeP==false);
00915         if (SubstKeyIdV.IsIn(CondKeyIdChA)){
00916           CopyModeP=true; IgnoreModeP=false;
00917         } else {
00918           CopyModeP=false; IgnoreModeP=true;
00919         }
00920       } else
00921       if (IdChA=="#endif"){
00922         // move to eoln
00923         while ((Ch!=TCh::EofCh)&&(Ch!='\n')&&(Ch!='\r')){
00924           GetCh();}
00925         // skip eoln
00926         if (Ch=='\n'){GetCh(); if (Ch=='\r'){GetCh();}}
00927         else if (Ch=='\r'){GetCh(); if (Ch=='\n'){GetCh();}}
00928         // reset copy&ignore modes
00929         IAssert(CopyModeP||IgnoreModeP);
00930         CopyModeP=false; IgnoreModeP=false;
00931       } else {
00932         // substitution or add id-as-seen
00933         TStr SubstValStr;
00934         if ((!CopyModeP)&&(IsSubstId(IdChA, SubstValStr))){
00935           if (!IgnoreModeP){SOut->PutStr(SubstValStr);}
00936         } else {
00937           if (!IgnoreModeP){SOut->PutStr(IdChA);}
00938         }
00939       }
00940     } else {
00941       // single character
00942       if (!IgnoreModeP){SOut->PutCh(Ch);}
00943       GetCh();
00944     }
00945   }
00946 }
00947