public StmtWordListCursor NextDeepFromParent(StmtWord InChildWord) { StmtWordListCursor c1 = null; // end of the line if this node does not have a parent. if (InChildWord.Parent == null) { c1 = new StmtWordListCursor( null, null, WhichEdge.None, RelativePosition.End); } // parent is the TopWord. Top word is special in that it is not a node in // a word list. else if (InChildWord.Parent.IsTopWord == true) { LinkedListNode <StmtWord> node = new LinkedListNode <StmtWord>(InChildWord.Parent); c1 = new StmtWordListCursor( null, node, WhichEdge.TrailEdge, RelativePosition.At); } // position at the trailing edge of the parent word. else { StmtWord par = InChildWord.Parent; c1 = new StmtWordListCursor( par.SubWords, par.SubWordNode, WhichEdge.TrailEdge, RelativePosition.At); } return(c1); }
// -------------------------- StmtWordToPresentationString ----------------------- static string StmtWordToPresentationString(StmtWord InWord, int InLevel) { StringBuilder sb = new StringBuilder(); sb.Append(InLevel.ToString() + " " + InWord.CompositeCode.ToString()); // nbr of sub words if (InWord.HasSubWords == true) { sb.Append(" " + "wCx:" + InWord.SubWords.Count.ToString()); } // the delimeter of the word is found in the EndCursor of the word. if (InWord.EndCursor != null) { sb.Append(" " + InWord.EndCursor.ToDelimPresentationString()); } // word classification if (InWord.WordCursor != null) { sb.Append(" wc: " + InWord.WordCursor.WordClassification.ToString()); } // the text of the word sb.Append(" wt: " + InWord.WordText); return(sb.ToString()); }
/// <summary> /// Get next stmt word deep. Assert that word gotten is either a sibling or child. /// Also assert that gotten word composite code is any of array of values. /// </summary> /// <param name="InAssertNodeRltv"></param> /// <param name="InAssertEqualAnyCompositeCode"></param> /// <param name="InExceptionText"></param> /// <returns></returns> public StmtWordListCursor NextDeep( AssertNextNodeRelative InAssertNodeRltv, WordCompositeCode[] InAssertEqualAnyCompositeCode, string InExceptionText) { StmtWord startWord = null; StmtWord nextWord = null; // Setup startWord. Current cursor must be at a word. if (this.Position != RelativePosition.At) { throw new ApplicationException( InExceptionText + " Not positioned at start word."); } startWord = this.Node.Value; // do the actual get next. StmtWordListCursor c1 = NextDeep(); // isolate next word. if (c1.Position == RelativePosition.At) { nextWord = c1.Node.Value; } if (InAssertNodeRltv == AssertNextNodeRelative.IsChild) { if ((nextWord == null) || (nextWord.IsChildOf(startWord) == false)) { throw new ApplicationException(InExceptionText + " No child words."); } } if (InAssertNodeRltv == AssertNextNodeRelative.IsSibling) { if ((nextWord == null) || (nextWord.IsSiblingOf(startWord) == false)) { throw new ApplicationException(InExceptionText + " No next sibling word."); } } if (InAssertEqualAnyCompositeCode != null) { if (nextWord == null) { throw new ApplicationException(InExceptionText + " Next word not found."); } else if (Array.IndexOf <WordCompositeCode>( InAssertEqualAnyCompositeCode, nextWord.CompositeCode) == -1) { throw new ApplicationException(InExceptionText + " Unexpected composite code " + nextWord.CompositeCode.ToString()); } } return(c1); }
// ----------------------- ReportParsedWords ------------------------------- public static ParsedWordsReport ReportParsedWords(StmtWord TopWord) { ParsedWordsReport r1 = new ParsedWordsReport(); StmtWordCursor c1 = new StmtWordCursor(TopWord); r1.AddTextLine(BuildLegend()); // show the first 5 lines of the stmt text. { string s1 = TopWord.StmtText.SubstringLenient(TopWord.BeginCursor.WordBx, 500); string[] lines = s1.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); int cx = 0; int bx = 0; foreach (string s2 in lines) { if (s2.IsNullOrEmpty() == false) { r1.AddTextLine(bx.ToString( ) + ") " + s2); cx += 1; if (cx > 5) { break; } } bx += (s2.Length + Environment.NewLine.Length); } r1.AddSepLine(); } StmtWord w1 = null; StmtWord pvWord = null; while (true) { pvWord = w1; c1 = c1.NextDeep(); if (c1 == null) { break; } w1 = c1.Node; if ((pvWord != null) && (pvWord.Depth != w1.Depth)) { r1.AddSepLine(); } r1.AddTextLine(CursorToPresentationString(c1)); } return(r1); }
// ----------------------- ReportParsedWords ------------------------------- public static ParsedWordsReport ReportParsedWords(Stmt InStmt) { ParsedWordsReport r1; int lvl = 0; StmtWord parentWord = InStmt.TopWord; r1 = ReportParsedWords(InStmt, parentWord, lvl); return(r1); }
/// <summary> /// cursor is at the leading edge of a braced word. /// </summary> /// <param name="InOpenBracePattern"></param> /// <returns></returns> public bool IsLeadEdgeBraced(string InOpenBracePattern) { if (IsLeadEdge == true) { if (StmtWord.IsBraced(InOpenBracePattern) == true) { return(true); } } return(false); }
// build a complex that contains the lines to parse concatenated together. // The complex also a cross reference for converting buffer locations to // line positions. // ParseBufferComplex buf = new ParseBufferComplex(InTextLines); public static StmtWord ParseTextLines( ParseBufferComplex ParseBuf, StmtTraits Traits) { StmtWord topWord = null; WordCursor csr = Scanner.PositionBeginWord(ParseBuf.Buffer, Traits); topWord = new StmtWord(ParseBuf.Buffer, null, null, WordCompositeCode.General); csr = ParseParent(ParseBuf.Buffer, Traits, csr, topWord); return(topWord); }
// ----------------------- ReportParsedWords ------------------------------- public static ParsedWordsReport ReportParsedWords( StmtWord InParentWord, int InLevel) { ParsedWordsReport r1 = new ParsedWordsReport(); StmtWord parentWord = InParentWord; if (InLevel == 0) { r1.AddTextLine(BuildLegend()); // show the stmt text ( up until any NewLine pattern in the string ) string s1 = parentWord.StmtText.SubstringLenient(parentWord.BeginCursor.WordBx, 100); int fx = s1.IndexOf(Environment.NewLine); if (fx != -1) { s1 = s1.Substring(0, fx); } r1.AddTextLine(s1); r1.AddTextLine(StmtWordToPresentationString(parentWord, InLevel)); ParsedWordsReport r2 = null; r2 = ReportParsedWords(parentWord, InLevel + 1); r1.AddReport(r2); } else { r1.AddSepLine(); foreach (StmtWord subWord in parentWord.SubWords) { r1.AddTextLine(StmtWordToPresentationString(subWord, InLevel)); if (subWord.HasSubWords == true) { var r3 = ReportParsedWords(subWord, InLevel + 1); r1.AddReport(r3); } } r1.AddSepLine(); } return(r1); }
public StmtWordListCursor( StmtWord Word, WhichEdge Edge, RelativePosition Rltv) { if (Word.IsTopWord == true) { mList = null; mRltv = Rltv; mNode = new LinkedListNode <StmtWord>(Word); mEdge = Edge; } else { mList = Word.Parent.SubWords; mRltv = Rltv; mEdge = Edge; mNode = Word.SubWordNode; } }
public bool IsCorrTrailEdge(StmtWordListCursor InLeadEdge) { bool isTrailEdge = false; if (InLeadEdge.IsLeadEdge == false) { throw new ApplicationException("argument is not a lead edge cursor"); } if (IsTrailEdge == true) { StmtWord teWord = this.StmtWord; StmtWord leWord = InLeadEdge.StmtWord; // the leading and trailing edge cursor contains the same StmtWord. if (teWord == leWord) { isTrailEdge = true; } } return(isTrailEdge); }
public StmtWordListCursor(StmtWord Word) : this(Word, WhichEdge.LeadEdge, RelativePosition.Before) { }
/// <summary> /// This is the central method where the cracking of statement text into a hierarchy /// of StmtWord(s) takes place. /// </summary> /// <param name="InStmtText"></param> /// <param name="InTraits"></param> /// <param name="InParentStart"></param> /// <param name="InParentWord"></param> /// <returns></returns> static WordCursor ParseParent( string StmtText, StmtTraits Traits, WordCursor ParentStart, StmtWord ParentWord) { WordCursor csr = ParentStart; StmtWord parentWord = ParentWord; StmtWord word = null; while (true) { word = null; // get next word in the stmt string. csr = Scanner.ScanNextWord(StmtText, csr); // end of string. Got nothing. if (csr.IsEndOfString == true) { break; } // word is start of a sentence. if ((Traits.FormSentencesFromWhitespaceDelimWords == true) && (parentWord.IsSentence == false)) { if ((csr.DelimIsWhitespace == true) || (csr.DelimIsOpenBrace == true)) { if (csr.WordClassification != WordClassification.CommentToEnd) { word = new StmtWord(StmtText, parentWord, csr, WordCompositeCode.Sentence); csr.StayAtFlag = true; csr = ParseParent(StmtText, Traits, csr, word); // word.EndCursor.AssignDelimPart(csr); } } } // Word is braced. Make a composite word, then recursively call this method to // parse the contents. bool bracedWordWasParsed = false; if ((word == null) && (csr.WordIsOpenBrace == true)) { word = new StmtWord(StmtText, parentWord, csr, WordCompositeCode.Braced); csr = ParseParent(StmtText, Traits, csr, word); bracedWordWasParsed = true; // this braced word may be the start of a sentence. if ((Traits.FormSentencesFromWhitespaceDelimWords == true) && (parentWord.IsSentence == false)) { if ((csr.DelimIsWhitespace == true) || (csr.DelimIsOpenBrace == true)) { StmtWord w2 = new StmtWord( StmtText, parentWord, word.WordCursor, WordCompositeCode.Sentence); word.Parent = w2; } } } // add the standalone word to the parent word if (word == null) { // this word might be the whitespace after an EndStmt delim sentence and the // end of the braced parent. ( ex: return _Name ; } ) // todo: draw distinction between skipping the empty word before a close brace // and the empty word after a comma delim sequence. ex: { a, b, c, } if (csr.IsDelimOnly == false) { word = new StmtWord(StmtText, parentWord, csr, WordCompositeCode.Atom); } } // is the final word in a sentence. // note: a semicolon or comma will end a sentence. if (parentWord.CompositeCode == WordCompositeCode.Sentence) { if ((csr.DelimIsWhitespace == false) && (csr.DelimIsAssignmentSymbol == false)) { break; } // sentence also ends when word is braced and this braced word is not the // first word in the sentence. ex: get { return _Name ; } else if ((bracedWordWasParsed == true) && (parentWord.SubWords.Count > 1)) { break; } } // final word in a Braced sequence. if (parentWord.CompositeCode == WordCompositeCode.Braced) { // the close brace delim is the closing brace of the parent word. // ex: { wd1 wd2 } the } delim for wd2 applies to the braced word. if ((csr.DelimIsCloseBrace == true) && ((word == null) || (word.OwnsCloseBracedDelim == false))) { // save the location of the closing brace. parentWord.CloseBracePosition = csr.DelimBx; parentWord.CloseBraceCursor = csr; // cursor is located at the closing brace. We want the word after the closing // brace to always be a delim only word. In a parent where members are delimed // by comma this is no problem. But in a whitespace sep list, this might not // be the case without a little helpful adjustment. csr = Scanner.ScanNextWord(StmtText, csr); csr.StayAtFlag = true; if (csr.IsDelimOnly == true) { csr.StayAtFlag = false; parentWord.CloseBraceCursor = csr; } else if ((csr.WordClassification == WordClassification.OpenNamedBraced) || (csr.WordClassification == WordClassification.OpenContentBraced)) { csr.SetVirtualCursor_WhitespaceOnly(csr.WordBx - 1); csr.StayAtFlag = false; } break; } } // line break. consider end of first pass processing of the stmt words // when the paren level is zero. // if ((csr.DelimClass == DelimClassification.NewLine) && ( word.ParenLevel == 0 )) // break ; } return(csr); }
// what first pass processing does: // - cracks the stmt stream into a sequence of delim separated words // - organizes the words in a bracket organized hierarchy // - possibly, groups the words into stmt units based on end of stmt and // new line delimeters spcfd in StmtTraits. Also on the comment // markers contained in StmtTraits. // public static WordCursor FirstPass( string InStmtText, StmtTraits InTraits, WordCursor InCsr, StmtWord InParentWord) { WordCursor csr = InCsr; StmtWord fsWord = null; StmtWord parentWord = InParentWord; int xx = 0; while (true) { xx += 1; csr = Scanner.ScanNextWord(InStmtText, csr); if (csr.IsEndOfString == true) { break; } StmtWord word = new StmtWord(InStmtText, parentWord, csr); // this word is start of stmt. if (fsWord == null) { fsWord = word; } // word is start of a sentence. if ((InTraits.FormSentencesFromWhitespaceDelimWords == true) && (parentWord.IsComposite == false)) { if ((csr.DelimIsWhitespace == true) || (csr.DelimIsOpenBrace == true)) { word.CompositeCode = WordCompositeCode.Sentence; parentWord = word; word = new StmtWord(InStmtText, parentWord, csr); } } // the EndStmt delim is considered to seperate stmts within this parent // StmtElem. Since we have saved the reference to the first word of the // parent, the first and last words of the stmt can be marked. if (csr.DelimClass == DelimClassification.EndStmt) { if (fsWord != null) { fsWord.BeginStmtWord = fsWord; fsWord.EndStmtWord = word; word.BeginStmtWord = fsWord; word.EndStmtWord = word; } fsWord = null; } // word is braced ( a function ). collect all the words within the braces. if (csr.WordIsOpenBrace == true) { csr = FirstPass(InStmtText, InTraits, csr, word); // cursor is located at the closing brace. We want the word after the closing // brace to always be a delim only word. In a parent where members are delimed // by comma this is no problem. But in a whitespace sep list, this might not // be the case without a little helpful adjustment. csr = Scanner.ScanNextWord(InStmtText, csr); csr.StayAtFlag = true; if (csr.IsDelimOnly == true) { } else if ((csr.WordClassification == WordClassification.OpenNamedBraced) || (csr.WordClassification == WordClassification.OpenContentBraced)) { csr.SetVirtualCursor_WhitespaceOnly(csr.WordBx - 1); } } // end of a sentence. else if ((parentWord.CompositeCode == WordCompositeCode.Sentence) && (csr.DelimIsWhitespace == false)) { return(csr); } // todo: have to expand this throw exception when the closing brace does // not match the open brace. else if (csr.DelimClass == DelimClassification.CloseBraced) { break; } } return(csr); }
// -------------------------- CursorToPresentationString ----------------------- static string CursorToPresentationString(StmtWordCursor Cursor) { StringBuilder sb = new StringBuilder(); // the StmtWord the cursor is at. if ((Cursor.Position != RelativePosition.At) && (Cursor.Position != RelativePosition.After)) { throw new ApplicationException("Cursor must be positioned at a StmtWord"); } StmtWord sw = Cursor.Node; sb.Append(sw.Depth.ToString() + " " + sw.CompositeCode.ToString()); // the trailing edge of a composite word if (Cursor.Position == RelativePosition.After) { sb.Append(" TrailingEdge."); } // nbr of sub words if (sw.HasSubWords == true) { sb.Append(" " + "wCx:" + sw.SubWords.Count.ToString()); } // the delimeter of the word is found in the EndCursor of the word. if ((sw.IsComposite == false) || (Cursor.Position == RelativePosition.After)) { if (sw.EndCursor != null) { sb.Append(" " + sw.EndCursor.ToDelimPresentationString()); } } // word classification if ((sw.IsComposite == false) || (Cursor.Position == RelativePosition.At)) { if (sw.WordCursor != null) { sb.Append(" wc: " + sw.WordCursor.WordClassification.ToString()); } } // the text of the word if ((sw.IsComposite == false) || (Cursor.CompositeNodeEdge == WhichEdge.LeadEdge)) { string showText = null; if (sw.WordText.Length < 60) { showText = sw.WordText; } else { showText = sw.WordText.Substring(0, 60) + "..."; } sb.Append(" wt: " + showText); } return(sb.ToString()); }