From: Jean-Philippe Bruyère Date: Tue, 5 Sep 2017 13:35:44 +0000 (+0200) Subject: simple syntactic analysis in xmlParser for enabling folding X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=eface6fa927c0292acc6b6f226ee3e83d521ff05;p=jp%2Fcrowedit.git simple syntactic analysis in xmlParser for enabling folding --- diff --git a/CrowEdit.csproj b/CrowEdit.csproj index 6fc1ab0..01825e2 100644 --- a/CrowEdit.csproj +++ b/CrowEdit.csproj @@ -84,6 +84,7 @@ + diff --git a/src/CSharpParser.cs b/src/CSharpParser.cs index 472d004..14e3de8 100644 --- a/src/CSharpParser.cs +++ b/src/CSharpParser.cs @@ -36,6 +36,10 @@ namespace Crow.Coding { throw new NotImplementedException (); } + public override void SyntaxAnalysis () + { + throw new NotImplementedException (); + } } } diff --git a/src/Node.cs b/src/Node.cs new file mode 100644 index 0000000..94eceb6 --- /dev/null +++ b/src/Node.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; + +namespace Crow.Coding +{ + public class Node + { + public Node Parent; + public string Name; + public string Type; + public int StartLine; + public int EndLine; + public Dictionary Attributes = new Dictionary (); + + public List Children = new List(); + + public Node () + { + } + + public void AddChild (Node child) { + child.Parent = this; + Children.Add (child); + } + + public override string ToString () + { + return string.Format ("Name:{0}, Type:{1}\n\tparent:{2}", Name, Type, Parent); + } + } +} + diff --git a/src/Parser.cs b/src/Parser.cs index a35b649..942454f 100644 --- a/src/Parser.cs +++ b/src/Parser.cs @@ -68,14 +68,12 @@ namespace Crow.Coding } reparseSource (); } - void Buffer_LineRemoveEvent (object sender, CodeBufferEventArgs e) { for (int i = 0; i < e.LineCount; i++) Tokens.RemoveAt (e.LineStart + i); reparseSource (); } - void Buffer_LineUpadateEvent (object sender, CodeBufferEventArgs e) { for (int i = 0; i < e.LineCount; i++) @@ -128,7 +126,12 @@ namespace Crow.Coding if (Tokens[i].Dirty) tryParseBufferLine (i); } - updateFolding (); + try { + SyntaxAnalysis (); + } catch (ParsingException ex) { + Debug.WriteLine ("Syntax Error: " + ex.ToString ()); + SetLineInError (ex); + } } void tryParseBufferLine(int lPtr) { try { @@ -149,6 +152,8 @@ namespace Crow.Coding public List Tokens; protected TokenList TokensLine; + public Node RootNode; + public Point CurrentPosition { get { return new Point (currentLine, currentColumn); } set { @@ -158,6 +163,8 @@ namespace Crow.Coding } public abstract void Parse(int line); + public abstract void SyntaxAnalysis (); + public virtual void SetLineInError(ParsingException ex) { currentTok = default(Token); Tokens [ex.Line] = new TokenList (ex, buffer [ex.Line]); diff --git a/src/SourceEditor.cs b/src/SourceEditor.cs index c7a3fde..0067774 100644 --- a/src/SourceEditor.cs +++ b/src/SourceEditor.cs @@ -70,11 +70,11 @@ namespace Crow.Coding } #endregion - const int leftMarginGap = 0;//gap between items in margin and text + const int leftMarginGap = 2;//gap between items in margin and text const int foldSize = 9;//folding rectangles size #region private and protected fields - bool foldingEnabled = false; + bool foldingEnabled = true; string filePath = "unamed.txt"; int leftMargin = 0; //margin used to display line numbers, folding errors,etc... int visibleLines = 1; @@ -614,17 +614,19 @@ namespace Crow.Coding } //draw folding if (foldingEnabled){ - if (tokens.foldingTo != null) { - gr.SetSourceColor (Color.Black); - Rectangle rFld = new Rectangle (cb.X + leftMargin - leftMarginGap - foldSize, (int)(y + fe.Height / 2.0 - foldSize / 2.0), foldSize, foldSize); - gr.Rectangle (rFld, 1.0); - if (tokens.folded) { - gr.MoveTo (rFld.Center.X + 0.5, rFld.Y + 2); - gr.LineTo (rFld.Center.X + 0.5, rFld.Bottom - 2); + if (tokens.SyntacticNode != null) { + if (tokens.SyntacticNode.StartLine < tokens.SyntacticNode.EndLine) { + gr.SetSourceColor (Color.Black); + Rectangle rFld = new Rectangle (cb.X + leftMargin - leftMarginGap - foldSize, (int)(y + fe.Height / 2.0 - foldSize / 2.0), foldSize, foldSize); + gr.Rectangle (rFld, 1.0); + if (tokens.folded) { + gr.MoveTo (rFld.Center.X + 0.5, rFld.Y + 2); + gr.LineTo (rFld.Center.X + 0.5, rFld.Bottom - 2); + } + gr.MoveTo (rFld.Left + 2, rFld.Center.Y + 0.5); + gr.LineTo (rFld.Right - 2, rFld.Center.Y + 0.5); + gr.Stroke (); } - gr.MoveTo (rFld.Left + 2, rFld.Center.Y + 0.5); - gr.LineTo (rFld.Right - 2, rFld.Center.Y + 0.5); - gr.Stroke (); } } @@ -765,7 +767,10 @@ namespace Crow.Coding public override void onMouseEnter (object sender, MouseMoveEventArgs e) { base.onMouseEnter (sender, e); - currentInterface.MouseCursor = XCursor.Text; + if (e.X - ScreenCoordinates(Slot).X < leftMargin + ClientRectangle.X) + currentInterface.MouseCursor = XCursor.Default; + else + currentInterface.MouseCursor = XCursor.Text; } public override void onMouseLeave (object sender, MouseMoveEventArgs e) { @@ -776,14 +781,16 @@ namespace Crow.Coding { base.onMouseMove (sender, e); + if (e.X - ScreenCoordinates(Slot).X < leftMargin + ClientRectangle.X) + currentInterface.MouseCursor = XCursor.Default; + else + currentInterface.MouseCursor = XCursor.Text; + if (!e.Mouse.IsButtonDown (MouseButton.Left)) return; if (!HasFocus || SelBegin < 0) return; - if (e.X < leftMargin + ClientRectangle.X) { - } - updatemouseLocalPos (e.Position); SelRelease = CurrentPosition; diff --git a/src/TokenList.cs b/src/TokenList.cs index f629f77..3160c09 100644 --- a/src/TokenList.cs +++ b/src/TokenList.cs @@ -15,7 +15,7 @@ namespace Crow.Coding /// Folding state reside here because it's the highest level of abstraction line per line /// public bool folded = false; - public TokenList foldingTo = null; + public Node SyntacticNode = null; /// /// if parsing issue error, exception is not null and tokenlist should contains only one token with line content and type = unknown /// @@ -47,7 +47,7 @@ namespace Crow.Coding public new void Clear() { EndingState = 0; folded = false; - foldingTo = null; + SyntacticNode = null; exception = null; Dirty = true; base.Clear (); diff --git a/src/XMLParser.cs b/src/XMLParser.cs index 7383618..dcb826a 100644 --- a/src/XMLParser.cs +++ b/src/XMLParser.cs @@ -3,6 +3,7 @@ using Crow; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Diagnostics; +using System.Linq; namespace Crow.Coding { @@ -196,7 +197,7 @@ namespace Crow.Coding readToCurrTok (true); if (Peek () != '>') throw new ParsingException (this, "Expecting '>'"); - readAndResetCurrentTok (TokenType.ElementClosing); + readAndResetCurrentTok (TokenType.ElementEnd); curState = States.XML; break; @@ -252,6 +253,47 @@ namespace Crow.Coding if (previousEndingState != curState && line < Tokens.Count - 1) Tokens [line + 1].Dirty = true; } + + public override void SyntaxAnalysis () + { + RootNode = new Node () { Name = "RootNode", Type="Root" }; + + Node currentNode = RootNode; + + for (int i = 0; i < Tokens.Count; i++) { + TokenList curTL = Tokens [i]; + curTL.SyntacticNode = null; + + int tokPtr = 0; + while (tokPtr < curTL.Count) { + switch ((XMLParser.TokenType)curTL [tokPtr].Type) { + case TokenType.ElementStart: + tokPtr++; + Node newElt = new Node () { Name = curTL [tokPtr].Content, StartLine = i }; + currentNode.AddChild (newElt); + currentNode = newElt; + if (curTL.SyntacticNode == null) + curTL.SyntacticNode = newElt; + break; + case TokenType.ElementEnd: + tokPtr++; + if (tokPtr < curTL.Count) { + if ((XMLParser.TokenType)curTL [tokPtr].Type == TokenType.ElementName && curTL [tokPtr].Content != currentNode.Name) + throw new ParsingException (this, "Closing tag mismatch"); + } + currentNode.EndLine = i; + currentNode = currentNode.Parent; + break; + case TokenType.ElementClosing: + //currentNode = currentNode.Parent; + break; + default: + break; + } + tokPtr++; + } + } + } } }