]> O.S.I.I.S - jp/crow.git/commitdiff
csharp parser wip
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 8 Mar 2018 07:46:43 +0000 (08:46 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 8 Mar 2018 07:46:43 +0000 (08:46 +0100)
CrowIDE/src/CrowIDE.cs
CrowIDE/src/SourceEditor/BufferParser.cs
CrowIDE/src/SourceEditor/CSharpParser.cs
CrowIDE/src/SourceEditor/SourceEditor.cs
CrowIDE/src/SourceEditor/Token.cs
CrowIDE/src/SourceEditor/XMLParser.cs
src/GraphicObjects/DockStack.cs

index 752f6a708527c79370931b3e666e597da8adf16b..f2b4d9c2a7e002eb5982b3f5325b7bfa50568649 100644 (file)
@@ -131,6 +131,9 @@ namespace Crow.Coding
                        DockWindow dw = loadDockWindow ("#Crow.Coding.ui.DockWindows.winEditor.crow");
                        dw.DockingPosition = Alignment.Center;
                        dw.Dock (mainDock.Children [0] as DockStack);
+                       dw = loadDockWindow ("#Crow.Coding.ui.DockWindows.winSolution.crow");
+                       dw.DockingPosition = Alignment.Right;
+                       dw.Dock (mainDock.Children [0] as DockStack);
                }
 
                void loadProjProps () {
index 0d1d0667f2031b486bd5515d9f53cf46c080fe90..6bef920d93070293788f18740dc48bd1a8b01412 100644 (file)
@@ -81,6 +81,17 @@ namespace Crow.Coding
                internal int currentLine = 0;
                internal int currentColumn = 0;
 
+               int syntTreeDepth = 0;
+               public int SyntacticTreeDepth {
+                       get { return syntTreeDepth;}
+                       set {
+                               syntTreeDepth = value;
+                               if (syntTreeDepth > SyntacticTreeMaxDepth)
+                                       SyntacticTreeMaxDepth = syntTreeDepth;
+                       }
+               }
+               public int SyntacticTreeMaxDepth = 0;
+
                protected CodeBuffer buffer;
                protected Token currentTok;
                protected bool eol = true;
@@ -177,6 +188,10 @@ namespace Crow.Coding
                }
 
                #region low level parsing
+               protected void addCharToCurTok(char c, Point position){
+                       currentTok.Start = position;
+                       currentTok += c;
+               }
                /// <summary>
                /// Read one char from current position in buffer and store it into the current token
                /// </summary>
@@ -268,6 +283,15 @@ namespace Crow.Coding
                        currentColumn++;
                        return c;
                }
+               protected virtual string Read(int charCount){
+                       string tmp = "";
+                       for (int i = 0; i < charCount; i++) {
+                               if (eol)
+                                       break;
+                               tmp += Read ();
+                       }
+                       return tmp;
+               }
                /// <summary>
                /// read until end of line is reached
                /// </summary>
@@ -316,5 +340,9 @@ namespace Crow.Coding
                                saveAndResetCurrentTok ();
                }
                #endregion
+
+               protected void throwParserException(string msg){
+                       throw new ParserException (currentLine, currentColumn, msg);
+               }
        }
 }
\ No newline at end of file
index 2878ce19da417903a3c1ed85e0b485a25714b09e..f612dacce642b958bc3c4a960311883423707611 100644 (file)
@@ -135,13 +135,20 @@ namespace Crow.Coding
                static Regex rxDecimal = new Regex(@"[0-9]+");
                static Regex rxHexadecimal = new Regex(@"[0-9a-fA-F]+");
 
+               public static bool CharIsValidCharStartName (char c) {
+                       return rxNameStartChar.IsMatch(new string(new char[]{c}));
+               }
+               public static bool CharIsValidCharName (char c) {
+                       return rxNameChar.IsMatch(new string(new char[]{c}));
+               }
+
                public bool nextCharIsValidCharStartName
                {
-                       get { return rxNameStartChar.IsMatch(new string(new char[]{Peek()})); }
+                       get { return CharIsValidCharStartName(Peek()); }
                }
                public bool nextCharIsValidCharName
                {
-                       get { return rxNameChar.IsMatch(new string(new char[]{Peek()})); }
+                       get { return CharIsValidCharName(Peek()); }
                }
                #endregion
 
@@ -164,23 +171,10 @@ namespace Crow.Coding
                        States previousEndingState = (States)cl.EndingState;
 
                        while (! eol) {
-                               SkipWhiteSpaces ();
-
-                               if (eol)
-                                       break;
-
-                               if (Peek () == '\n') {
-                                       if (currentTok != TokenType.Unknown)
-                                               throw new ParserException (currentLine, currentColumn, "Unexpected end of line");
-                                       Read ();
-                                       eol = true;
-                                       continue;
-                               }
+                               if (currentTok.IsNull)
+                                       SkipWhiteSpaces ();
 
                                if (curState == States.BlockComment) {
-                                       if (currentTok != TokenType.Unknown)
-                                               Debugger.Break ();
-
                                        currentTok.Start = CurrentPosition;
                                        currentTok.Type = (BufferParser.TokenType)TokenType.BlockComment;
                                        currentTok += ReadLineUntil ("*/");
@@ -193,6 +187,11 @@ namespace Crow.Coding
                                }
 
                                switch (Peek()) {
+                               case '\n':
+                                       eol = true;
+                                       if (!currentTok.IsNull)
+                                               saveAndResetCurrentTok ();
+                                       break;
                                case '#':
                                        readToCurrTok (true);
                                        currentTok += ReadLine ();
@@ -221,21 +220,83 @@ namespace Crow.Coding
                                                break;
                                        }
                                        break;
-                               default:                                        
-                                       if (nextCharIsValidCharStartName) {                                             
-                                               readToCurrTok (true);
-                                               while (nextCharIsValidCharName)
-                                                       readToCurrTok ();
+                               case '{':
+                                       if (currentTok.IsNull)
+                                               readAndResetCurrentTok (TokenType.OpenBlock, true);
+                                       else
+                                               readToCurrTok ();
+                                       break;
+                               case '}':
+                                       if (currentTok.IsNull)
+                                               readAndResetCurrentTok (TokenType.CloseBlock, true);
+                                       else
+                                               readToCurrTok ();                                       
+                                       break;
+                               case '\\'://unicode escape sequence
+                                       if (!(currentTok.Type == TokenType.Identifier ||
+                                           currentTok.IsEmpty || currentTok.Type == TokenType.StringLitteral || currentTok.Type == TokenType.CharLitteral)) {
+                                               saveAndResetCurrentTok ();
+                                       }
+                                       Point pos = CurrentPosition;
+                                       Read ();
+                                       char escChar = Read ();
 
-                                               if (keywords.Contains (currentTok.Content))
-                                                       saveAndResetCurrentTok (TokenType.Keyword);
-                                               else
-                                                       saveAndResetCurrentTok (TokenType.Identifier);
-                                               continue;
+                                       if (escChar == 'u') {
+                                               char c = char.ConvertFromUtf32 (int.Parse (Read (4), System.Globalization.NumberStyles.HexNumber))[0];
+                                               if (currentTok.IsEmpty) {
+                                                       if (!CharIsValidCharStartName (c))
+                                                               throwParserException ("expecting identifier start");                                                    
+                                                       currentTok.Start = pos;
+                                                       currentTok.Type = TokenType.Identifier;
+                                               } else if (currentTok.Type == TokenType.Identifier) {
+                                                       if (!CharIsValidCharName (c))
+                                                               throwParserException ("expecting identifier valid char");                                               
+                                               }
+                                               currentTok += c;
+                                               break;
                                        }
-                                       readToCurrTok (true);
-                                       currentTok+=ReadLine ();
-                                       saveAndResetCurrentTok (TokenType.Unknown);
+                                       currentTok += new String (new char[] { '\\', escChar });
+                                       break;
+                               case '\'':
+                                       if (currentTok.IsNull) {
+                                               readAndResetCurrentTok (TokenType.CharLitteralOpening, true);
+                                               currentTok.Type = TokenType.CharLitteral;
+                                       } else if (currentTok.Type == TokenType.CharLitteral) {
+                                               saveAndResetCurrentTok ();
+                                               readAndResetCurrentTok (TokenType.CharLitteralClosing, true);
+                                       } else if (currentTok.Type == TokenType.StringLitteral){
+                                               readToCurrTok ();
+                                       } else
+                                               throwParserException ("unexpected character: (\')");                                            
+                                       break;
+                               case '"':
+                                       if (currentTok.IsNull) {
+                                               readAndResetCurrentTok (TokenType.StringLitteralOpening, true);
+                                               currentTok.Type = TokenType.StringLitteral;
+                                       } else if (currentTok.Type == TokenType.StringLitteral) {
+                                               saveAndResetCurrentTok ();
+                                               readAndResetCurrentTok (TokenType.StringLitteralClosing, true);
+                                       } else
+                                               throwParserException ("unexpected character: (\")");
+                                       break;
+                               default:
+                                       if (currentTok.Type == TokenType.StringLitteral || currentTok.Type == TokenType.CharLitteral) {
+                                               readToCurrTok (currentTok.IsEmpty);
+                                       } else if (currentTok.IsNull) {
+                                               if (nextCharIsValidCharStartName) {                                             
+                                                       readToCurrTok (true);
+                                                       while (nextCharIsValidCharName)
+                                                               readToCurrTok ();
+
+                                                       if (keywords.Contains (currentTok.Content))
+                                                               saveAndResetCurrentTok (TokenType.Keyword);
+                                                       else
+                                                               saveAndResetCurrentTok (TokenType.Identifier);
+                                                       continue;
+                                               } else
+                                                       readAndResetCurrentTok(TokenType.Unknown, true);
+                                       } else
+                                               readAndResetCurrentTok(TokenType.Unknown, true);                                        
                                        break;
                                }
                        }
@@ -245,21 +306,41 @@ namespace Crow.Coding
 
                        cl.EndingState = (int)curState;
                }
-
-               Node addChildNode (Node curNode, CodeLine cl, int tokPtr) {
-                       Node n = new Node () { Name = cl.Tokens [tokPtr].Content, StartLine = cl };
+               
+               Node addChildNode (Node curNode, CodeLine cl, int tokPtr, string type = "") {
+                       Node n = new Node () { Name = cl.Tokens [tokPtr].Content, StartLine = cl, Type = type };
                        curNode.AddChild (n);
                        if (cl.SyntacticNode == null)
                                cl.SyntacticNode = n;
+                       SyntacticTreeDepth++;
                        return n;
                }
+               void closeNodeAndGoUp (ref Node n, CodeLine cl, string type = ""){
+                       while (n != null) {
+                               if (n.Type == type) {
+                                       n.EndLine = cl;
+                                       n = n.Parent;
+                                       SyntacticTreeDepth--;
+                                       break;
+                               }
+                               n = n.Parent;
+                               SyntacticTreeDepth--;
+                       }
+//                     if (n.StartLine == cl){//prevent single line node
+//                             n.Parent.Children.Remove (n);
+//                             if (cl.SyntacticNode == n)
+//                                     cl.SyntacticNode = null;
+//                     }else                           
+
+               }
                void closeNodeAndGoUp (ref Node n, CodeLine cl){
-                       if (n.StartLine == cl){//prevent single line node
-                               n.Parent.Children.Remove (n);
-                               if (cl.SyntacticNode == n)
-                                       cl.SyntacticNode = null;
-                       }else                           
-                               n.EndLine = cl;
+                       //                      if (n.StartLine == cl){//prevent single line node
+                       //                              n.Parent.Children.Remove (n);
+                       //                              if (cl.SyntacticNode == n)
+                       //                                      cl.SyntacticNode = null;
+                       //                      }else   
+                       SyntacticTreeDepth--;
+                       n.EndLine = cl;
                        n = n.Parent;
                }
 
@@ -268,6 +349,7 @@ namespace Crow.Coding
                        RootNode = new Node () { Name = "RootNode", Type="Root" };
 
                        Node currentNode = RootNode;
+                       SyntacticTreeDepth = SyntacticTreeMaxDepth = 0;
 
                        int ptrLine = 0;
                        while (ptrLine < buffer.LineCount) {
@@ -299,8 +381,8 @@ namespace Crow.Coding
                                                }
                                                ptrLine--;
                                                if (ptrLine - startLine > 0) {
-                                                       currentNode = addChildNode (currentNode, cl, tokPtr);
-                                                       closeNodeAndGoUp (ref currentNode, buffer [ptrLine]);
+                                                       currentNode = addChildNode (currentNode, cl, tokPtr, "comment");
+                                                       closeNodeAndGoUp (ref currentNode, buffer [ptrLine], "comment");
                                                }
                                                break;
                                        }
@@ -314,9 +396,11 @@ namespace Crow.Coding
                                                break;
                                        case TokenType.Preprocessor:
                                                if (cl.Tokens [tokPtr].Content.StartsWith ("#region")) {
-                                                       currentNode = addChildNode (currentNode, cl, tokPtr);
-                                               }else if (cl.Tokens [tokPtr].Content.StartsWith("#endregion"))
-                                                       closeNodeAndGoUp (ref currentNode, cl);
+                                                       currentNode = addChildNode (currentNode, cl, tokPtr, "region");
+                                               } else if (cl.Tokens [tokPtr].Content.StartsWith ("#endregion")) {
+                                                       
+                                                       closeNodeAndGoUp (ref currentNode, cl,"region");
+                                               }
                                                break;
                                        }
                                        onlyWhiteSpace = false;
@@ -324,6 +408,15 @@ namespace Crow.Coding
                                }
                                ptrLine++;
                        }
+                       ptrLine = 0;
+                       while (ptrLine < buffer.LineCount) {
+                               CodeLine cl = buffer [ptrLine];
+                               if (cl.IsFoldable) {
+                                       if (cl.SyntacticNode.Type == "comment" || cl.SyntacticNode.Type == "region")
+                                               cl.IsFolded = true;
+                               }
+                               ptrLine++;
+                       }
                }
        }
 }
index 5e012c1969dde6e480470f1a133f5d88b1a84118..760bd2c89bd0db3094bc6d5db04e727cd6d08fb9 100644 (file)
@@ -63,7 +63,7 @@ namespace Crow.Coding
                        formatting.Add ((int)BufferParser.TokenType.BlockComment, new TextFormatting (Color.Gray, Color.Transparent, false, true));
                        formatting.Add ((int)BufferParser.TokenType.LineComment, new TextFormatting (Color.Gray, Color.Transparent, false, true));
                        formatting.Add ((int)BufferParser.TokenType.OperatorOrPunctuation, new TextFormatting (Color.Black, Color.Transparent));
-                       formatting.Add ((int)BufferParser.TokenType.Keyword, new TextFormatting (Color.DarkCyan, Color.Transparent));
+                       //formatting.Add ((int)BufferParser.TokenType.Keyword, new TextFormatting (Color.DarkCyan, Color.Transparent));
 
                        parsing.Add (".crow", "Crow.Coding.XMLParser");
                        parsing.Add (".template", "Crow.Coding.XMLParser");
@@ -115,8 +115,8 @@ namespace Crow.Coding
                }
                const int leftMarginGap = 3;//gap between items in margin and text
                const int foldSize = 9;//folding rectangles size
-               const int foldMargin = 50;//folding margin size
-               const int foldHSpace = 7;//folding level tabulation x
+               const int foldHSpace = 4;//folding level tabulation x
+               int foldMargin { get { return parser == null ? 0 : parser.SyntacticTreeMaxDepth * foldHSpace; }}//folding margin size
 
                #region private and protected fields
                bool foldingEnabled = true;
@@ -154,7 +154,7 @@ namespace Crow.Coding
                        if (foldingEnabled)
                                leftMargin += foldMargin;
                        if (leftMargin > 0)
-                               leftMargin += leftMarginGap;
+                               leftMargin += leftMarginGap;                    
                        updateVisibleColumns ();
                }
                void findLongestLineAndUpdateMaxScrollX() {
@@ -265,11 +265,12 @@ namespace Crow.Coding
                                        continue;
                                parser.TryParseBufferLine (e.LineStart + i);
                        }
-                       measureLeftMargin ();
 
                        if (parser != null)
                                parser.reparseSource ();
 
+                       measureLeftMargin ();
+
                        updatePrintedLines ();
                        updateMaxScrollY ();
                        RegisterForGraphicUpdate ();
@@ -607,6 +608,7 @@ namespace Crow.Coding
                                        (int)(y + (fe.Ascent + fe.Descent) / 2.0 - foldSize / 2.0), foldSize, foldSize);
 
                                gr.SetSourceColor (Color.Black);
+                               gr.LineWidth = 1.0;
 
                                int level = 0;
                                bool closingNode = false;
@@ -620,9 +622,27 @@ namespace Crow.Coding
                                                level = currentNode.Level - 1;
                                }
 
-                               rFld.Left += level * foldHSpace;
+                               for (int l = 0; l < level; l++) {                                       
+                                       gr.MoveTo (rFld.Center.X + 0.5, y);
+                                       gr.LineTo (rFld.Center.X + 0.5, y + fe.Ascent + fe.Descent);
+                                       rFld.Left += foldHSpace;
+                               }
+                               if (closingNode) {
+                                       gr.MoveTo (rFld.Center.X + 0.5, y);
+                                       gr.LineTo (rFld.Center.X + 0.5, y + fe.Ascent / 2 + 0.5);
+                                       gr.LineTo (rFld.Center.X + 0.5 + foldSize / 2, y + fe.Ascent / 2 + 0.5);
+                                       closingNode = false;
+                               }
+                               gr.SetDash (new double[]{ 1.5 },0.0);
+                               gr.SetSourceColor (Color.Gray);
+                               gr.Stroke ();
+                               gr.SetDash (new double[]{}, 0.0);
 
                                if (cl.IsFoldable) {
+                                       gr.Rectangle (rFld);
+                                       gr.SetSourceColor (Color.White);
+                                       gr.Fill();
+                                       gr.SetSourceColor (Color.Black);
                                        gr.Rectangle (rFld, 1.0);
                                        if (cl.IsFolded) {
                                                gr.MoveTo (rFld.Center.X + 0.5, rFld.Y + 2);
@@ -633,27 +653,7 @@ namespace Crow.Coding
                                        gr.MoveTo (rFld.Left + 2, rFld.Center.Y + 0.5);
                                        gr.LineTo (rFld.Right - 2, rFld.Center.Y + 0.5);
                                        gr.Stroke ();
-
                                } 
-                       
-                               if (closingNode) {
-                                       gr.MoveTo (rFld.Center.X + 0.5, y);
-                                       gr.LineTo (rFld.Center.X + 0.5, y + fe.Ascent / 2 + 0.5);
-                                       gr.LineTo (rFld.Center.X + 0.5 + foldSize / 2, y + fe.Ascent / 2 + 0.5);
-                                       closingNode = false;
-                               }
-
-
-                               while (level > 0) {
-                                       level--;
-                                       rFld.Left -= foldHSpace;
-                                       gr.MoveTo (rFld.Center.X + 0.5, y);
-                                       gr.LineTo (rFld.Center.X + 0.5, y + fe.Ascent + fe.Descent);
-                               }
-                               gr.SetDash (new double[]{ 1.5 },0.0);
-                               gr.Stroke ();
-                               gr.SetDash (new double[]{}, 0.0);
-
                        }
 
                        gr.SetSourceColor (Foreground);
@@ -880,11 +880,14 @@ namespace Crow.Coding
                                int unfoldedLines = buffer.UnfoldedLines;
                                currentNode = null;
                                CodeLine cl = PrintedLines[0];
-                               int li = buffer.IndexOf(cl);
+                               int idx0 = buffer.IndexOf(cl);
+                               int li = idx0-1;
                                while (li >= 0) {
-                                       if (buffer [li].IsFoldable) {
-                                               currentNode = buffer [li].SyntacticNode;
-                                               break;
+                                       if (buffer [li].IsFoldable && !buffer [li].IsFolded) {
+                                               if (buffer.IndexOf(buffer [li].SyntacticNode.EndLine) > idx0){
+                                                       currentNode = buffer [li].SyntacticNode;
+                                                       break;
+                                               }
                                        }
                                        li--;
                                }
index c6b8a3bbcd9c52b8cfd39df0dae7deb4ae501567..8b4df5e57ba8975f72314d94ddb74c6b455fb2c4 100644 (file)
@@ -38,6 +38,7 @@ namespace Crow.Coding
 //                     Content = content;
 //             }
 
+               public bool IsNull { get { return IsEmpty && Type == BufferParser.TokenType.Unknown; }}
                public bool IsEmpty { get { return string.IsNullOrEmpty(Content); }}
 
                public static bool operator == (Token t, System.Enum tt){
index 6f00158705a5089324581b26b54f15999c38b419..ad7aaa62a4cc93e9cba530a38593f29ffb5ceb1e 100644 (file)
@@ -17,8 +17,8 @@ namespace Crow.Coding
                        BlockCommentStart = BufferParser.TokenType.BlockCommentStart,
                        BlockComment = BufferParser.TokenType.BlockComment,
                        BlockCommentEnd = BufferParser.TokenType.BlockCommentEnd,
-                       ElementName = BufferParser.TokenType.Type,
-                       AttributeName = BufferParser.TokenType.Identifier,
+                       ElementName = BufferParser.TokenType.Identifier,
+                       AttributeName = BufferParser.TokenType.Keyword,
                        ElementClosing = BufferParser.TokenType.StatementEnding,
                        Affectation = BufferParser.TokenType.OperatorOrPunctuation,
                        AttributeValueOpening = BufferParser.TokenType.StringLitteralOpening,
@@ -260,6 +260,7 @@ namespace Crow.Coding
                        RootNode = new Node () { Name = "RootNode", Type="Root" };
 
                        Node currentNode = RootNode;
+                       SyntacticTreeDepth = SyntacticTreeMaxDepth = 0;
 
                        for (int i = 0; i < buffer.LineCount; i++) {
                                CodeLine cl = buffer[i];
@@ -277,6 +278,7 @@ namespace Crow.Coding
                                                currentNode = newElt;
                                                if (cl.SyntacticNode == null)
                                                        cl.SyntacticNode = newElt;
+                                               SyntacticTreeDepth++;
                                                break;
                                        case TokenType.ElementEnd:
                                                tokPtr++;
@@ -287,6 +289,7 @@ namespace Crow.Coding
                                                }
                                                currentNode.EndLine = cl;
                                                currentNode = currentNode.Parent;
+                                               SyntacticTreeDepth--;
                                                break;
                                        case TokenType.ElementClosing:
                                                //currentNode = currentNode.Parent;
index bfd3ac9a325f29891ba804a3090918ebcd433c5b..e9a5348601d533bd5dda1afd271a02932929d21d 100644 (file)
@@ -204,6 +204,8 @@ namespace Crow
                        }
 
                        DockWindow dw = IFace.DragAndDropOperation.DragSource as DockWindow;
+                       if (dw == null)
+                               return;
                        if (!dw.IsDocked) {
                                Rectangle cb = ClientRectangle;
                                double minDim = Math.Min (cb.Width, cb.Height);