From c05d77faf8a8fc6f2e7b6f5298f2772f6b1d2b09 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Sat, 8 Mar 2025 22:10:28 +0100 Subject: [PATCH] save commit --- CrowEditBase/src/Compiler/SourceDocument.cs | 8 +- CrowEditBase/src/Compiler/SyntaxAnalyser.cs | 52 +++-- CrowEditBase/src/Compiler/SyntaxNode.cs | 87 +++++++-- CrowEditBase/src/Compiler/SyntaxRootNode.cs | 2 +- CrowEditBase/src/Compiler/Token.cs | 6 +- CrowEditBase/src/SourceEditor.cs | 19 +- CrowEditBase/ui/CrowEdit.style | 10 + CrowEditBase/ui/SimpleStatus.template | 2 +- .../src/Parsing/IML/ImlDocument.cs | 5 +- .../src/Parsing/Styling/StyleDocument.cs | 25 ++- .../Parsing/Styling/StyleSyntaxAnalyser.cs | 181 ++++++++++++++---- .../src/Parsing/Styling/StyleSyntaxNodes.cs | 72 +++++++ .../src/Parsing/Styling/StyleTokenType.cs | 7 +- .../src/Parsing/Styling/SyntaxNodes.cs | 25 --- .../CEEbnfPlugin/src/Parsing/EbnfDocument.cs | 5 +- .../src/Parsing/EbnfSyntaxAnalyser.cs | 2 +- plugins/CERoslynPlugin/src/CSDocument.cs | 9 +- .../CERoslynPlugin/src/CSSyntaxAnalyser.cs | 31 ++- .../CEXmlPlugin/src/Parsing/XmlDocument.cs | 3 +- .../src/Parsing/XmlSyntaxAnalyser.cs | 2 +- ui/windows/winSyntaxExplorer.crow | 10 +- 21 files changed, 427 insertions(+), 136 deletions(-) create mode 100644 plugins/CECrowPlugin/src/Parsing/Styling/StyleSyntaxNodes.cs delete mode 100644 plugins/CECrowPlugin/src/Parsing/Styling/SyntaxNodes.cs diff --git a/CrowEditBase/src/Compiler/SourceDocument.cs b/CrowEditBase/src/Compiler/SourceDocument.cs index d702db1..b4f220b 100644 --- a/CrowEditBase/src/Compiler/SourceDocument.cs +++ b/CrowEditBase/src/Compiler/SourceDocument.cs @@ -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; } /// @@ -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)) diff --git a/CrowEditBase/src/Compiler/SyntaxAnalyser.cs b/CrowEditBase/src/Compiler/SyntaxAnalyser.cs index 449fc0a..9273fe1 100644 --- a/CrowEditBase/src/Compiler/SyntaxAnalyser.cs +++ b/CrowEditBase/src/Compiler/SyntaxAnalyser.cs @@ -22,15 +22,9 @@ namespace CrowEditBase protected Token curTok => tokIdx < 0 ? default : tokens[tokIdx]; protected ReadOnlySpan 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 /// @@ -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));*/ diff --git a/CrowEditBase/src/Compiler/SyntaxNode.cs b/CrowEditBase/src/Compiler/SyntaxNode.cs index d720aae..69c73cb 100644 --- a/CrowEditBase/src/Compiler/SyntaxNode.cs +++ b/CrowEditBase/src/Compiler/SyntaxNode.cs @@ -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 children = new List (); + 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 children = new List (); public IEnumerable Children => children; public SyntaxNode AddChild (SyntaxNode child) { children.Add (child); @@ -32,8 +47,35 @@ namespace CrowEditBase } public IEnumerable GetChilds () => children.OfType(); - - public override bool HasChilds => children.Count > 0; + public bool ChildIs (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; diff --git a/CrowEditBase/src/Compiler/SyntaxRootNode.cs b/CrowEditBase/src/Compiler/SyntaxRootNode.cs index 44f7492..2c177e2 100644 --- a/CrowEditBase/src/Compiler/SyntaxRootNode.cs +++ b/CrowEditBase/src/Compiler/SyntaxRootNode.cs @@ -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 GetText(TextSpan span) => diff --git a/CrowEditBase/src/Compiler/Token.cs b/CrowEditBase/src/Compiler/Token.cs index 7f11721..40a6b09 100644 --- a/CrowEditBase/src/Compiler/Token.cs +++ b/CrowEditBase/src/Compiler/Token.cs @@ -8,8 +8,9 @@ using System.Diagnostics.CodeAnalysis; namespace CrowEditBase { - public struct Token : IComparable, IEquatable { + public class Token : IComparable, IEquatable { 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; diff --git a/CrowEditBase/src/SourceEditor.cs b/CrowEditBase/src/SourceEditor.cs index 9a1ba91..4724f9e 100644 --- a/CrowEditBase/src/SourceEditor.cs +++ b/CrowEditBase/src/SourceEditor.cs @@ -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; diff --git a/CrowEditBase/ui/CrowEdit.style b/CrowEditBase/ui/CrowEdit.style index ca50a82..099d56a 100644 --- a/CrowEditBase/ui/CrowEdit.style +++ b/CrowEditBase/ui/CrowEdit.style @@ -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"; diff --git a/CrowEditBase/ui/SimpleStatus.template b/CrowEditBase/ui/SimpleStatus.template index 9b124d3..b6392a9 100644 --- a/CrowEditBase/ui/SimpleStatus.template +++ b/CrowEditBase/ui/SimpleStatus.template @@ -1,2 +1,2 @@  -