//////////////////////////////////////////////// // Lexical-Chars void TLxChDef::SetUcCh(const TStr& Str){ for (int CC=1; CC?()[]{}"); SetChTy(lctTerm, TStr(TCh::CrCh)); SetChTy(lctTerm, TStr(TCh::LfCh)); SetChTy(lctTerm, TStr(TCh::EofCh)); // Upper-Case for (int Ch=TCh::Mn; Ch<=TCh::Mx; Ch++){UcChV[Ch-TCh::Mn]=TCh(char(Ch));} SetUcCh("Aa"); SetUcCh("Bb"); SetUcCh("Cc"); SetUcCh("Dd"); SetUcCh("Ee"); SetUcCh("Ff"); SetUcCh("Gg"); SetUcCh("Hh"); SetUcCh("Ii"); SetUcCh("Jj"); SetUcCh("Kk"); SetUcCh("Ll"); SetUcCh("Mm"); SetUcCh("Nn"); SetUcCh("Oo"); SetUcCh("Pp"); SetUcCh("Qq"); SetUcCh("Rr"); SetUcCh("Ss"); SetUcCh("Tt"); SetUcCh("Uu"); SetUcCh("Vv"); SetUcCh("Ww"); SetUcCh("Xx"); SetUcCh("Yy"); SetUcCh("Zz"); } else if (ChDefTy==lcdtYuAscii){ // Character-Types ChTyV.PutAll(TInt(lctSpace)); SetChTy(lctNum, "0123456789"); SetChTy(lctAlpha, "ABC^]D\\EFGHIJKLMNOPQRS[TUVWXYZ@"); SetChTy(lctAlpha, "abc~}d|efghijklmnopqrs{tuvwxyz`"); SetChTy(lctAlpha, "_"); SetChTy(lctSSym, "\".,:;+-*/%!#&<=>?()"); SetChTy(lctTerm, TStr(TCh::CrCh)); SetChTy(lctTerm, TStr(TCh::LfCh)); SetChTy(lctTerm, TStr(TCh::EofCh)); // Upper-Case for (int Ch=TCh::Mn; Ch<=TCh::Mx; Ch++){UcChV[Ch-TCh::Mn]=TCh(char(Ch));} SetUcCh("Aa"); SetUcCh("Bb"); SetUcCh("Cc"); SetUcCh("^~"); SetUcCh("]}"); SetUcCh("Dd"); SetUcCh("\\|"); SetUcCh("Ee"); SetUcCh("Ff"); SetUcCh("Gg"); SetUcCh("Hh"); SetUcCh("Ii"); SetUcCh("Jj"); SetUcCh("Kk"); SetUcCh("Ll"); SetUcCh("Mm"); SetUcCh("Nn"); SetUcCh("Oo"); SetUcCh("Pp"); SetUcCh("Qq"); SetUcCh("Rr"); SetUcCh("Ss"); SetUcCh("[{"); SetUcCh("Tt"); SetUcCh("Uu"); SetUcCh("Vv"); SetUcCh("Ww"); SetUcCh("Xx"); SetUcCh("Yy"); SetUcCh("Zz"); SetUcCh("@`"); } else { Fail; } } bool TLxChDef::IsNmStr(const TStr& Str) const { if (Str.Len()==0){return false;} if (!IsAlpha(Str.GetCh(0))){return false;} for (int ChN=1; ChNGetUcStr(Str); IAssert(!RwStrH.IsKey(UcStr)); TLxSym RwSym=TLxSym(syMnRw+RwStrH.Len()); RwStrH.AddDat(Str, TInt(int(RwSym))); return RwSym; } PSIn TILx::GetSIn(const char& SepCh){ IAssert(PrevSymStStack.Empty()); while ((Ch!=TCh::EofCh)&&(Ch!=SepCh)){GetCh();} return SIn; } TLxSym TILx::GetSym(const TFSet& Expect){ CmtStr.Clr(); if (!PrevSymStStack.Empty()){ // symbols already on the stack PrevSymStStack.Top().Restore(*this); PrevSymStStack.Pop(); } else if (Expect.In(syLn)){ // symbol is the whole line string if (Ch==TCh::EofCh){ Sym=syEof; } else { Str.Clr(); if (IsBof()){GetCh();} while (!ChDef->IsTerm(Ch)){Str.AddCh(Ch); GetCh();} bool _IsRetEoln=IsRetEoln; IsRetEoln=true; GetSym(TFSet()|syEoln|syEof); Sym=syLn; IsRetEoln=_IsRetEoln; } } else if (IsTabSep){ // symbol is between tab characters if (IsBof()){GetCh();} if (Ch==TCh::TabCh){ // tab character Sym=syTab; GetCh(); } else if (ChDef->IsTerm(Ch)){ // eoln & eof characters bool _IsRetEoln=IsRetEoln; IsRetEoln=true; IsTabSep=false; GetSym(TFSet()|syEoln|syEof); IsRetEoln=_IsRetEoln; IsTabSep=true; } else { Str.Clr(); while ((!ChDef->IsTerm(Ch))&&(Ch!=TCh::TabCh)){ Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh();} Sym=syStr; QuoteP=false; } } else { // usual symbol while (ChDef->IsSpace(Ch)){GetCh();} SymLnN=LnN; SymLnChN=LnChN; SymChN=ChN; if (ChDef->IsAlpha(Ch)){ if (IsUniStr){Sym=syStr;} else {Sym=syIdStr;} Str.Clr(); UcStr.Clr(); QuoteP=false; do {Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch));} while (ChDef->IsAlNum(GetCh())); if (!RwStrH.Empty()){ TStr RwStr=Str; if (!IsCsSens){RwStr=UcStr;} int SymKeyId=RwStrH.GetKeyId(RwStr); if (SymKeyId!=-1){Sym=TLxSym(int(RwStrH[SymKeyId]));} } if (Expect.In(syBool)){ Sym=syBool; IAssert(TBool::IsValStr(Str)); Bool=TBool::GetValFromStr(Str); } } else if ((Ch=='"')||(Ch=='\'')){ if (IsUniStr){Sym=syStr;} else {Sym=syQStr;} Str.Clr(); UcStr.Clr(); QuoteP=true; QuoteCh=Ch; GetCh(); forever{ while ((Ch!=QuoteCh)&&(Ch!=TCh::EofCh)){ Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh();} if (Ch==TCh::EofCh){ Sym=syUndef; break; } else { GetCh(); if (Ch==QuoteCh){ Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh(); } else { break; } } } } else if ((ChDef->IsNum(Ch))||(IsSigNum&&((Ch=='+')||(Ch=='-')))){ Str.Clr(); bool IntP=true; do {Str.AddCh(Ch);} while (ChDef->IsNum(GetCh())); if (Expect.In(syFlt)){ if (Ch=='.'){ Str.AddCh(Ch); IntP=false; while (ChDef->IsNum(GetCh())){Str.AddCh(Ch);} } if ((Ch=='e')||(Ch=='E')){ Str.AddCh(Ch); GetCh(); IntP=false; if ((Ch=='+')||(Ch=='-')){Str.AddCh(Ch); GetCh();} while (ChDef->IsNum(Ch)){Str.AddCh(Ch); GetCh();} } } UcStr=Str; if (IntP&&(Expect.In(syInt))){ Sym=syInt; Int=atoi(Str.CStr()); } else { Sym=syFlt; Flt=atof(Str.CStr()); } } else if ((Ch==TCh::CrCh)||(Ch==TCh::LfCh)){ Sym=syEoln; if (Ch==TCh::CrCh){if (GetCh()==TCh::LfCh){GetCh();}} else if (Ch==TCh::LfCh){if (GetCh()==TCh::CrCh){GetCh();}} LnN++; LnChN=0; if (!IsRetEoln){GetSym(Expect);} } else if (Ch=='/'){ GetCh(); if ((IsCmtAlw)&&(Ch=='/')){ TChA _CmtStr; do {_CmtStr+=GetCh();} while (!ChDef->IsTerm(Ch)); _CmtStr.Trunc(_CmtStr.Len()-1); _CmtStr.Trunc(); if (Ch==TCh::CrCh){ if (GetCh()==TCh::LfCh){GetCh();} } else if (Ch==TCh::LfCh){ if (GetCh()==TCh::CrCh){GetCh();} } if (IsRetEoln){Sym=syEoln;} else {GetSym(Expect);} CmtStr=_CmtStr; } else if (Ch=='*'){ TChA _CmtStr; do { while (GetCh()!='*'){_CmtStr+=Ch;} _CmtStr+=GetCh(); } while (Ch!='/'); _CmtStr.Trunc(_CmtStr.Len()-2); _CmtStr.Trunc(); GetCh(); GetSym(Expect); CmtStr=_CmtStr; } else { Sym=sySlash; } } else if (Ch==TCh::EofCh){ Sym=syEof; } else { switch (Ch){ case '.': if (GetCh()=='.'){Sym=syDPeriod; GetCh();} else {Sym=syPeriod;} break; case ',': Sym=syComma; GetCh(); break; case ':': if (GetCh()==':'){Sym=syDColon; GetCh();} else {Sym=syColon;} break; case ';': Sym=sySemicolon; GetCh(); break; case '+': Sym=syPlus; GetCh(); break; case '-': Sym=syMinus; GetCh(); break; case '*': Sym=syAsterisk; GetCh(); break; case '/': Sym=sySlash; GetCh(); break; case '%': Sym=syPercent; GetCh(); break; case '!': Sym=syExclamation; GetCh(); break; case '|': Sym=syVBar; GetCh(); break; case '&': Sym=syAmpersand; GetCh(); break; case '=': Sym=syEq; GetCh(); break; case '<': GetCh(); if (Ch=='='){Sym=syLEq; GetCh();} else if (Ch=='>'){Sym=syNEq; GetCh();} else {Sym=syLss;} break; case '>': if (GetCh()=='='){Sym=syGEq; GetCh();} else {Sym=syGtr;} break; case '?': Sym=syQuestion; GetCh(); break; case '#': if (IsCmtAlw){ TChA _CmtStr; do {_CmtStr+=GetCh();} while (!ChDef->IsTerm(Ch)); _CmtStr.Trunc(_CmtStr.Len()-1); _CmtStr.Trunc(); if (Ch==TCh::CrCh){ if (GetCh()==TCh::LfCh){GetCh();} } else if (Ch==TCh::LfCh){ if (GetCh()==TCh::CrCh){GetCh();} } if (IsRetEoln){Sym=syEoln;} else {GetSym(Expect);} CmtStr=_CmtStr; } else { Sym=syHash; GetCh(); } break; case '(': Sym=syLParen; GetCh(); break; case ')': Sym=syRParen; GetCh(); break; case '[': Sym=syLBracket; GetCh(); break; case ']': Sym=syRBracket; GetCh(); break; case '{': Sym=syLBrace; GetCh(); break; case '}': Sym=syRBrace; GetCh(); break; default: Sym=syUndef; GetCh(); break; } } } if ((!Expect.In(Sym))&&(!Expect.Empty())){ if (IsExcept){ TStr MsgStr= TStr("Unexpected symbol (")+GetSymStr()+") ["+GetFPosStr()+"]"; throw PExcept(new TExcept(MsgStr)); } else { Fail; } } return Sym; } TStr TILx::GetStrToCh(const char& ToCh){ Sym=syStr; Str.Clr(); UcStr.Clr(); while ((Ch!=ToCh)&&(Ch!=TCh::EofCh)){ Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh();} return Str; } TStr TILx::GetStrToEolnOrCh(const char& ToCh){ Sym=syStr; Str.Clr(); UcStr.Clr(); while ((Ch!=ToCh)&&(Ch!=TCh::CrCh)&&(Ch!=TCh::LfCh)&&(Ch!=TCh::EofCh)){ Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh();} return Str; } TStr TILx::GetStrToEoln(const bool& DoTrunc){ Sym=syStr; Str.Clr(); UcStr.Clr(); while ((Ch!=TCh::CrCh)&&(Ch!=TCh::LfCh)&&(Ch!=TCh::EofCh)){ Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh();} if (DoTrunc){Str.ToTrunc(); UcStr.ToTrunc();} return Str; } TStr TILx::GetStrToEolnAndCh(const char& ToCh){ Sym=syStr; Str.Clr(); UcStr.Clr(); if (IsBof()){GetCh();} forever { if (Ch==TCh::EofCh){break;} if (((ChN==0)||(PrevCh==TCh::CrCh)||(PrevCh==TCh::LfCh))&&(Ch==ToCh)){ GetCh(); break;} else {Str.AddCh(Ch); UcStr.AddCh(ChDef->GetUc(Ch)); GetCh();} } return Str; } void TILx::SkipToEoln(){ while ((Ch!=TCh::CrCh)&&(Ch!=TCh::LfCh)&&(Ch!=TCh::EofCh)){ GetCh();} if (Ch==TCh::CrCh){if (GetCh()==TCh::LfCh){GetCh();}} else if (Ch==TCh::LfCh){if (GetCh()==TCh::CrCh){GetCh();}} } TLxSym TILx::PeekSym(const int& Syms){ TILxSymSt CurSymSt(*this); TSStack SymStStack; for (int SymN=0; SymNGetSNm(); ChA+=" Line:"; ChA+=TInt::GetStr(LnN+1); ChA+=" Char:"; ChA+=TInt::GetStr(LnChN); return ChA; } TStr TILx::GetQStr(const TStr& Str, const bool& QuoteP, const char& QuoteCh){ if (QuoteP){ TChA ChA; ChA+=QuoteCh; int StrLen=Str.Len(); for (int ChN=0; ChN& StrVV, const bool& NewLn){ StrVV.Clr(); GetVar(VarNm, true, NewLn); while (GetSym(syRBracket, syLBracket)==syLBracket){ StrVV.Add(); while (GetSym(syQStr, syRBracket)==syQStr){ StrVV.Last().Add(Str);} if (NewLn){GetEoln();} } if (NewLn){GetEoln();} } void TILx::GetLnV(const TStr& FNm, TStrV& LnV){ TFIn SIn(FNm); LnV.Clr(); TChA Ln; if (!SIn.Eof()){ char Ch=SIn.GetCh(); while (!SIn.Eof()){ if ((Ch==TCh::CrCh)||(Ch==TCh::LfCh)){ if (!SIn.Eof()){ char PrevCh=Ch; Ch=SIn.GetCh(); if (!SIn.Eof()){ if (PrevCh==TCh::CrCh){if (Ch==TCh::LfCh){Ch=SIn.GetCh();}} else if (PrevCh==TCh::LfCh){if (Ch==TCh::CrCh){Ch=SIn.GetCh();}} } } LnV.Add(Ln); Ln.Clr(); } else { Ln+=Ch; Ch=SIn.GetCh(); } } if (!Ln.Empty()){ LnV.Add(Ln);} } } ///////////////////////////////////////////////// // Lexical-Output void TOLx::PutSep(const TLxSym& Sym){ if (TLxSymStr::IsSep(PrevSym, Sym)){ if (IsTabSep){RSOut.PutCh(TCh::TabCh);} else {RSOut.PutCh(' ');}} PrevSym=Sym; } TOLx::TOLx(const PSOut& _SOut, const TFSet& OptSet, const TLxChDefTy& ChDefTy): ChDef(TLxChDef::GetChDef(ChDefTy)), SOut(_SOut), RSOut(*SOut), IsCmtAlw(false), IsFrcEoln(false), IsSigNum(false), IsUniStr(false), IsCsSens(false), IsTabSep(false), IsVarIndent(false), VarIndentLev(0), RwStrH(50), RwSymH(50), PrevSym(syUndef){ for (int Opt=0; OptGetUcStr(Str); IAssert(!RwStrH.IsKey(UcStr)); TLxSym RwSym=TLxSym(syMnRw+RwStrH.Len()); RwStrH.AddDat(Str, TInt(int(RwSym))); RwSymH.AddDat(TInt(int(RwSym)), Str); return RwSym; } void TOLx::PutSym(const TLxSym& Sym){ TStr Str; if ((syMnRw<=Sym)&&(Sym<=syMxRw)){ Str=Str=RwSymH[Sym]; } else { Str=TLxSymStr::GetSymStr(Sym); } PutSep(Sym); RSOut.PutStr(Str); } void TOLx::PutVarBoolV(const TStr& VarNm, const TBoolV& BoolV, const bool& NewLn, const bool& CheckIdStr){ PutVar(VarNm, true, NewLn, CheckIdStr); for (int BoolN=0; BoolN& StrVV, const bool& NewLn, const bool& CheckIdStr){ PutVar(VarNm, true, NewLn, CheckIdStr); for (int StrVN=0; StrVNEof()) ? TCh::EofCh : SIn->GetCh()); //putchar(Ch); return Ch; } bool TPreproc::IsSubstId(const TStr& SubstId, TStr& SubstValStr) const { if (SubstIdToKeyIdValPrVH.IsKey(SubstId)){ const TStrPrV& KeyIdValPrV=SubstIdToKeyIdValPrVH.GetDat(SubstId); for (int KeyN=0; KeyNGetTok()->GetTagTokV("Subst", SubstTokV); for (int SubstTokN=0; SubstTokNGetArgVal("Id", ""); if (!SubstId.Empty()){ // create substitution TStrPrV& KeyIdValPrV=SubstIdToKeyIdValPrVH.AddDat(SubstId); // get list of substitution-strings TXmlTokV StrTokV; SubstTok->GetTagTokV("Str", StrTokV); for (int StrTokN=0; StrTokNGetArgVal("Key", ""); TStr ValStr=StrTok->GetTokStr(false); // assign key-value-pair if (!KeyId.Empty()){ KeyIdValPrV.Add(TStrPr(KeyId, ValStr)); } } } } } // substitution // open files SIn=TFIn::New(InFNm); PSOut SOut=TFOut::New(OutFNm); // set copy & ignore mode bool CopyModeP=false; bool IgnoreModeP=false; GetCh(); while (Ch!=TCh::EofCh){ if (isalpha(Ch)||(((PrevCh=='\0')||(PrevCh=='\r')||(PrevCh=='\n'))&&(Ch=='#'))){ // collect identifier TChA IdChA; do { IdChA+=Ch; GetCh(); } while ((Ch!=TCh::EofCh)&&(isalnum(Ch))); // check identifier if (IdChA=="#ifdef"){ // collect condition-key-id TChA CondKeyIdChA; while ((Ch!=TCh::EofCh)&&(Ch!='\n')&&(Ch!='\r')){ CondKeyIdChA+=Ch; GetCh();} // skip eoln if (Ch=='\n'){GetCh(); if (Ch=='\r'){GetCh();}} else if (Ch=='\r'){GetCh(); if (Ch=='\n'){GetCh();}} // check for key CondKeyIdChA.Trunc(); IAssert(CopyModeP==false); IAssert(IgnoreModeP==false); if (SubstKeyIdV.IsIn(CondKeyIdChA)){ CopyModeP=true; IgnoreModeP=false; } else { CopyModeP=false; IgnoreModeP=true; } } else if (IdChA=="#endif"){ // move to eoln while ((Ch!=TCh::EofCh)&&(Ch!='\n')&&(Ch!='\r')){ GetCh();} // skip eoln if (Ch=='\n'){GetCh(); if (Ch=='\r'){GetCh();}} else if (Ch=='\r'){GetCh(); if (Ch=='\n'){GetCh();}} // reset copy&ignore modes IAssert(CopyModeP||IgnoreModeP); CopyModeP=false; IgnoreModeP=false; } else { // substitution or add id-as-seen TStr SubstValStr; if ((!CopyModeP)&&(IsSubstId(IdChA, SubstValStr))){ if (!IgnoreModeP){SOut->PutStr(SubstValStr);} } else { if (!IgnoreModeP){SOut->PutStr(IdChA);} } } } else { // single character if (!IgnoreModeP){SOut->PutCh(Ch);} GetCh(); } } }