]> O.S.I.I.S - jp/crowedit.git/commitdiff
simple syntactic analysis in xmlParser for enabling folding
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Tue, 5 Sep 2017 13:35:44 +0000 (15:35 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Tue, 5 Sep 2017 13:35:44 +0000 (15:35 +0200)
CrowEdit.csproj
src/CSharpParser.cs
src/Node.cs [new file with mode: 0644]
src/Parser.cs
src/SourceEditor.cs
src/TokenList.cs
src/XMLParser.cs

index 6fc1ab0e8a1777120c455931875e51975a8bdcee..01825e2cc11fa04a10c0601579ca76e59bd20c77 100644 (file)
@@ -84,6 +84,7 @@
     <Compile Include="src\TextFormatting.cs" />
     <Compile Include="ParsingException.cs" />
     <Compile Include="CodeBufferEventArgs.cs" />
+    <Compile Include="src\Node.cs" />
   </ItemGroup>
   <ItemGroup>
     <Folder Include="ui\" />
index 472d004fdfcdd74be5f39079f8b1d4b517198396..14e3de8ce6a43e72089245b5aafbe8fcb3e1f76a 100644 (file)
@@ -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 (file)
index 0000000..94eceb6
--- /dev/null
@@ -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<string,string> Attributes = new Dictionary<string, string> ();
+
+               public List<Node> Children = new List<Node>();
+
+               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);
+               }
+       }
+}
+
index a35b6498a3b84e8ef3e9dab3cfc1b47cdb19e4e9..942454ff862a0a86a0103fb06090ac4bd0191531 100644 (file)
@@ -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<TokenList> 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]);
index c7a3fdeba202bf59e1e8f52d3b18d27c24266708..00677749793c2e528c3ecd3b1785ca87a50504b6 100644 (file)
@@ -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;
 
index f629f771e9bd4d3c9c342535ecade29affe797aa..3160c09dc4d351468329bba4f04ba448a6f74aa2 100644 (file)
@@ -15,7 +15,7 @@ namespace Crow.Coding
                /// Folding state reside here because it's the highest level of abstraction line per line
                /// </summary>
                public bool folded = false;
-               public TokenList foldingTo = null;
+               public Node SyntacticNode = null;
                /// <summary>
                /// if parsing issue error, exception is not null and tokenlist should contains only one token with line content and type = unknown
                /// </summary>
@@ -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 ();
index 738361837582ac261857a62b6ce41626cd661e64..dcb826a25e65e16cf3a54877037987d387d3d045 100644 (file)
@@ -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++;
+                               }
+                       }
+               }
        }
 }