/// <summary> /// This function will get the list/child corresponding the keys /// (Keys can basically be a path [similar to a filesystem or XPath] /// ex: "/root/child/subchild" or just an "element"/key) /// </summary> /// <param name="Keys">The path to the node/child</param> /// <param name="ReturnAll">Should we return all that matches?</param> public ktList Get(ktString Keys, bool ReturnAll) { // Init... ktString Key; ktString TmpKeys = Keys; // Temporary to save the given value // Remove leading slashs (/).. Keys.Trim(ktStripType.leading, "/"); if (Keys.Contains("/")) { // Get the first key Key = Keys.BeforeFirst('/'); // Remove the first key Keys = Keys.AfterFirst('/'); } else { Key = Keys; } // If the given key matches the key of "this node" (or we didn't get a key) if ((m_Node != null) && (m_Node.Check(Key)) || (Key == "")) { // Return "this" return this; } // No elements?? if (m_Head == null) { // there's nothing to get throw new ktError("The list is empty (in ktList::Get( " + TmpKeys + ", bool ))", ktERR.EMPTY); } // Init... ktList TmpList = null; ktList AllMatches = null; bool GoOn = true; Reset(); // Should we return all matches? if (ReturnAll) { AllMatches = new ktList(); } // Go thru the list.. while (MoveNext() && GoOn) { // Try it... try { // Get the "sublist(s)" TmpList = CurrentNode.Get(Keys, ReturnAll); // Key or Keys?? // If we should return all if (ReturnAll) { // Add the found list... (and then go on) AllMatches.Add(TmpList); } else { // Stop looking... GoOn = false; } // Catch an error... } catch (ktError E) { // If it was an error other than "Not found" or empty... if ((E.ErrorNumber != ktERR._404) && (E.ErrorNumber != ktERR.EMPTY)) { // Re-throw it throw E; } // If } // Catch } // While // If we should return all matches and // we found something (The list isn't empty) if (ReturnAll && (!AllMatches.IsEmpty())) { // Set GoOn to false (as it marks a found node/list) GoOn = false; } // If we should get all matches but only found one if (ReturnAll && (AllMatches.GetCount() == 1)) { // Get the first (and only) child TmpList = AllMatches.First; // Set "match/return all" to false ReturnAll = false; // Set tail and head to null... AllMatches.m_Head = AllMatches.m_Tail = null; // Dispose of the list... AllMatches.Dispose(); } // If we didn't find a match if (GoOn) { // Throw an error throw new ktError("Couldn't find the list '" + TmpKeys + "' (in ktList::Get( " + TmpKeys + " ))", ktERR._404); // If we should return all matches... } else if (ReturnAll) { // Return the list return AllMatches; // Found an match } else { // Return it.. return TmpList; } }
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; }