public static Dictionary<ktString, ktString> ParseInfoString( ktString InfoStr ) { int p = 0, p2 = 0; ktString property; ktString prop_name, prop_value; Dictionary<ktString, ktString> InfoMap = new Dictionary<ktString, ktString>(); while (!InfoStr.IsEmpty()) { p = InfoStr.IndexOf(';'); if (p < 0) { property = InfoStr; p = InfoStr.Length() - 1; } else { property = InfoStr.SubString(0, p).Trim(); } p2 = property.IndexOf('='); prop_name = property.SubString(0, p2).AsUpper(); prop_value = property.SubString(p2 + 1); InfoMap.Add(prop_name, prop_value); InfoStr.Remove(0, p + 1); InfoStr = InfoStr.Trim(); } return InfoMap; }
/// <summary> /// Scan/Parse the script into tokens /// </summary> public bool Scan(ktString Script, ktString Name) { bool Ret = true; Script.Replace("\r\n", "\n",true); // Initiate the lineno. m_CurLine = 1; m_CharPos = 1; // .. and name m_Name = Name; if (m_Tokens != null) { m_Tokens.Clear(); m_Tokens = null; } // Init... ktString Line = new ktString(); int Pos = 0; Script.Trim(); ktRegEx RE = new ktRegEx(ktToken.Separators); // ... the block-stack if (m_BlockStack != null) { m_BlockStack.Clear(); m_BlockStack = null; } m_BlockStack = new ktList(); // ... the token-list if (m_Tokens != null) { m_Tokens.Clear(); m_Tokens = null; } m_Tokens = new ktList(); m_Tokens.Node = new ktNode("ktTStatement", new ktToken(ktTokenType.Statement, "", 0, 0)); // ... the token-stack if (m_TokenStack != null) { m_TokenStack.Clear(); m_TokenStack = null; } m_TokenStack = new ktList(); // ... the lines (??) if (m_Lines != null) { m_Lines.Clear(); m_Lines = null; } m_Lines = new ktList(); m_Lines.Node = new ktNode(Name, m_CurToken = new ktToken(ktTokenType.Program, Name, 0, 0)); // ... the line-stack if (m_LineStack != null) { m_LineStack.Clear(); m_LineStack = null; } m_LineStack = new ktList(); if (m_MainBlock == null) { m_MainBlock = new ktBlock(new ktList()); } else { if (m_MainBlock.Lines != null) { m_MainBlock.Lines.Clear(); } m_MainBlock.ClearKTSymbols(); } m_MainBlock.SetMain(this); m_BlockStack.Add("ktTBlock", m_MainBlock); /* In the "original scanner" (C++), we took one line (terminated by \n) * at a time and worked on, now we just go through the line. * And We hope that it will be much "leaner"! */ // Go on until the there's nothing left... while (!Script.IsEmpty()) { // Get the position for the next separator Pos = RE.Find(Script); // If there was none... if (Pos < 0) { // Take it to the end... Pos = Script.Len(); } else if (Pos == 0) { Pos++; } // Get the next "token" Line = Script.SubStr(0, Pos); // If it's the start of a comment if ((Line == "/") && (Script.StartsWith("//") || Script.StartsWith("/*"))) { Line = Script.SubStr(0, 2); Pos++; } else if ((Line == "*") && (Script.StartsWith("*/"))) { Line = "*/"; Pos++; } ReactOnToken(Line, m_CurLine, ref m_CharPos); if (Line == "\n") { m_CurLine++; m_CharPos = 1; } else { m_CharPos += Line.Len(); } // Remove the "token", we just worked on... Script.Remove(0, Pos); } #if ParseDebug || DebugXML ktDebug.Log("XML111111:"); ktDebug.Log(ktXML.FromList(m_TokenStack).AsXML()); ktDebug.Log("=================="); ktDebug.Log(ktXML.FromList(m_Tokens).AsXML()); #endif if (!m_Tokens.IsEmpty()) { if (m_AllowMissingEOL) { ((ktToken)m_Tokens.Node.Value).Type = ktTokenType.Line; ((ktToken)m_Tokens.Node.Value).Name = m_Tokens.Node.Name = "ktTLine"; m_LineStack.AddList(m_Tokens); m_Tokens = null; } else { throw new ktError("Expected a ktTEOL at line " + m_CurLine.ToString() + " but didn't find one!", ktERR.MISSING); } } if (m_BlockStack.Count > 1) { throw new ktError("Expecting ktTEOB (}) at " + m_CharPos.ToString() + ", line " + m_CurLine.ToString() + ".", ktERR.MISSING); } //ktToken.OnlyExportValue = false; //ktDebug.Log( m_LineStack.Get_R( ) ); //ktToken.OnlyExportValue = false; #if ParseDebug || DebugXML ktDebug.Log( "XML:" ); ktDebug.Log( ktXML.FromList(m_LineStack).AsXML() ); ktDebug.Log( "==================" ); ktDebug.Log( ktXML.FromList(m_Lines).AsXML() ); #endif /* ktDebug.Log( "?+++++\n" + m_Tokens.Get_R( "\t", true ) ); ktDebug.Log( "?+++++\n" + m_CurToken.Export if (m_CurToken != null) { if (m_CurToken.Type == ktTokenType.List) { throw new ktError( "Expected a ktTEndPar at line " + m_CurLine.ToString() + " but didn't find one!", ktERR.MISSING ); } else if (m_CurToken.Type == ktTokenType.String) { throw new ktError( "Expected a ktTStringQuot at line " + m_CurLine.ToString() + " but didn't find one!", ktERR.MISSING ); } else if (m_CurToken.Type == ktTokenType.Block) { throw new ktError( "Expected a ktTEndOfBlock at line " + m_CurLine.ToString() + " but didn't find one!", ktERR.MISSING ); } } else if ((m_Tokens != null) && (!m_Tokens.IsEmpty())) { throw new ktError( "Expected a ktTEOL at line " + m_CurLine.ToString() + " but didn't find one!", ktERR.MISSING ); } */ // MakeATree( ); // MakeAOpTree( ); if ((m_BlockStack == null) || (m_BlockStack.IsEmpty())) { return Ret; } ktBlock Block = (ktBlock)(m_BlockStack.Pop().Node.Value); #if ParseDebug ktDebug.Log( "BLOCK1:" + ktXML.FromList(Block.Lines).AsXML() );r #endif MakeATree(); #if ParseDebug ktDebug.Log("BLOCK2:" + ktXML.FromList(m_Lines).AsXML()); #endif Block.Lines = MakeAOpTree(); m_LineStack.Clear(); m_LineStack = null; // Add Current "statement"/"post" to the block and theń switch them //Temp.AddList( m_Tokens ); //m_Tokens = Temp; #if ParseDebug ktDebug.Log( "BLOCK:" + ((Block == m_MainBlock) ? "MAIN":"NOT_MAIN") ); #endif /*ktList Temp = null; if (LastBlockLines == null) { throw new ktError( "No Last Block Lines!", ktERR.MISSING ); } LastBlockLines.Add( "ktTBlock", new ktToken( Block, m_CurToken.LineNo, m_CurToken.CharPos ) );*/ #if ParseDebug || DebugXML ktDebug.Log( "XML_After Tree:" + ktXML.FromList(Block.Lines).AsXML() ); ktDebug.Log( "XML_After Tree:" + Block.Lines.Get_R( "\t", true ) ); #endif //ktDebug.Log( m_Lines.Export() ); return Ret; }
// Set the pattern to use public bool SetPattern(ktString Pattern) { RegexOptions Opt = new RegexOptions(); switch (m_Mode) { case ktRE_Mode.PERL: { ktString OPattern = new ktString(Pattern); char Delim = Pattern.First(); Pattern.RemoveFirst(); int Pos = Find(Pattern, @"[^\\]" + Delim.ToString()); if (Pos < 0) { throw new ktError("ktRegEx::SetPattern() : The pattern isn't Perl compatible (" + OPattern + ")", ktERR.NOTFOUND); } else { Pos++; } ktString Modifiers = Pattern.SubStr(Pos + 1); Pattern.Remove((uint)Pos); for (uint I = 0; I < Modifiers.Len(); I++) { // Console.Write( Modifiers[I].ToString() + ";" ); switch (Modifiers[I]) { case 'i': { Opt = Opt | RegexOptions.IgnoreCase; break; } case 'm': { Opt = Opt | RegexOptions.Multiline; break; } case 'x': { Opt = Opt | RegexOptions.IgnorePatternWhitespace; break; } case 'A': { if (Pattern.First() != '^') { Pattern.Prepend("^"); } break; }/* case 'i': { Opt = Opt | RegexOptions.IgnoreCase; break; }*/ } } break; } case ktRE_Mode.Plain: { break; } default: { throw new ktError("ktRegExp::SetPattern(): The mode '" + GetModeAsString() + "' is not implementet yet!", ktERR.NOTIMP); } } // Set the pattern m_Pattern = Pattern; // Take care of the (if any) exception try { // Create the (internal) regex object m_P = new Regex(m_Pattern.GetValue(), Opt); } catch (ktError Ex) { SetError("Couldn't set pattern and create a new (internal) Regex object" + Ex.Message, ktERR.REGEX_COULDNT_SET_PATTERN); return false; } catch (Exception Ex) { SetError("Couldn't set pattern and create a new (internal) Regex object" + Ex.Message, ktERR.REGEX_COULDNT_SET_PATTERN); return false; } return true; }
// Match and compare... // Find, but with a mask (using ? and *) public bool Matches(ktString Mask) { /* ** <note> For now we just cross our fingers and hopes that this function (/method?) actually works. We haven't runned this code yet. (BTW this goes with most of the whole class...)</note> ***/ bool Match = false; bool GoOn = true; int Pos; ktTripple Joker = 0; // 1 == * and 2 == ? ktString MatchTmp; ktString Str = new ktString(GetValue()); // Don't stop until we say so while (GoOn) { Joker = 0; // If there's no more "Joker" if ((Pos = ktRegEx.Find(Mask.GetValue(), "\\*|\\?")) < 0) { // If (the rest of) the mask matches the string if (Mask == Str) { // Stop looping GoOn = false; // And "OK it" Match = true; } else { // Stop looping GoOn = false; // Didn' match... Match = false; } } else { // Find a "Joker" and get everything infront of it MatchTmp = Mask.SubStr(0, Pos); // Remove what we got from the mask Mask.Remove(0, MatchTmp.Length()); // Chech the "Joker" // If the first char is * in the "new mask" // then indicate that if (Mask.First() == '*') Joker = 1; // Or if it's ?... else Joker = 2; // Remove the "Joker" Mask.RemoveFirst(); // If this part of the mask doesn't match... (simply not a match) if ((!MatchTmp.IsEmpty()) && (MatchTmp != Str.SubStr(0, MatchTmp.Length()))) { // Stop looping GoOn = false; Match = false; } else { // As we now that this part of the mask matches the string // Remove that part from the string Str.Remove(0, MatchTmp.Length()); // If the "Joker" is * if (Joker == 1) { // Get the position of the next "Joker" Pos = ktRegEx.Find(Mask.GetValue(), "\\*|\\?"); // If we didn't find a new "Joker" if (Pos < 0) { // get the length of the rest of the mask ("find the end") Pos = Mask.Length(); // If Pos is 0 if (Pos == 0) // No more mask... Pos = -1; } // If Pos is less than 0 // This (should) means that the * was the last thing in // the mask and should therefor match the rest of the string if (Pos < 0) { // Stop looping GoOn = false; // It's a match... Match = true; } else { // Get the next part of the mask MatchTmp = Mask.SubStr(0, Pos); // Remove that part of the mask... Mask.Remove(0, Pos); // If the "submask" matches the corresponding "substring" if ((Pos = Str.Find(MatchTmp)) >= 0) { // The substring matched... Match = true; // Remove the matched "substring" Str.Remove(0, Pos + MatchTmp.Length()); // If the mask now is empty if (Mask.IsEmpty()) { // Stop looping GoOn = false; // If the string isn't empty if (!Str.IsEmpty()) // As the mask is empty but not the // the string, it means that it's // an missmatch... Match = false; } // It wasn't a match (the match failed... } else { // Stop looping GoOn = false; Match = false; } } // If the "Joker" is ? } else { // Just remove the first char Str.RemoveFirst(); // As the mask has matched so far... Match = true; } } } // If the mask is empty (and we can go on) // Means that the mask matched the string if (((Str == "") || (Mask == "")) && (GoOn)) { // Stop looping GoOn = false; // And "OK it" Match = true; } } return Match; }