]> O.S.I.I.S - jp/crowedit.git/commitdiff
save commit
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sat, 8 Mar 2025 21:10:28 +0000 (22:10 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sun, 9 Mar 2025 12:22:49 +0000 (13:22 +0100)
21 files changed:
CrowEditBase/src/Compiler/SourceDocument.cs
CrowEditBase/src/Compiler/SyntaxAnalyser.cs
CrowEditBase/src/Compiler/SyntaxNode.cs
CrowEditBase/src/Compiler/SyntaxRootNode.cs
CrowEditBase/src/Compiler/Token.cs
CrowEditBase/src/SourceEditor.cs
CrowEditBase/ui/CrowEdit.style
CrowEditBase/ui/SimpleStatus.template
plugins/CECrowPlugin/src/Parsing/IML/ImlDocument.cs
plugins/CECrowPlugin/src/Parsing/Styling/StyleDocument.cs
plugins/CECrowPlugin/src/Parsing/Styling/StyleSyntaxAnalyser.cs
plugins/CECrowPlugin/src/Parsing/Styling/StyleSyntaxNodes.cs [new file with mode: 0644]
plugins/CECrowPlugin/src/Parsing/Styling/StyleTokenType.cs
plugins/CECrowPlugin/src/Parsing/Styling/SyntaxNodes.cs [deleted file]
plugins/CEEbnfPlugin/src/Parsing/EbnfDocument.cs
plugins/CEEbnfPlugin/src/Parsing/EbnfSyntaxAnalyser.cs
plugins/CERoslynPlugin/src/CSDocument.cs
plugins/CERoslynPlugin/src/CSSyntaxAnalyser.cs
plugins/CEXmlPlugin/src/Parsing/XmlDocument.cs
plugins/CEXmlPlugin/src/Parsing/XmlSyntaxAnalyser.cs
ui/windows/winSyntaxExplorer.crow

index d702db177107a8439cc9c417d300e3302091d9d8..b4f220b6bfd9b3c8dbd89dcdc056b9d3a4f672ff 100644 (file)
@@ -38,7 +38,7 @@ namespace CrowEditBase
                public Token FindTokenIncludingPosition (int pos) {
                        if (!IsParsed || pos == 0 || Tokens.Length == 0)
                                return default;
-                       int idx = Tokens.BinarySearch(new  Token () {Start = pos});
+                       int idx = Tokens.BinarySearch(new  Token (pos));
                        return idx == 0 ? Tokens[0] : idx < 0 ? Tokens[~idx - 1] : Tokens[idx];
                }
                public Token GetTokenByIndex(int tokIdx) => IsParsed && tokIdx >= 0 ?
@@ -46,7 +46,7 @@ namespace CrowEditBase
                public int FindTokenIndexIncludingPosition (int pos) {
                        if (!IsParsed || pos == 0 || Tokens.Length == 0)
                                return default;
-                       int idx = Tokens.BinarySearch(new  Token () {Start = pos});
+                       int idx = Tokens.BinarySearch(new  Token (pos));
                        return idx == 0 ? 0 : idx < 0 ? ~idx - 1 : idx;
                }
                /// <summary>
@@ -124,7 +124,9 @@ namespace CrowEditBase
                }
 
 
-               public virtual Color GetColorForToken (TokenType tokType) {
+               public virtual Color GetColorForToken (Token token)
+               {
+                       TokenType tokType = token.Type;
                        if (tokType.HasFlag (TokenType.Punctuation))
                                return Colors.DarkGrey;
                        if (tokType.HasFlag (TokenType.WhiteSpace))
index 449fc0a0b9b0d081edd9f5a6c4879f0e571c3083..9273fe19e5970e7e36a9181d31354220e306ecd7 100644 (file)
@@ -22,15 +22,9 @@ namespace CrowEditBase
                protected Token curTok => tokIdx < 0 ? default : tokens[tokIdx];
                
                protected ReadOnlySpan<Token> tokens => Root.Tokens;
-               protected bool EOF => tokIdx == tokens.Length;
-               protected bool tryRead (out Token tok) {
-                       if (EOF) {
-                               tok = default;
-                               return false;
-                       }
-                       tok = tokens [tokIdx++];
-                       return true;
-               }
+               protected bool EOF => tokIdx >= tokens.Length;
+               protected Token Read() => tokens [tokIdx++];
+               protected Token Peek() => tokens [tokIdx];
                protected bool tryPeek (out Token tok) {
                        if (EOF) {
                                tok = default;
@@ -41,15 +35,6 @@ namespace CrowEditBase
                }
                protected bool tryPeek (Enum expectedType)
                        => EOF ? false : Enum.Equals(tokens [tokIdx].Type, expectedType);
-               
-               protected bool tryRead (out Token tok, Enum expectedType) {
-                       if (EOF) {
-                               tok = default;
-                               return false;
-                       }
-                       tok = tokens [tokIdx++];
-                       return Enum.Equals(tok.Type, expectedType);
-               }               
                protected bool tryPeek (out Token tok, Enum expectedType) {
                        if (EOF) {
                                tok = default;
@@ -66,12 +51,30 @@ namespace CrowEditBase
                        tok = tokens [tokIdx];
                        return tok.Type.HasFlag(expectedFlag);
                }               
+               
+               protected bool tryRead (out Token tok) {
+                       if (EOF) {
+                               tok = default;
+                               return false;
+                       }
+                       tok = tokens [tokIdx++];
+                       return true;
+               }               
+               protected bool tryRead (out Token tok, Enum expectedType) {
+                       if (EOF) {
+                               tok = default;
+                               return false;
+                       }
+                       tok = tokens [tokIdx++];
+                       return Enum.Equals(tok.Type, expectedType);
+               }
+
 
                #endregion
 
                #region parsing context
                protected int currentLine = 0, tokIdx = 0;
-               protected SyntaxNode currentNode;
+               //protected MultiNodeSyntax currentNode;
                #endregion
 
                /// <summary>
@@ -106,6 +109,17 @@ namespace CrowEditBase
                        }
                        return !EOF;
                }
+               protected bool skipWhiteSpaces(bool skipLineBreaks = true) {
+                       while (tryPeekFlag(out Token tok, TokenType.WhiteSpace)) {
+                               if (tok.Type == TokenType.LineBreak) {
+                                       if (!skipLineBreaks)
+                                               return true;
+                                       currentLine++;
+                               }
+                               tokIdx++;
+                       }
+                       return !EOF;
+               }               
                protected void addException(string message) {
                        /*CharLocation loc = lines.GetLocation(curTok.Start);
                        currentNode.AddException(new SyntaxException(message, loc, curTok));*/
index d720aaeb37b48ad5f66ec2f3cc61948900ff3606..69c73cbc2e74e1cf4bd08582e560ea757717eb62 100644 (file)
@@ -6,20 +6,35 @@ using System.Collections.Generic;
 using System.Linq;
 using Crow.Text;
 using Crow;
+using System.Diagnostics;
 
 namespace CrowEditBase
 {
+       public class UnexpectedTokenSyntax : SingleTokenSyntax {
+               public UnexpectedTokenSyntax(Token tok) : base (tok) { }
+       }
        public class SingleTokenSyntax : SyntaxNode {
-               Token token;
+               protected Token token;
         public override TokenType Type => token.Type;
         public override int SpanStart => token.Start;
                public override int SpanEnd => token.End;
-               public SingleTokenSyntax(Token tok) {
+        public override bool IsComplete => token.Type != TokenType.Unknown && token.Length > 0;
+        public SingleTokenSyntax(Token tok) {
                        token = tok;
+                       token.syntaxNode = this;
                }
        }
-       public class MultiNodeSyntax : SyntaxNode {
-               internal List<SyntaxNode> children = new List<SyntaxNode> ();
+       public class CommentTriviaSyntax : MultiNodeSyntax {
+               bool block;
+               public CommentTriviaSyntax(bool block) {
+                       this.block = block;
+               }
+        public override bool IsComplete => true;
+                       
+    }
+       public abstract class MultiNodeSyntax : SyntaxNode {
+               public MultiNodeSyntax() { }
+        internal List<SyntaxNode> children = new List<SyntaxNode> ();
                public IEnumerable<SyntaxNode> Children => children;
                public SyntaxNode AddChild (SyntaxNode child) {
                        children.Add (child);
@@ -32,8 +47,35 @@ namespace CrowEditBase
                }
                public IEnumerable<T> GetChilds<T> () => children.OfType<T>();
 
-               
-               public override bool HasChilds => children.Count > 0;
+               public bool ChildIs<T> (int idx) => children.Count() <= idx ? false : children[idx] is T;
+               public bool ChildSequenceIs(params object[] sequ) {
+                       if (children.Count != sequ.Length)
+                               return false;
+                       for (int i = 0; i < sequ.Length; i++) {
+                               if (typeof(Type).IsAssignableFrom(sequ[i].GetType())) {
+                                       if ((sequ[i] as Type) != children[i].GetType())
+                                               return false;
+                               } else if (sequ[i].GetType().IsEnum) {
+                                       if (!(children[i] is SingleTokenSyntax tok) || (TokenType)sequ[i] != tok.Type)
+                                               return false;
+                               } else
+                                       return false;
+                               if (!children[i].IsComplete)
+                                       return false;
+                               
+                       }
+                       return true;
+               }
+        public override bool IsComplete {
+                       get {
+                               for (int i = 0; i < children.Count(); i++) {
+                                       if (!children[i].IsComplete)
+                                               return false;
+                               }
+                               return true;
+                       }
+               }
+        public override bool HasChilds => children.Count > 0;
         public override int SpanStart => HasChilds ? children[0].SpanStart : 0;
                public override int SpanEnd => HasChilds ? children[children.Count - 1].SpanEnd : 0;
 
@@ -85,24 +127,41 @@ namespace CrowEditBase
                                        return node.FindNodeIncludingPosition (pos);
                        }
                        return this;
+               }
+               bool _isExpanded;
+               public override bool isExpanded {
+                       get => _isExpanded;
+                       set {
+                               bool expand = HasChilds ? value : false;
+                               if  (_isExpanded == expand)
+                                       return;
+                               _isExpanded = value;
+                               if (isExpanded && Parent is SyntaxNode sn) {
+                                       try {
+                                               sn.isExpanded = true;
+                                       } catch (Exception ex) {
+                                               Debug.WriteLine($"SyntaxNode expand to the top failed:{ex.Message}");
+                                               Debug.WriteLine(ex.StackTrace);
+                                       }
+                                       
+                               }
+                               NotifyValueChanged (_isExpanded);
+                       }
                }               
     }
        public abstract class SyntaxNode : CrowEditComponent {
 
 
                #region  Folding and ?expand?
-               bool _isExpanded;
-               public bool isExpanded {
-                       get => _isExpanded;
+               public virtual bool isExpanded {
+                       get => false;
                        set {
-                               if  (_isExpanded == value)
-                                       return;
-                               _isExpanded = value;
-                               NotifyValueChanged (_isExpanded);
+                               if (value && Parent is SyntaxNode sn) {
+                                       sn.isExpanded = true;                                   
+                               }
                        }
                }
                #endregion
-
                public MultiNodeSyntax Parent { get; internal set; }
                public virtual SyntaxRootNode Root => Parent.Root;
                public virtual TokenType Type => TokenType.Unknown;
index 44f7492f578a364b474206c9bcc3f2e8f23d4ec7..2c177e2da18315170f61211f4eadd8a9b0917ca4 100644 (file)
@@ -30,7 +30,7 @@ namespace CrowEditBase
                public int FindTokenIndexIncludingPosition (int pos) {
                        if (pos == 0 || Tokens.Length == 0)
                                return default;
-                       int idx = Tokens.BinarySearch(new  Token () {Start = pos});
+                       int idx = Tokens.BinarySearch(new  Token (pos));
                        return idx == 0 ? 0 : idx < 0 ? ~idx - 1 : idx;
                }
                public ReadOnlySpan<char> GetText(TextSpan span) =>
index 7f117215946353b748bc61afae4a06b1f692e637..40a6b0979e55b493ceaa4ac42030b0d10f725841 100644 (file)
@@ -8,8 +8,9 @@ using System.Diagnostics.CodeAnalysis;
 
 namespace CrowEditBase
 {
-       public struct Token : IComparable<Token>, IEquatable<Token> {
+       public class Token : IComparable<Token>, IEquatable<Token> {
                public TokenType Type;
+               public SyntaxNode syntaxNode;
                public int Start;
                public int Length;
                public int End => Start + Length;
@@ -33,6 +34,9 @@ namespace CrowEditBase
                        Start = start;
                        Length = length;
                }
+               public Token (int start) {
+                       Start = start;
+               }
 
                public int CompareTo([AllowNull] Token other)
                        => Start - other.Start;
index 9a1ba9178a53565059ba90814006b33e6bf7af80..4724f9e92020a0d4d5026a8ba1930903d92f11e6 100644 (file)
@@ -44,7 +44,15 @@ namespace CrowEditBase
                        set {
                                if (currentNode == value)
                                        return;
+                               if (currentNode != null)
+                                       currentNode.IsSelected = false;
                                currentNode = value;
+                               if (currentNode != null) {
+                                       currentNode.IsSelected = true;
+                                       if (currentNode.Parent is SyntaxNode sn)
+                                               sn.isExpanded = true;
+                               }
+                                       
                                NotifyValueChanged ("CurrentNode", currentNode);
                        }
                }
@@ -55,7 +63,7 @@ namespace CrowEditBase
 #if DEBUG
                public string CurrentTokenString => sourceDocument != null && sourceDocument.IsParsed ? 
                        CurrentToken.AsString(Document.source) : null;
-               public string CurrentTokenType => sourceDocument != null && sourceDocument.IsParsed ? 
+               public string CurrentTokenType => sourceDocument != null && CurrentToken != null && sourceDocument.IsParsed ? 
                        sourceDocument.GetTokenTypeString(CurrentToken.Type) : default;
 #endif
 
@@ -691,7 +699,7 @@ namespace CrowEditBase
                                                        gr.ShowText (buff);*/
                                                } else
                                                        buff = sourceBytes.Slice (tok.Start, tok.Length);
-                                               gr.SetSource (doc.GetColorForToken (tok.Type));
+                                               gr.SetSource (doc.GetColorForToken (tok));
 
                                                int size = buff.Length * 4 + 1;
                                                if (bytes.Length < size)
@@ -707,11 +715,11 @@ namespace CrowEditBase
                                                                gr.ShowText (bytes.Slice (0, encodedBytes));
                                                        }
 
-                                                       if (CurrentToken.Equals(tok)) {
+                                                       if (CurrentToken != null && CurrentToken.Equals(tok)) {
                                                                Rectangle r = new RectangleD(pixX, pixY, extents.Width, lineHeight);
                                                                r.Inflate(1);
                                                                gr.Rectangle(r);
-                                                               gr.SetSource(doc.GetColorForToken (tok.Type).AdjustAlpha(0.5));
+                                                               gr.SetSource(doc.GetColorForToken (tok).AdjustAlpha(0.5));
                                                                gr.Stroke();
                                                        }
 
@@ -850,6 +858,7 @@ namespace CrowEditBase
                                int pos = srcdoc.GetAbsolutePosition(currentLoc.Value);
                                currentTokenIndex = srcdoc.FindTokenIndexIncludingPosition(pos);
                                Token tok = srcdoc.GetTokenByIndex(currentTokenIndex);
+
                                CurrentNode = srcdoc.Root?.FindNodeIncludingSpan(tok.Span);
                                
                                NotifyValueChanged("CurrentToken",tok);
@@ -857,7 +866,7 @@ namespace CrowEditBase
                                NotifyValueChanged("CurrentTokenString",CurrentTokenString);
                                NotifyValueChanged("CurrentTokenType",CurrentTokenType);
 #endif
-                               
+                       
                                
                        } else {
                                currentTokenIndex = -1;
index ca50a828b76f2a81deb62b802c9cc3ca45ee49ed..099d56abb8da4ff0d8b1b6c9adec34209c387066 100644 (file)
@@ -176,6 +176,16 @@ StateBox {
        Unchecked = "{Background=DarkRed}";
        Focusable = "false";
 }
+StateBoxSmall {
+       Template= "#ui.SimpleStatus.template";
+       Checked = "{Background=Green}";
+       Unchecked = "{Background=DarkRed}";
+       Focusable = "false";
+       Background = "DarkRed";
+       Foreground = "${ControlForeground}";
+       Width = "Fit";
+       Height = "Fit";
+}
 
 LogViewerWidget {
        Background = "0.01,0.01,0.01,1";
index 9b124d3b5797589ea1942ddd2b819d56265d555a..b6392a9c47fcf42beae804716cbbfe1a35966291 100644 (file)
@@ -1,2 +1,2 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<Label Background="{./Background}"/>
\ No newline at end of file
+<Label Text="{./Caption}" Background="{./Background}"/>
\ No newline at end of file
index b0d3fd451917366a6479d039c9b0cd19dd2d5964..1c2c9d8ce1bf53fbef043cbf1f83fda0d761e033 100644 (file)
@@ -192,8 +192,9 @@ namespace CECrowPlugin
                        return null;
                }*/
 
-               public override Color GetColorForToken(TokenType tokType)
+               public override Color GetColorForToken(Token token)
                {
+                       TokenType tokType = token.Type;
                        switch ((ImlTokenType)tokType) {
                                case ImlTokenType.BindingOpen:
                                case ImlTokenType.BindingClose:
@@ -208,7 +209,7 @@ namespace CECrowPlugin
                                case ImlTokenType.ConstantRefClose:
                                        return Colors.Brown;
                        }
-                       return base.GetColorForToken (tokType);
+                       return base.GetColorForToken (token);
                }
        }
 }
\ No newline at end of file
index f71c84360ec314ee87afa00b716da8eb2a1b55be..31a3b8a4abc48f36b3b7b38f74e009200df5b506 100644 (file)
@@ -32,26 +32,37 @@ namespace CECrowPlugin.Style
                        return null;
                }
                public override string GetTokenTypeString (TokenType tokenType) => ((StyleTokenType)tokenType).ToString();
-               public override Color GetColorForToken(TokenType tokType)
+               public override Color GetColorForToken(Token token)
                {
+                       TokenType tokType = token.Type;
                        StyleTokenType xmlTokType = (StyleTokenType)tokType;
                        if (xmlTokType.HasFlag (StyleTokenType.Punctuation))
                                return Colors.DarkGrey;
+                       if (tokType.HasFlag (TokenType.WhiteSpace))
+                               return Colors.Silver;                                   
                        if (xmlTokType.HasFlag (StyleTokenType.Trivia))
                                return Colors.DimGrey;
-                       if (xmlTokType == StyleTokenType.MemberName)
-                               return Colors.Blue;
+                       
+                               
                        if (xmlTokType == StyleTokenType.ConstantName)
                                return Colors.DarkCyan;
-                       else if (xmlTokType.HasFlag (StyleTokenType.Name))
-                               return Colors.Green;
+                       if (xmlTokType.HasFlag (StyleTokenType.Name)) {
+                               if (token.syntaxNode is ConstantNameSyntax)
+                                       return Colors.DarkCyan;
+                               if (token.syntaxNode is StyleIdentifierSyntax)
+                                       return Colors.Blue;
+                               if (token.syntaxNode is MemberIdentifierSyntax)
+                                       return Colors.Green;
+                               return Colors.Red;
+                       }
+                               
                        if (xmlTokType == StyleTokenType.MemberValuePart)
-                               return Colors.OrangeRed;
+                               return Colors.DarkGoldenRod;
                        if (xmlTokType == StyleTokenType.EqualSign)
                                return Colors.Black;
                        if (xmlTokType == StyleTokenType.Unknown)
                                return Colors.Red;
-                       return Colors.YellowGreen;
+                       return Colors.DarkRed;
                }
        }
 }
\ No newline at end of file
index 948c71bcb3667b084759979dbaa0bf56d8f71a5b..97519566555e6930f1d7e425d76e879005d323dd 100644 (file)
@@ -4,7 +4,9 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Reflection.Metadata.Ecma335;
 using System.Threading.Tasks;
+using CrowEdit.Xml;
 using CrowEditBase;
 
 namespace CECrowPlugin.Style
@@ -16,55 +18,160 @@ namespace CECrowPlugin.Style
                public static void SetTokenType (this Token tok, StyleTokenType type) {
                        tok.Type = (TokenType)type;
                }
+               public static bool Is(this Token tok, StyleTokenType type) => (StyleTokenType)tok.Type == type;                 
        }
        public class StyleSyntaxAnalyser : SyntaxAnalyser {
                public StyleSyntaxAnalyser (StyleDocument document) : base (document) {}
 
+               bool skipTriviaAndComments(MultiNodeSyntax currentNode) {
+                       while (tryPeekFlag(out Token token, TokenType.Trivia)) {
+                               switch(token.GetTokenType()) {
+                                       case (StyleTokenType)TokenType.LineBreak:
+                                               currentLine++;
+                                               Read();
+                                               break;
+                                       case StyleTokenType.LineCommentStart:
+                                               MultiNodeSyntax cmt = new CommentTriviaSyntax(false);
+                                               cmt.AddChild(new SingleTokenSyntax(Read()));
+                                               if (tryPeek(TokenType.LineComment))
+                                                       cmt.AddChild(new SingleTokenSyntax(Read()));
+                                               currentNode.AddChild(cmt);
+                                               break;
+                                       case StyleTokenType.BlockCommentStart:
+                                               MultiNodeSyntax bc = new CommentTriviaSyntax(true);
+                                               bc.AddChild(new SingleTokenSyntax(Read()));
+                                               while(tryPeek(out Token tok)) {
+                                                       if (tok.Type == TokenType.BlockCommentEnd)      {
+                                                               bc.AddChild(new SingleTokenSyntax(Read()));
+                                                               break;
+                                                       }
+                                                       if (tok.Type == TokenType.LineBreak) {
+                                                               Read();
+                                                               currentLine++;
+                                                       } else {
+                                                               bc.AddChild(new SingleTokenSyntax(Read()));
+                                                       }
+                                               }
+                                               currentNode.AddChild(bc);
+                                               break;
+                                       default:
+                                               Read();
+                                               break;
+                               }
+                       }
+
+                       return !EOF;
+               }
+
+               bool accept(MultiNodeSyntax node, Enum tokenType) {
+                       if (EOF)
+                               return false;
+                       if (Peek().Type == (TokenType)tokenType) {
+                               node.AddChild(new SingleTokenSyntax(Read()));
+                               return true;
+                       }
+                       return false;
+               }
+
+
+               ConstantDefinitionSyntax processNode(ConstantDefinitionSyntax cstDef) {
+                       cstDef.AddChild(new SingleTokenSyntax(Read()));//read equal
+                       if (skipTriviaAndComments(cstDef))
+                               if (accept(cstDef, StyleTokenType.MemberValueOpen))
+                                       if (accept(cstDef, StyleTokenType.MemberValuePart))
+                                               if (accept(cstDef, StyleTokenType.MemberValueClose))
+                                                       accept(cstDef, StyleTokenType.EndOfExpression);
+                       return cstDef;
+               }
+               StyleDefinitionSyntax processNode(StyleDefinitionSyntax styleDef) {
+                       while (Peek().Is(StyleTokenType.Comma)) {
+                               styleDef.AddChild(new SingleTokenSyntax(Read()));
+                               if (!skipTriviaAndComments(styleDef))
+                                       break;
+                               if (!Peek().Is(StyleTokenType.Name))
+                                       break;
+                               styleDef.AddChild(new StyleIdentifierSyntax(Read()));
+                               if (!skipTriviaAndComments(styleDef))
+                                       break;
+                       }
+                       if (Peek().Is(StyleTokenType.OpeningBrace))
+                               styleDef.AddChild(processNode(new MemberListSyntax()));
+
+                       return styleDef;
+               }
+               MemberListSyntax processNode(MemberListSyntax memberList) {
+                       memberList.AddChild(new SingleTokenSyntax(Read()));
+                       while (skipTriviaAndComments(memberList)) {
+                               if (Peek().Is(StyleTokenType.Name)) {
+                                       memberList.AddChild(processNode(new MemberSyntax(new MemberIdentifierSyntax(Read()))));
+                                       continue;
+                               }
+                               if (Peek().Is(StyleTokenType.ClosingBrace))
+                                       memberList.AddChild(new SingleTokenSyntax(Read()));
+                               break;
+                       } 
+
+                       return memberList;
+               }
+               MemberSyntax processNode(MemberSyntax member) {
+                       if (skipTriviaAndComments(member))
+                               if (accept(member, StyleTokenType.EqualSign)) 
+                                       if (skipTriviaAndComments(member))
+                                               member.AddChild(processNode(new ImlValueSyntax()));
+                       return member;
+               }
+               ImlValueSyntax processNode(ImlValueSyntax iml) {
+                       if (accept(iml, StyleTokenType.MemberValueOpen)) {
+                               while (tryPeek(out Token tok)) {
+                                       if (tok.Is(StyleTokenType.ConstantRefOpen)) {
+                                               iml.AddChild(processNode(new ConstanteReferenceSyntax()));
+                                       } else if (tok.Is(StyleTokenType.MemberValueClose)) {
+                                               iml.AddChild(new SingleTokenSyntax(Read()));
+                                               accept(iml, StyleTokenType.EndOfExpression);                    
+                                               break;
+                                       } else  if (tok.Is(StyleTokenType.MemberValuePart)) {
+                                               iml.AddChild(new SingleTokenSyntax(Read()));
+                                       } else  {
+                                               iml.AddChild(new UnexpectedTokenSyntax(Read()));
+                                               break;
+                                       }
+                               }
+                       }                                                               
+
+                       return iml;
+               }
+               ConstanteReferenceSyntax processNode(ConstanteReferenceSyntax cst) {
+                       if (accept(cst, StyleTokenType.ConstantRefOpen))
+                               if (accept(cst, StyleTokenType.ConstantName))
+                                       accept(cst, StyleTokenType.ClosingBrace);
+                       return cst;
+               }
+
                public override async Task<SyntaxRootNode> Process () {
                        Tokenizer tokenizer = new StyleTokenizer();
                        ReadOnlyTextBuffer buff = document.ImmutableBufferCopy;
                        Token[] tokens = tokenizer.Tokenize(buff.Source.Span);
-                       currentNode = Root = new StyleRootSyntax (buff, tokens);
-
-                       currentLine = 0;
                        tokIdx = 0;
-                       /*
-                       while (tokIdx < tokens.Length) {
-                               if (!skipTrivia(true))
-                                       break;
-                               Token curTok = tokens[tokIdx];
-                               if (currentNode is StyleRootSyntax srs) {
-                                       if (tokens[tokIdx].GetTokenType() != StyleTokenType.Name) {
-                                               addException ("Unexpected Token");
-                                       } else {
-                                               StyleIdentifierSyntax sis = new StyleIdentifierSyntax(currentLine, tokIdx);
-                                               if (!skipTrivia(true)) {
-                                                       addException ("Unexpected end of file");
-                                                       break;
-                                               }
-                                               if (tokens[tokIdx].GetTokenType() == StyleTokenType.EqualSign) {
-                                                       ConstantDefinitionSyntax cds = new ConstantDefinitionSyntax(sis);
-                                                       cds.equal = tokIdx;
-                                                       if (!skipTrivia(true)) {
-                                                               addException ("Unexpected end of file");
-                                                               break;
-                                                       }
-
 
-                                               }
-                                               
-                                       }
+                       Root = new StyleRootSyntax (buff, tokens);
+                       while (!EOF) {
+                               if (!skipTriviaAndComments(Root))
+                                       break;
+                               if (!Peek().Is(StyleTokenType.Name)) {
+                                       Root.AddChild(new UnexpectedTokenSyntax(Read()));       
+                                       continue;
+                               }
+                               Token name = Read();
+                               if (!skipTriviaAndComments(Root)) {
+                                       Root.AddChild(new UnexpectedTokenSyntax(name)); 
+                                       break;
+                               }
+                               if (Peek().Is(StyleTokenType.EqualSign)) {
+                                       Root.AddChild(processNode(new ConstantDefinitionSyntax(new ConstantNameSyntax(name))));
+                               } else {
+                                       Root.AddChild(processNode(new StyleDefinitionSyntax(new StyleIdentifierSyntax(name))));
                                }
-                       
-                               tokIdx++;
-                       }
-                       while (currentNode.Parent != null) {
-                               if (!currentNode.LastTokenIndex.HasValue)
-                                       finishCurrentNode (-1);
-                               else
-                                       currentNode = currentNode.Parent;
                        }
-                       setCurrentNodeEndLine (currentLine);*/
 
                        return Root;
                }
diff --git a/plugins/CECrowPlugin/src/Parsing/Styling/StyleSyntaxNodes.cs b/plugins/CECrowPlugin/src/Parsing/Styling/StyleSyntaxNodes.cs
new file mode 100644 (file)
index 0000000..8c0bd49
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright (c) 2025  Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using CrowEditBase;
+
+namespace CECrowPlugin.Style
+{
+
+       public class StyleRootSyntax : SyntaxRootNode {
+               public StyleRootSyntax (ReadOnlyTextBuffer source, Token[] tokens) : base (source, tokens) { }
+       }
+       public class ConstantDefinitionSyntax : MultiNodeSyntax {
+               public ConstantDefinitionSyntax(ConstantNameSyntax nameNode) {
+                       AddChild(nameNode);
+               }
+        public override bool IsComplete => ChildSequenceIs
+               (
+                       typeof(ConstantNameSyntax),
+                       StyleTokenType.EqualSign,
+                       StyleTokenType.MemberValueOpen,
+                       StyleTokenType.MemberValuePart,
+                       StyleTokenType.MemberValueClose,
+                       StyleTokenType.EndOfExpression
+               );
+       }
+       public class StyleDefinitionSyntax : MultiNodeSyntax {
+               public StyleDefinitionSyntax(StyleIdentifierSyntax nameNode) {
+                       AddChild(nameNode);
+               }
+        /*public override bool IsComplete => ChildSequenceIs
+               (
+                       typeof(ConstantNameSyntax),
+                       StyleTokenType.EqualSign,
+                       StyleTokenType.MemberValueOpen,
+                       StyleTokenType.MemberValuePart,
+                       StyleTokenType.MemberValueClose,
+                       StyleTokenType.EndOfExpression
+               );*/            
+       }       
+
+       public class ConstantNameSyntax : SingleTokenSyntax {
+               public ConstantNameSyntax(Token name) : base(name) {}
+        public override bool IsComplete => token.GetTokenType() == StyleTokenType.Name;
+    }
+       public class StyleIdentifierSyntax : SingleTokenSyntax {
+               public StyleIdentifierSyntax(Token name) : base(name) {}
+        public override bool IsComplete => token.GetTokenType() == StyleTokenType.Name;
+       }
+       public class MemberIdentifierSyntax : SingleTokenSyntax {
+               public MemberIdentifierSyntax(Token name) : base(name) {}
+        public override bool IsComplete => token.GetTokenType() == StyleTokenType.Name;
+       }
+       public class MemberListSyntax : MultiNodeSyntax {
+
+       }
+       public class MemberSyntax : MultiNodeSyntax {
+               public MemberSyntax(MemberIdentifierSyntax name) {
+                       AddChild(name);
+               }
+       }
+
+
+       public class ImlValueSyntax : MultiNodeSyntax {
+
+       }
+       public class ConstanteReferenceSyntax : MultiNodeSyntax {
+       }
+}
\ No newline at end of file
index 8267f1b5cc26ce85ee48e47c62bcc41159e66242..055572d4c95f8e574acb119f125438d33bbc3b29 100644 (file)
@@ -20,7 +20,6 @@ namespace CECrowPlugin.Style
                BlockCommentEnd                 = 0x0106,
                Name                                    = 0x0200,
                StyleKey                                = 0x0201,//may be a class name or a style name.
-               MemberName                              = 0x0202,
                ConstantName                    = 0x0203,
                Punctuation                             = 0x0400,
                OpeningBrace                    = 0x0401,// '{'
@@ -28,9 +27,13 @@ namespace CECrowPlugin.Style
                Comma                                   = 0x0403,// ','
                EndOfExpression                 = 0x0404,// ';'
                EqualSign                               = 0x0801,
-               MemberValuePart                         = 0x2000,
+               MemberValuePart                 = 0x2000,
                MemberValueOpen                 = 0x2401,
                MemberValueClose                = 0x2402,
                ConstantRefOpen                 = 0x2403,// '${'
+
+               Syntax                                  = 0x8000,
+               ConstantDefinition              = 0x8001,
+               StyleDefinition                 = 0x8002,
        }
 }
\ No newline at end of file
diff --git a/plugins/CECrowPlugin/src/Parsing/Styling/SyntaxNodes.cs b/plugins/CECrowPlugin/src/Parsing/Styling/SyntaxNodes.cs
deleted file mode 100644 (file)
index 3e1d8d8..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2013-2021  Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-using CrowEditBase;
-
-namespace CECrowPlugin.Style
-{
-
-       public class StyleRootSyntax : SyntaxRootNode {
-               public StyleRootSyntax (ReadOnlyTextBuffer source, Token[] tokens) : base (source, tokens) { }
-       }
-       public class ConstantDefinitionSyntax : SyntaxNode {
-       }
-       public class StyleIdentifierSyntax : SyntaxNode {
-       }
-       public class ImlValueSyntax : SyntaxNode {
-
-       }
-       public class AttributeSyntax : SyntaxNode {
-       }
-}
\ No newline at end of file
index d32410ddfe7f268f651a8fd36976c5253992892f..3c6f920be2e5ac9f4488a8ef05a22d985313dac5 100644 (file)
@@ -31,8 +31,9 @@ namespace CrowEdit.Ebnf
                        return null;
                }
 
-               public override Color GetColorForToken(TokenType tokType)
+               public override Color GetColorForToken(Token token)
                {
+                       TokenType tokType = token.Type;
                        EbnfTokenType xmlTokType = (EbnfTokenType)tokType;
                        if (xmlTokType == EbnfTokenType.OpenBracket || xmlTokType == EbnfTokenType.ClosingBracket)
                                return Colors.RebeccaPurple;
@@ -51,7 +52,7 @@ namespace CrowEdit.Ebnf
                                return Colors.Blue;
                        if (xmlTokType == EbnfTokenType.Name)
                                return Colors.Green;
-                       return base.GetColorForToken(tokType);
+                       return base.GetColorForToken(token);
 
                }
        }
index 86759e60803c718cf9fbe4aad2d1a125ac4b3c0f..ef2e1c6118beac689b5a43ffe5877b67fcf922ba 100644 (file)
@@ -27,7 +27,7 @@ namespace CrowEdit.Ebnf
                        Tokenizer tokenizer = new EbnfTokenizer();
                        ReadOnlyTextBuffer buff = document.ImmutableBufferCopy;
                        Token[] tokens = tokenizer.Tokenize(buff.Source.Span);
-                       currentNode = Root = new EbnfRootSyntax (buff, tokens);
+                       Root = new EbnfRootSyntax (buff, tokens);
 
                        currentLine = 0;
                        tokIdx = 0;
index adabef8b6404e1d709956ee0e615b6e9e42c7908..2adc607e1614acb090f16617754ff79636e0b20c 100644 (file)
@@ -69,9 +69,14 @@ namespace CERoslynPlugin
                        }
                }*/
                public override string GetTokenTypeString (TokenType tokenType) => ((SyntaxKind)tokenType).ToString();
-               public override Color GetColorForToken(TokenType tokType)
+               public override Color GetColorForToken(Token token)
                {
+                       SyntaxKind tokType = (SyntaxKind)token.Type;
                        CSTokenType xmlTokType = (CSTokenType)tokType;
+                       if (tokType == SyntaxKind.IdentifierToken)
+                               return Colors.Blue;
+                       
+                       /*CSTokenType xmlTokType = (CSTokenType)tokType;
                        if (xmlTokType.HasFlag (CSTokenType.Punctuation))
                                return Colors.DarkGrey;
                        if (tokType.HasFlag (TokenType.WhiteSpace))
@@ -89,7 +94,7 @@ namespace CERoslynPlugin
                        if (xmlTokType == CSTokenType.Directive)
                                return Colors.Black;
                        if (xmlTokType == CSTokenType.Operator)
-                               return Colors.DarkSlateBlue;
+                               return Colors.DarkSlateBlue;*/
                        return Colors.Red;
 
                }
index dfb7f37d36eff7895cb42429bf2337382895699b..1814cde2c066df5ef4cf9c7c33303f4bc1ef8183 100644 (file)
@@ -3,10 +3,12 @@
 // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Linq;
 using System.Threading.Tasks;
 using CrowEditBase;
 using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
 using Microsoft.CodeAnalysis.CSharp.Syntax;
 using Microsoft.CodeAnalysis.Text;
 
@@ -15,7 +17,20 @@ namespace CERoslynPlugin
        public class CSRootSyntax : SyntaxRootNode {
                public CSRootSyntax (ReadOnlyTextBuffer source, Token[] tokens) : base (source, tokens) {       }
        }
+       public class CSToken : SingleTokenSyntax {
+               SyntaxToken cstoken;
+               public CSToken(SyntaxToken token, Token tok) : base (tok) {
+                       cstoken = token;
+               }
+               public override string ToString() => $"TOK:{cstoken.Kind()}";
+       }
        public class CSSyntaxNode : MultiNodeSyntax {
+               Microsoft.CodeAnalysis.SyntaxNode node;
+               public CSSyntaxNode(Microsoft.CodeAnalysis.SyntaxNode node) {
+                       this.node = node;
+               }
+               public override string ToString() => $"{node.Kind()}";
+
     }
        
        public class CSSyntaxAnalyser : SyntaxAnalyser {
@@ -50,13 +65,13 @@ namespace CERoslynPlugin
                }
                public override void Visit (Microsoft.CodeAnalysis.SyntaxNode node)
                {
-                       Location loc = node.GetLocation();
+                       /*Location loc = node.GetLocation();
                        LinePosition start = loc.GetLineSpan().StartLinePosition;
                        LinePosition end = loc.GetLineSpan().EndLinePosition;
 
                        int indexBase = Root.FindTokenIndexIncludingPosition(node.Span.Start);
-                       int lastTokIndex = Root.FindTokenIndexIncludingPosition(node.Span.End - 1);
-                       currentNode = currentNode.AddChild(new CSSyntaxNode()) as MultiNodeSyntax;
+                       int lastTokIndex = Root.FindTokenIndexIncludingPosition(node.Span.End - 1);*/
+                       currentNode = currentNode.AddChild(new CSSyntaxNode(node)) as MultiNodeSyntax;
                        
                        base.Visit (node);
 
@@ -65,9 +80,13 @@ namespace CERoslynPlugin
 
         public override void VisitToken(SyntaxToken token)
         {
-                       TextSpan fs = token.FullSpan;
-                       Token tok = new Token(fs.Start,fs.Length,(TokenType)token.RawKind);
-                       currentNode.AddChild(new SingleTokenSyntax(tok));
+                       TextSpan fs = token.Span;
+                       if (token.Span.Length == 0)
+                               Debug.WriteLine($"Empty token: {token}");
+                       else {
+                               Token tok = new Token(fs.Start,fs.Length,(TokenType)token.RawKind);
+                               currentNode.AddChild(new CSToken(token, tok));
+                       }
             base.VisitToken(token);
         }
     }
index 4fdc81ff5b030f6285f1844db0b15f0b19109d5c..35b72b86e3902b83dd28cd93084ca6dfbcf12b73 100644 (file)
@@ -213,8 +213,9 @@ namespace CrowEdit.Xml
                        return true;
                }*/
 
-               public override Color GetColorForToken(TokenType tokType)
+               public override Color GetColorForToken(Token token)
                {
+                       TokenType tokType = token.Type;
                        XmlTokenType xmlTokType = (XmlTokenType)tokType;
                        if (xmlTokType.HasFlag (XmlTokenType.Punctuation))
                                return Colors.DarkGrey;
index 3c9da55b344e22853cd28bbe593f009836fcff38..d64454e7193a259647c1cb3045ea7171eee275da 100644 (file)
@@ -19,7 +19,7 @@ namespace CrowEdit.Xml
                        Tokenizer tokenizer = new XmlTokenizer();
                        ReadOnlyTextBuffer buff = document.ImmutableBufferCopy;
                        Token[] tokens = tokenizer.Tokenize(buff.Source.Span);
-                       currentNode = Root = new XMLRootSyntax (buff, tokens);
+                       Root = new XMLRootSyntax (buff, tokens);
 
                        currentLine = 0;
                        tokIdx = 0;
index f52acb3f548fd2becf565cf691a4b4a100333b5b..65c65fe720c87f77cef096f57ccdd367e7e46e42 100644 (file)
                                                                                Foreground="Transparent"
                                                                                MouseEnter="{Foreground=DimGrey}"
                                                                                MouseLeave="{Foreground=Transparent}">
-                                                                       <HorizontalStack Background="{./Background}" Spacing="1">
+                                                                       <HorizontalStack Background="{./Background}" Spacing="3">
                                                                                <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
                                                                                        Path="{./Image}"
                                                                                        Visible="{HasChilds}"
                                                                                        SvgSub="{isExpanded}"
                                                                                        MouseEnter="{Background=LightGrey}"
                                                                                        MouseLeave="{Background=Transparent}"/>
-                                                                               <Label Style="TreeLabel" Text="{./Caption}"/>
-                                                                               <Label Style="TreeLabel" Text="ok:"/>
-                                                                               <Label Style="TreeLabel" Text="{IsComplete}"/>
+                                                                               <Label Style="TreeLabel" Text="{StartLocation}"/>
+                                                                               <CheckBox Style="StateBoxSmall" Caption="{./Caption}" IsChecked="{IsComplete}"/>
                                                                                <Label Style="TreeLabel" Text="span:"/>
                                                                                <Label Style="TreeLabel" Text="{Span}"/>
-                                                                               <Label Style="TreeLabel" Text="foldable:"/>
-                                                                               <Label Style="TreeLabel" Text="{IsFoldable}"/>
+                                                                               <CheckBox Style="StateBoxSmall" Caption="Foldable" IsChecked="{IsFoldable}"/>
                                                                        </HorizontalStack>
                                                                </Border>
                                                                <!--<Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"