]> O.S.I.I.S - jp/crowedit.git/commitdiff
xml parsing quiet good
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 30 Aug 2017 17:12:55 +0000 (19:12 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 30 Aug 2017 17:12:55 +0000 (19:12 +0200)
CrowEdit.csproj
src/CSharpParser.cs
src/CodeTextBuffer.cs
src/Parser.cs
src/SourceEditor.cs
src/TokenList.cs [new file with mode: 0644]
src/XMLParser.cs

index 39b204fae3dbadc6db64410cc651cd2657a185b8..6a66e49980dc107e09064d8ae6d1f95de11d6531 100644 (file)
@@ -80,6 +80,7 @@
     <Compile Include="src\Parser.cs" />
     <Compile Include="src\XMLParser.cs" />
     <Compile Include="src\CSharpParser.cs" />
+    <Compile Include="src\TokenList.cs" />
   </ItemGroup>
   <ItemGroup>
     <Folder Include="ui\" />
index 25acf4c7c3fde56efd2438587a67b9530108d196..8105b8980087b61e627c18d846d548a43c6b997e 100644 (file)
@@ -31,7 +31,8 @@ namespace CrowEdit
                public CSharpParser (CodeTextBuffer _buffer) : base(_buffer)
                {
                }
-               public override void Parse ()
+
+               public override void Parse (int line)
                {
                        throw new NotImplementedException ();
                }
index f82e93f46ecb0b53f66eacd7fd7e1118f197c9ca..b218ae3a4ea70ce3e4c7b63a346a1b16ae0a2a07 100644 (file)
@@ -25,24 +25,79 @@ using System.Text.RegularExpressions;
 
 namespace Crow
 {
-       public class CodeTextBuffer : List<string>
-       {
+       public class CodeBufferEventArgs : EventArgs {
+               public int LineStart;
+               public int LineCount;
+
+               public CodeBufferEventArgs(int lineNumber) {
+                       LineStart = lineNumber;
+                       LineCount = 1;
+               }
+               public CodeBufferEventArgs(int lineStart, int lineCount) {
+                       LineStart = lineStart;
+                       LineCount = lineCount;
+               }
+       }
 
+       public class CodeTextBuffer
+       {
+               #region Events
+               public event EventHandler<CodeBufferEventArgs> LineUpadateEvent;
+               public event EventHandler<CodeBufferEventArgs> LineRemoveEvent;
+               public event EventHandler<CodeBufferEventArgs> LineAdditionEvent;
+               public event EventHandler BufferCleared;
+               #endregion
 
                #region CTOR
-               public CodeTextBuffer () : base(){}
+               public CodeTextBuffer () : base() {}
+               #endregion
+
+
+               List<string> lines = new List<string>();
+
+               public int Length { get { return lines.Count;}}
+
+               public string this[int i]
+               {
+                       get { return lines[i]; }
+                       set {
+                               if (lines [i] == value)
+                                       return;
+                               lines[i] = value;
+                               LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
+                       }
+               }
+
+               public void RemoveAt(int i){
+                       lines.RemoveAt(i);
+                       LineRemoveEvent.Raise (this, new CodeBufferEventArgs (i));
+               }
+               public void Insert(int i, string item){
+                       lines.Insert (i, item);
+                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (i));
+               }
+               public void AddRange (string[] items){
+                       int start = lines.Count;
+                       lines.AddRange (items);
+                       LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length));
+               }
+               public void Clear () {
+                       lines.Clear();
+                       BufferCleared.Raise (this, null);
+               }
+
+
+               public void Load(string rawSource) {
+                       this.Clear();
 
-               public CodeTextBuffer (string rawSource) : this (){
                        if (string.IsNullOrEmpty (rawSource))
                                return;
-                       
-                       this.AddRange (Regex.Split (rawSource, "\r\n|\r|\n|\\\\n"));
+
+                       AddRange (Regex.Split (rawSource, "\r\n|\r|\n|\\\\n"));
 
                        lineBreak = detectLineBreakKind (rawSource);
                        findLongestLine ();
                }
-               #endregion
-
                string lineBreak = Interface.LineBreak;
 
                public int longestLineIdx = 0;
@@ -50,9 +105,9 @@ namespace Crow
 
                void findLongestLine(){
                        longestLineCharCount = 0;
-                       for (int i = 0; i < this.Count; i++) {
-                               if (this[i].Length > longestLineCharCount) {
-                                       longestLineCharCount = this[i].Length;
+                       for (int i = 0; i < lines.Count; i++) {
+                               if (lines[i].Length > longestLineCharCount) {
+                                       longestLineCharCount = lines[i].Length;
                                        longestLineIdx = i;
                                }
                        }
@@ -86,7 +141,7 @@ namespace Crow
                /// </summary>
                public string FullText{
                        get {
-                               return this.Count > 0 ? this.Aggregate((i, j) => i + this.lineBreak + j) : "";
+                               return lines.Count > 0 ? lines.Aggregate((i, j) => i + this.lineBreak + j) : "";
                        }
                }
        }
index 945f843e3b0f9acbf872f1d7499cf1896383ee43..19c3df4ac1c920f2aeba6d5b43e9f1cd63e6746c 100644 (file)
@@ -2,6 +2,7 @@
 using System.IO;
 using Crow;
 using System.Collections.Generic;
+using System.Diagnostics;
 
 namespace CrowEdit
 {
@@ -42,14 +43,17 @@ namespace CrowEdit
                        }
                }
 
+               #region CTOR
                public Parser (CodeTextBuffer _buffer)
                {
                        buffer = _buffer;
-                       if (buffer.Count > 0)
+                       Tokens = new List<TokenList> ();
+                       if (buffer.Length > 0)
                                eof = false;
                }
 
-               protected bool parsed = false;
+               #endregion
+
                protected int currentLine = 0;
                protected int currentColumn = 0;
                protected Token currentTok;
@@ -57,13 +61,16 @@ namespace CrowEdit
 
                CodeTextBuffer buffer;
 
-               public List<List<Token>> Tokens;
-               protected List<Token> TokensLine;
+               public List<TokenList> Tokens;
+               protected TokenList TokensLine;
 
-               public bool Parsed { get { return parsed; }}
                public Point CurrentPosition { get { return new Point (currentLine, currentColumn); } }
 
-               public abstract void Parse();
+               public virtual void SetLineInError(int lineNumber) {
+                       currentTok = default(Token);
+                       Tokens [lineNumber] = new TokenList () {new Token () { Content = buffer [lineNumber] }};
+               }
+               public abstract void Parse(int line);
 
                protected void readToCurrTok(bool startOfTok = false){
                        if (startOfTok)
@@ -102,28 +109,13 @@ namespace CrowEdit
 
                        if (c == '\n') {
                                currentLine++;
-                               if (currentLine >= buffer.Count)
+                               if (currentLine >= buffer.Length)
                                        eof = true;
                                currentColumn = 0;
                        } else
                                currentColumn++;
                        return c;
                }
-               protected virtual string Read(uint length) {
-                       string tmp = "";
-                       for (int i = 0; i < length; i++) {
-                               char c = Peek ();
-                               if (c == '\n') {
-                                       currentLine++;
-                                       if (currentLine >= buffer.Count)
-                                               eof = true;
-                                       currentColumn = 0;
-                               } else
-                                       currentColumn++;
-                               tmp += c;
-                       }
-                       return tmp;
-               }
 
                protected virtual string ReadUntil (string endExp){
                        string tmp = "";
@@ -131,7 +123,7 @@ namespace CrowEdit
                        while (!eof) {
                                if (buffer [currentLine].Length - currentColumn - endExp.Length < 0) {
                                        currentLine++;
-                                       if (currentLine >= buffer.Count)
+                                       if (currentLine >= buffer.Length)
                                                eof = true;
                                        currentColumn = 0;
                                        continue;
index 123573af03556e4b2e34e40fa10f3a0dddec7871..a653b0e239f5ba40b19167b768250e533dc91f38 100644 (file)
@@ -64,6 +64,14 @@ namespace Crow
                        formating.Add ((int)XMLParser.TokenType.AttributeValueOpening, new TextFormating (Color.DarkPink, Color.Transparent));
                        formating.Add ((int)XMLParser.TokenType.AttributeValueClosing, new TextFormating (Color.DarkPink, Color.Transparent));
                        formating.Add ((int)XMLParser.TokenType.AttributeValue, new TextFormating (Color.DarkPink, Color.Transparent));
+
+                       buffer = new CodeTextBuffer ();
+                       buffer.LineUpadateEvent += Buffer_LineUpadateEvent;
+                       buffer.LineAdditionEvent += Buffer_LineAdditionEvent;;
+                       buffer.LineRemoveEvent += Buffer_LineRemoveEvent;
+                       buffer.BufferCleared += Buffer_BufferCleared;
+
+                       parser = new CrowEdit.XMLParser (buffer);
                }
                #endregion
 
@@ -104,8 +112,9 @@ namespace Crow
                                if (string.Equals (value, buffer?.FullText, StringComparison.Ordinal))
                                        return;
 
-                               buffer = new CodeTextBuffer (value);
-                               MaxScrollY = Math.Max (0, buffer.Count - visibleLines);
+                               buffer.Load (value);
+
+                               MaxScrollY = Math.Max (0, buffer.Length - visibleLines);
                                MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns);
 
                                OnTextChanged (this, null);
@@ -113,6 +122,51 @@ namespace Crow
                        }
                }
 
+               void Buffer_BufferCleared (object sender, EventArgs e)
+               {
+                       parser = new CrowEdit.XMLParser (buffer);
+                       RegisterForGraphicUpdate ();
+               }
+               void reparseSource () {
+                       for (int i = 0; i < parser.Tokens.Count; i++) {
+                               if (parser.Tokens[i].Dirty)
+                                       tryParseBufferLine (i);
+                       }
+               }
+               void tryParseBufferLine(int lPtr) {
+                       try {
+                               parser.Parse (lPtr);
+                       } catch (Exception ex) {
+                               Debug.WriteLine (ex.ToString ());
+                               parser.SetLineInError (lPtr);
+                       }
+                       RegisterForGraphicUpdate ();
+               }
+               void Buffer_LineAdditionEvent (object sender, CodeBufferEventArgs e)
+               {
+                       for (int i = 0; i < e.LineCount; i++) {
+                               parser.Tokens.Insert (e.LineStart + i, new TokenList());
+                               tryParseBufferLine (e.LineStart + i);
+                       }
+                       reparseSource ();
+                       RegisterForGraphicUpdate ();
+               }
+
+               void Buffer_LineRemoveEvent (object sender, CodeBufferEventArgs e)
+               {
+                       for (int i = 0; i < e.LineCount; i++)
+                               parser.Tokens.RemoveAt (e.LineStart + i);
+                       reparseSource ();
+                       RegisterForGraphicUpdate ();
+               }
+
+               void Buffer_LineUpadateEvent (object sender, CodeBufferEventArgs e)
+               {
+                       for (int i = 0; i < e.LineCount; i++)
+                               tryParseBufferLine (e.LineStart + i);
+                       reparseSource ();
+                       RegisterForGraphicUpdate ();
+               }
 
                [XmlAttributeAttribute][DefaultValue("BlueGray")]
                public virtual Color SelectionBackground {
@@ -163,8 +217,8 @@ namespace Crow
                        set {
                                if (value == _currentLine)
                                        return;
-                               if (value >= buffer.Count)
-                                       _currentLine = buffer.Count-1;
+                               if (value >= buffer.Length)
+                                       _currentLine = buffer.Length-1;
                                else if (value < 0)
                                        _currentLine = 0;
                                else
@@ -286,7 +340,7 @@ namespace Crow
                public bool MoveRight(){
                        int tmp = _currentCol + 1;
                        if (tmp > buffer [_currentLine].Length){
-                               if (CurrentLine == buffer.Count - 1)
+                               if (CurrentLine == buffer.Length - 1)
                                        return false;
                                CurrentLine++;
                                CurrentColumn = 0;
@@ -321,7 +375,7 @@ namespace Crow
                {
                        if (selectionIsEmpty) {
                                if (CurrentColumn == 0) {
-                                       if (CurrentLine == 0 && buffer.Count == 1)
+                                       if (CurrentLine == 0 && buffer.Length == 1)
                                                return;
                                        CurrentLine--;
                                        CurrentColumn = buffer [CurrentLine].Length;
@@ -374,7 +428,7 @@ namespace Crow
                protected override int measureRawSize(LayoutingType lt)
                {
                        if (lt == LayoutingType.Height)
-                               return (int)Math.Ceiling(fe.Height * buffer.Count) + Margin * 2;
+                               return (int)Math.Ceiling(fe.Height * buffer.Length) + Margin * 2;
 
                        return (int)(fe.MaxXAdvance * buffer.longestLineCharCount) + Margin * 2;
                }
@@ -414,7 +468,7 @@ namespace Crow
 
                        for (int i = 0; i < visibleLines; i++) {
                                int curL = i + ScrollY;
-                               if (curL >= buffer.Count)
+                               if (curL >= buffer.Length)
                                        break;
                                string lstr = buffer[curL];
                                if (ScrollX < lstr.Length)
@@ -480,13 +534,13 @@ namespace Crow
                        #endregion
 
                        for (int i = 0; i < visibleLines; i++) {
-                               int curL = i + ScrollY;
-                               if (curL >= parser.Tokens.Count)
+                               if (i + ScrollY >= parser.Tokens.Count)
                                        break;
-                               drawTokenLine (gr, curL, selectionInProgress);
+                               drawTokenLine (gr, i, selectionInProgress, cb);
                        }
                }
-               void drawTokenLine(Context gr, int curL, bool selectionInProgress) {
+               void drawTokenLine(Context gr, int i, bool selectionInProgress, Rectangle cb) {
+                       int curL = i + ScrollY;
                        List<Token> tokens = parser.Tokens[curL];
                        int lPtr = 0;
 
@@ -526,13 +580,14 @@ namespace Crow
                                        double rLineX = x,
                                        rLineY = cb.Y + i * fe.Height,
                                        rLineW = lstr.Length * fe.MaxXAdvance;
+                                       double startAdjust = 0.0;
 
-                                       if ((curL == selectionStart.Y) && (selectionStart.X < lPtr + lstr.Length) && (selectionStart.X > lPtr)) {
-                                               rLineX += (selectionStart.X - lPtr) * fe.MaxXAdvance;
-                                               rLineW -= (selectionStart.X - lPtr) * fe.MaxXAdvance;
-                                       }
+                                       if ((curL == selectionStart.Y) && (selectionStart.X < lPtr + lstr.Length) && (selectionStart.X > lPtr))
+                                               startAdjust = (selectionStart.X - lPtr) * fe.MaxXAdvance;
+                                       rLineX += startAdjust;
                                        if ((curL == selectionEnd.Y) && (selectionEnd.X < lPtr + lstr.Length))
                                                rLineW = (selectionEnd.X - lPtr) * fe.MaxXAdvance;
+                                       rLineW -= startAdjust;
 
                                        gr.Save ();
                                        gr.Operator = Operator.Source;
@@ -555,7 +610,7 @@ namespace Crow
                {
                        base.onDraw (gr);
 
-                       if (parser?.Parsed == true)
+                       if (parser != null)
                                drawParsed (gr);
                        else
                                draw(gr);
@@ -807,16 +862,8 @@ namespace Crow
                                this.Insert ("\t");
                                break;
                        case Key.F8:
-                               try {
-                                       parser = new CrowEdit.XMLParser (buffer);
-                                       parser.Parse ();
-                               } catch (Exception ee) {
-                                       Debug.WriteLine (ee.ToString ());
-                                       parser = null;
-                               }
-                               break;
-                       case Key.F9:
-                               parser = null;
+                               if (parser != null)
+                                       reparseSource ();
                                break;
                        default:
                                break;
@@ -851,7 +898,7 @@ namespace Crow
 
                void updateVisibleLines(){
                        visibleLines = (int)Math.Floor ((double)ClientRectangle.Height / fe.Height);
-                       MaxScrollY = Math.Max (0, buffer.Count - visibleLines);
+                       MaxScrollY = Math.Max (0, buffer.Length - visibleLines);
 
                        System.Diagnostics.Debug.WriteLine ("update visible lines: " + visibleLines);
                        System.Diagnostics.Debug.WriteLine ("update MaxScrollY: " + MaxScrollY);
diff --git a/src/TokenList.cs b/src/TokenList.cs
new file mode 100644 (file)
index 0000000..902c184
--- /dev/null
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+
+namespace Crow
+{
+       public class TokenList : List<Token>
+       {
+               public bool Dirty = true;
+               public int EndingState;
+
+               public TokenList () : base ()
+               {
+                       EndingState = 0;
+               }
+
+               public new void Clear() {
+                       EndingState = 0;
+                       Dirty = true;
+                       base.Clear ();
+               }
+       }
+}
+
index 99ff5cb6749269a79653fb05c57974fca3c57edd..57c2f08484076353d09f6840ab9ea22d86361ee4 100644 (file)
@@ -2,6 +2,7 @@
 using Crow;
 using System.Collections.Generic;
 using System.Text.RegularExpressions;
+using System.Diagnostics;
 
 namespace CrowEdit
 {
@@ -96,18 +97,35 @@ namespace CrowEdit
 //             }
                #endregion
 
-               public override void Parse ()
+               public override void SetLineInError (int lineNumber)
                {
-                       parsed = false;
-                       Tokens = new List<List<Token>> ();
-                       TokensLine = new List<Token> ();
-                       currentLine = currentColumn = 0;
-                       currentTok = default(Token);
-                       curState = States.init;
+                       base.SetLineInError (lineNumber);
+                       Tokens[lineNumber].EndingState = (int)States.init;
+               }
+
+               public override void Parse (int line)
+               {
+                       Debug.WriteLine (string.Format("parsing line:{0}", line));
+
+                       currentLine = line;
+                       currentColumn = 0;
+                       eof = false;
+                       bool eol = false;
+
+                       if (line > 0)
+                               curState = (States)Tokens [line - 1].EndingState;
+                       else
+                               curState = States.init;
+
+                       TokensLine = Tokens [line];
 
-                       string tmp = "";
+                       States previousEndingState = (States)TokensLine.EndingState;
 
-                       while (!eof) {
+                       TokensLine.Clear ();
+
+
+
+                       while (! (eof||eol)) {
                                SkipWhiteSpaces ();
 
                                if (eof)
@@ -118,8 +136,7 @@ namespace CrowEdit
                                        if (currentTok != TokenType.Unknown)
                                                throw new ParsingException (this, "Unexpected end of line");
                                        Read ();
-                                       Tokens.Add (TokensLine);
-                                       TokensLine = new List<Token> ();
+                                       eol = true;
                                        break;
                                case '<':
                                        readToCurrTok (true);
@@ -226,10 +243,14 @@ namespace CrowEdit
                                        break;
                                }
                        }
-                       if (TokensLine.Count > 0)
-                               Tokens.Add (TokensLine);
 
-                       parsed = true;
+                       TokensLine.EndingState = (int)curState;
+                       TokensLine.Dirty = false;
+
+                       Debug.WriteLine ("\tState:{0}->{1}", previousEndingState, curState);
+
+                       if (previousEndingState != curState && line < Tokens.Count - 1)
+                               Tokens [line + 1].Dirty = true;
                }
        }
 }