/// <summary> /// Tries tp match SymbolDefinitionLine against input source /// </summary> /// <param name="iIndex"></param> /// <param name="part">Parent TrackPart entity</param> /// <param name="trackingNode"></param> /// <param name="line"></param> private bool MatchSymbolLine(int iIndex, TrackPart part, TreeNode trackingNode, SymbolLineDefinition line) { int startIndex = iIndex; TrackPart tempart = null; SymbolLineDefinition matchedLine = line; List<TrackPart> lp = new List<TrackPart>(); //ddt(+1, "LINE DEF"); TreeNode tn2 = PushNode(trackingNode, line.ToString()); foreach (SymbolLineDefinitionItem sdi in line) { UInt32 numberOfOccurences = 0; while (numberOfOccurences < sdi.max) { tempart = TrySymbol(tn2, sdi, startIndex); if (tempart.status != TrackStatus.MATCHED) break; lp.Add(tempart); startIndex = tempart.end + 1; numberOfOccurences++; } if (numberOfOccurences < sdi.min) { if (part.end < startIndex - 1) { part.end = startIndex - 1; part.children = lp; } matchedLine = null; break; } } if (matchedLine != null) { // line was matched // we have to subtract 1 from startIndex, because value // in startIndex was prepared for next item, but now we are // ending with comparision, so we need not next item // but we need last item, which is 1 step back part.end = startIndex - 1; part.status = TrackStatus.MATCHED; part.children = lp; //ddt(-1, "--LINE DEF - SUCC"); tn2.SelectedImageIndex = tn2.ImageIndex = 1; return true; } else { // line failed, go to next line //ddt(-1, "--LINE DEF - FAIL"); tn2.SelectedImageIndex = tn2.ImageIndex = 2; } return false; }
/// <summary> /// <summary> /// For given line definition, do throug all items (except first) /// and try to match /// If item fails, then return null, which is signal to caller method /// that this line was not matched /// </summary> /// <param name="line"></param> /// <param name="p"></param> /// <returns>TrackPart is returned, but only children, end /// and status is used in caller function</returns> private TrackPart MatchSymbolLineFromSecond(TreeNode tn, SymbolLineDefinition line, int p) { TrackPart result = new TrackPart(); result.children = new List<TrackPart>(); TrackPart part; int startIndex = p; for (int j = 1; j < line.Count; j++ ) { SymbolLineDefinitionItem sdi = line[j]; part = TrySymbol(tn, sdi, startIndex); if (part.status == TrackStatus.MATCHED) { result.children.Add(part); startIndex = part.end + 1; } else { return null; } } // line was matched result.end = startIndex - 1; result.status = TrackStatus.MATCHED; return result; }
/// <summary> /// Reads definition of BNF analyzer. Lines starting with /// 4 spaces are child lines to those /// that starts with letter /// </summary> /// <param name="script"></param> public void LoadText(string script) { SymbolDefinition symbol = null; string[] lines = script.Split('\r', '\n'); foreach(string line in lines) { if (line.Length > 0) { if (line.StartsWith(" ")) { if (symbol != null) { SymbolLineDefinition sd = new SymbolLineDefinition(); sd.SetString(line.Substring(4)); symbol.InsertLine(sd); } } else { symbol = new SymbolDefinition(); symbol.symbolText = line; symbolsList.Add(symbol); symbolsMap.Add(line, symbol); } } } }