From d5cf794076899803b9a34eb46d3b2e34f3e3cfbc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Wed, 28 Feb 2018 00:51:17 +0100 Subject: [PATCH] change styling grammar for value now enclose in double quote --- Crow.csproj | 1 + CrowIDE/CrowIDE.csproj | 3 +- CrowIDE/src/Project.cs | 10 +- .../{Parser.cs => BufferParser.cs} | 22 +- CrowIDE/src/SourceEditor/CSharpParser.cs | 6 +- CrowIDE/src/SourceEditor/CodeLine.cs | 4 +- CrowIDE/src/SourceEditor/ParsingException.cs | 22 -- CrowIDE/src/SourceEditor/SourceEditor.cs | 14 +- CrowIDE/src/SourceEditor/StyleParser.cs | 38 ++- CrowIDE/src/SourceEditor/Token.cs | 2 +- CrowIDE/src/SourceEditor/XMLParser.cs | 68 +++--- CrowIDE/ui/IDE.style | 32 +-- Default.style | 220 +++++++++--------- src/ParsingException.cs | 20 ++ src/StyleReader.cs | 220 ++++++++++-------- 15 files changed, 350 insertions(+), 332 deletions(-) rename CrowIDE/src/SourceEditor/{Parser.cs => BufferParser.cs} (92%) delete mode 100644 CrowIDE/src/SourceEditor/ParsingException.cs create mode 100644 src/ParsingException.cs diff --git a/Crow.csproj b/Crow.csproj index 41e556f8..91b16e31 100644 --- a/Crow.csproj +++ b/Crow.csproj @@ -222,6 +222,7 @@ + diff --git a/CrowIDE/CrowIDE.csproj b/CrowIDE/CrowIDE.csproj index b916d716..38adac85 100644 --- a/CrowIDE/CrowIDE.csproj +++ b/CrowIDE/CrowIDE.csproj @@ -110,14 +110,13 @@ - - + diff --git a/CrowIDE/src/Project.cs b/CrowIDE/src/Project.cs index 1cbdecbf..0da5dc19 100644 --- a/CrowIDE/src/Project.cs +++ b/CrowIDE/src/Project.cs @@ -439,10 +439,14 @@ namespace Crow.Coding // } public void GetStyling () { - foreach (ProjectFile pi in flattenNodes.OfType ().Where (pp=>pp.Type == ItemType.EmbeddedResource && pp.Extension == ".style")) { - using (Stream s = new MemoryStream (System.Text.Encoding.UTF8.GetBytes(pi.Source))) { - new StyleReader (solution.Styling, s, pi.ResourceID); + try { + foreach (ProjectFile pi in flattenNodes.OfType ().Where (pp=>pp.Type == ItemType.EmbeddedResource && pp.Extension == ".style")) { + using (Stream s = new MemoryStream (System.Text.Encoding.UTF8.GetBytes(pi.Source))) { + new StyleReader (solution.Styling, s, pi.ResourceID); + } } + } catch (Exception ex) { + Console.WriteLine (ex.ToString ()); } foreach (ProjectReference pr in flattenNodes.OfType()) { Project p = solution.Projects.FirstOrDefault (pp => pp.ProjectGuid == pr.ProjectGUID); diff --git a/CrowIDE/src/SourceEditor/Parser.cs b/CrowIDE/src/SourceEditor/BufferParser.cs similarity index 92% rename from CrowIDE/src/SourceEditor/Parser.cs rename to CrowIDE/src/SourceEditor/BufferParser.cs index f655fa49..87dd779e 100644 --- a/CrowIDE/src/SourceEditor/Parser.cs +++ b/CrowIDE/src/SourceEditor/BufferParser.cs @@ -10,7 +10,7 @@ namespace Crow.Coding /// /// base class for tokenizing sources /// - public abstract class Parser + public abstract class BufferParser { /// /// Default tokens, this enum may be overriden in derived parser with the new keyword, @@ -42,7 +42,7 @@ namespace Crow.Coding } #region CTOR - public Parser (CodeBuffer _buffer) + public BufferParser (CodeBuffer _buffer) { buffer = _buffer; @@ -108,7 +108,7 @@ namespace Crow.Coding // continue; // } // parser.CurrentPosition = tls [fstTK + 1].Start; - // parser.SetLineInError(new ParsingException(parser, "closing tag not corresponding")); + // parser.SetLineInError(new ParserException(parser, "closing tag not corresponding")); // } // // } @@ -123,8 +123,8 @@ namespace Crow.Coding SyntaxAnalysis (); } catch (Exception ex) { Debug.WriteLine ("Syntax Error: " + ex.ToString ()); - if (ex is ParsingException) - SetLineInError (ex as ParsingException); + if (ex is ParserException) + SetLineInError (ex as ParserException); } } public void tryParseBufferLine(int lPtr) { @@ -137,8 +137,8 @@ namespace Crow.Coding ParseCurrentLine (); } catch (Exception ex) { Debug.WriteLine (ex.ToString ()); - if (ex is ParsingException) - SetLineInError (ex as ParsingException); + if (ex is ParserException) + SetLineInError (ex as ParserException); } } @@ -163,7 +163,7 @@ namespace Crow.Coding public abstract void ParseCurrentLine(); public abstract void SyntaxAnalysis (); - public virtual void SetLineInError(ParsingException ex) { + public virtual void SetLineInError(ParserException ex) { currentTok = default(Token); if (ex.Line >= buffer.LineCount) ex.Line = buffer.LineCount - 1; @@ -220,7 +220,7 @@ namespace Crow.Coding /// protected virtual char Peek() { if (eol) - throw new ParsingException (this, "Unexpected End of line"); + throw new ParserException (currentLine, currentColumn, "Unexpected End of line"); return currentColumn < buffer [currentLine].Length ? buffer [currentLine] [currentColumn] : '\n'; } @@ -233,7 +233,7 @@ namespace Crow.Coding /// Length. protected virtual string Peek(int length) { if (eol) - throw new ParsingException (this, "Unexpected End of Line"); + throw new ParserException (currentLine, currentColumn, "Unexpected End of Line"); int lg = Math.Min(length, Math.Max (buffer [currentLine].Length - currentColumn, buffer [currentLine].Length - currentColumn - length)); if (lg == 0) return ""; @@ -287,7 +287,7 @@ namespace Crow.Coding /// protected void SkipWhiteSpaces () { if (currentTok.Type != TokenType.Unknown) - throw new ParsingException (this, "current token should be reset to unknown (0) before skiping white spaces"); + throw new ParserException (currentLine, currentColumn, "current token should be reset to unknown (0) before skiping white spaces"); while (!eol) { if (!char.IsWhiteSpace (Peek ())||Peek()=='\n') break; diff --git a/CrowIDE/src/SourceEditor/CSharpParser.cs b/CrowIDE/src/SourceEditor/CSharpParser.cs index 7d56ce43..8c445824 100644 --- a/CrowIDE/src/SourceEditor/CSharpParser.cs +++ b/CrowIDE/src/SourceEditor/CSharpParser.cs @@ -7,7 +7,7 @@ using System.Linq; namespace Crow.Coding { - public class CSharpParser : Parser + public class CSharpParser : BufferParser { #region keywords string[] keywords = new string[] { @@ -171,7 +171,7 @@ namespace Crow.Coding if (Peek () == '\n') { if (currentTok != TokenType.Unknown) - throw new ParsingException (this, "Unexpected end of line"); + throw new ParserException (currentLine, currentColumn, "Unexpected end of line"); Read (); eol = true; continue; @@ -182,7 +182,7 @@ namespace Crow.Coding Debugger.Break (); currentTok.Start = CurrentPosition; - currentTok.Type = (Parser.TokenType)TokenType.BlockComment; + currentTok.Type = (BufferParser.TokenType)TokenType.BlockComment; currentTok += ReadLineUntil ("*/"); if (Peek (2) == "*/") { readToCurrTok (2); diff --git a/CrowIDE/src/SourceEditor/CodeLine.cs b/CrowIDE/src/SourceEditor/CodeLine.cs index 622584c7..612cac73 100644 --- a/CrowIDE/src/SourceEditor/CodeLine.cs +++ b/CrowIDE/src/SourceEditor/CodeLine.cs @@ -10,7 +10,7 @@ namespace Crow.Coding public List Tokens; public int EndingState = 0; public Node SyntacticNode; - public ParsingException exception; + public ParserException exception; public CodeLine (string _content){ Content = _content; @@ -52,7 +52,7 @@ namespace Crow.Coding } } - public void SetLineInError (ParsingException ex) { + public void SetLineInError (ParserException ex) { Tokens = null; exception = ex; } diff --git a/CrowIDE/src/SourceEditor/ParsingException.cs b/CrowIDE/src/SourceEditor/ParsingException.cs deleted file mode 100644 index 88c51c9b..00000000 --- a/CrowIDE/src/SourceEditor/ParsingException.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -namespace Crow.Coding -{ - public class ParsingException : Exception - { - public int Line; - public int Column; - public ParsingException(Parser parser, string txt) - : base(string.Format("Parser exception ({0},{1}): {2}", parser.currentLine, parser.currentColumn, txt)) - { - Line = parser.currentLine; - Column = parser.currentColumn; - } - public ParsingException(Parser parser, string txt, Exception innerException) - : base(txt, innerException) - { - txt = string.Format("Parser exception ({0},{1}): {2}", parser.currentLine, parser.currentColumn, txt); - } - } -} - diff --git a/CrowIDE/src/SourceEditor/SourceEditor.cs b/CrowIDE/src/SourceEditor/SourceEditor.cs index d594776e..8d8a5d68 100644 --- a/CrowIDE/src/SourceEditor/SourceEditor.cs +++ b/CrowIDE/src/SourceEditor/SourceEditor.cs @@ -58,10 +58,10 @@ namespace Crow.Coding formatting.Add ((int)XMLParser.TokenType.AttributeValue, new TextFormatting (Color.TractorRed, Color.Transparent, false, true)); formatting.Add ((int)XMLParser.TokenType.XMLDecl, new TextFormatting (Color.AoEnglish, Color.Transparent)); - formatting.Add ((int)Parser.TokenType.BlockComment, new TextFormatting (Color.Gray, Color.Transparent, false, true)); - formatting.Add ((int)Parser.TokenType.LineComment, new TextFormatting (Color.Gray, Color.Transparent, false, true)); - formatting.Add ((int)Parser.TokenType.Affectation, new TextFormatting (Color.Black, Color.Transparent)); - formatting.Add ((int)Parser.TokenType.Keyword, new TextFormatting (Color.DarkCyan, Color.Transparent)); + 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.Affectation, new TextFormatting (Color.Black, 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"); @@ -122,7 +122,7 @@ namespace Crow.Coding int printedCurrentLine = 0;//Index of the currentline in the PrintedLines array CodeBuffer buffer; - Parser parser; + BufferParser parser; List PrintedLines;//list of lines visible in the Editor depending on scrolling and folding Dictionary formatting = new Dictionary(); @@ -348,7 +348,7 @@ namespace Crow.Coding } } - Parser getParserFromExt (string extension) { + BufferParser getParserFromExt (string extension) { if (string.IsNullOrEmpty(extension)) return null; if (!parsing.ContainsKey(extension)) @@ -356,7 +356,7 @@ namespace Crow.Coding Type parserType = Type.GetType (parsing [extension]); if (parserType == null) return null; - return (Parser)Activator.CreateInstance (parserType, buffer ); + return (BufferParser)Activator.CreateInstance (parserType, buffer ); } #region Public Crow Properties diff --git a/CrowIDE/src/SourceEditor/StyleParser.cs b/CrowIDE/src/SourceEditor/StyleParser.cs index 9952b267..a4273ede 100644 --- a/CrowIDE/src/SourceEditor/StyleParser.cs +++ b/CrowIDE/src/SourceEditor/StyleParser.cs @@ -7,7 +7,7 @@ using System.Linq; namespace Crow.Coding { - public class StyleParser : Parser + public class StyleParser : BufferParser { enum States { init, classNames, members, value, endOfStatement } @@ -15,15 +15,13 @@ namespace Crow.Coding { } - #region Regular Expression for validity checks - private static Regex rxValidChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}"); - private static Regex rxNameStartChar = new Regex(@"_|\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}"); - private static Regex rxNameChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}"); - private static Regex rxDecimal = new Regex(@"[0-9]+"); - private static Regex rxHexadecimal = new Regex(@"[0-9a-fA-F]+"); - #endregion - #region Character ValidityCheck + static Regex rxValidChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}"); + static Regex rxNameStartChar = new Regex(@"_|\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}"); + static Regex rxNameChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}"); + static Regex rxDecimal = new Regex(@"[0-9]+"); + static Regex rxHexadecimal = new Regex(@"[0-9a-fA-F]+"); + public bool nextCharIsValidCharStartName { get { return rxNameStartChar.IsMatch(new string(new char[]{Peek()})); } @@ -58,7 +56,7 @@ namespace Crow.Coding if (Peek () == '\n') { if (currentTok != TokenType.Unknown) - throw new ParsingException (this, "Unexpected end of line"); + throw new ParserException (currentLine, currentColumn, "Unexpected end of line"); Read (); eol = true; continue; @@ -80,31 +78,31 @@ namespace Crow.Coding break; case ',': if (curState != States.init || curState != States.classNames ) - throw new ParsingException (this, "Unexpected char ','"); + throw new ParserException (currentLine, currentColumn, "Unexpected char ','"); readAndResetCurrentTok (TokenType.UnaryOp, true); curState = States.classNames; break; case '{': if (!(curState == States.init || curState == States.classNames)) - throw new ParsingException (this, "Unexpected char '{'"); + throw new ParserException (currentLine, currentColumn, "Unexpected char '{'"); readAndResetCurrentTok (TokenType.OpenBlock, true); curState = States.members; break; case '}': if (curState != States.members) - throw new ParsingException (this, "Unexpected char '}'"); + throw new ParserException (currentLine, currentColumn, "Unexpected char '}'"); readAndResetCurrentTok (TokenType.CloseBlock, true); curState = States.classNames; break; case '=': if (curState == States.classNames) - throw new ParsingException (this, "Unexpected char '='"); + throw new ParserException (currentLine, currentColumn, "Unexpected char '='"); readAndResetCurrentTok (TokenType.Affectation, true); curState = States.value; break; case '"': if (curState != States.value) - throw new ParsingException (this, "Unexpected char '\"'"); + throw new ParserException (currentLine, currentColumn, "Unexpected char '\"'"); readAndResetCurrentTok (TokenType.StringLitteralOpening, true); while (!eol) { @@ -115,7 +113,7 @@ namespace Crow.Coding break; } if (eol) - throw new ParsingException (this, "Unexpected end of line"); + throw new ParserException (currentLine, currentColumn, "Unexpected end of line"); saveAndResetCurrentTok (TokenType.StringLitteral); readAndResetCurrentTok (TokenType.StringLitteralClosing, true); @@ -123,17 +121,17 @@ namespace Crow.Coding break; case ';': if (curState != States.endOfStatement) - throw new ParsingException (this, "Unexpected end of statement"); + throw new ParserException (currentLine, currentColumn, "Unexpected end of statement"); readAndResetCurrentTok (TokenType.StatementEnding, true); curState = States.members; break; default: if (currentTok.Type != TokenType.Unknown) - throw new ParsingException (this, "error curtok not null"); + throw new ParserException (currentLine, currentColumn, "error curtok not null"); if (curState == States.value) - throw new ParsingException (this, "expecting value enclosed in '\"'"); + throw new ParserException (currentLine, currentColumn, "expecting value enclosed in '\"'"); if (curState == States.endOfStatement) - throw new ParsingException (this, "expecting end of statement"); + throw new ParserException (currentLine, currentColumn, "expecting end of statement"); if (nextCharIsValidCharStartName) { readToCurrTok (true); diff --git a/CrowIDE/src/SourceEditor/Token.cs b/CrowIDE/src/SourceEditor/Token.cs index 36f0242f..c6b8a3bb 100644 --- a/CrowIDE/src/SourceEditor/Token.cs +++ b/CrowIDE/src/SourceEditor/Token.cs @@ -24,7 +24,7 @@ namespace Crow.Coding { public struct Token { - public Parser.TokenType Type; + public BufferParser.TokenType Type; public string Content; public Point Start; public Point End; diff --git a/CrowIDE/src/SourceEditor/XMLParser.cs b/CrowIDE/src/SourceEditor/XMLParser.cs index 952e038b..59601a75 100644 --- a/CrowIDE/src/SourceEditor/XMLParser.cs +++ b/CrowIDE/src/SourceEditor/XMLParser.cs @@ -7,24 +7,24 @@ using System.Linq; namespace Crow.Coding { - public class XMLParser : Parser + public class XMLParser : BufferParser { public new enum TokenType { - Unknown = Parser.TokenType.Unknown, - WhiteSpace = Parser.TokenType.WhiteSpace, - NewLine = Parser.TokenType.NewLine, - LineComment = Parser.TokenType.LineComment, - BlockCommentStart = Parser.TokenType.BlockCommentStart, - BlockComment = Parser.TokenType.BlockComment, - BlockCommentEnd = Parser.TokenType.BlockCommentEnd, - ElementName = Parser.TokenType.Type, - AttributeName = Parser.TokenType.Identifier, - ElementClosing = Parser.TokenType.StatementEnding, - Affectation = Parser.TokenType.Affectation, - AttributeValueOpening = Parser.TokenType.StringLitteralOpening, - AttributeValueClosing = Parser.TokenType.StringLitteralClosing, - AttributeValue = Parser.TokenType.StringLitteral, - XMLDecl = Parser.TokenType.Preprocessor, + Unknown = BufferParser.TokenType.Unknown, + WhiteSpace = BufferParser.TokenType.WhiteSpace, + NewLine = BufferParser.TokenType.NewLine, + LineComment = BufferParser.TokenType.LineComment, + BlockCommentStart = BufferParser.TokenType.BlockCommentStart, + BlockComment = BufferParser.TokenType.BlockComment, + BlockCommentEnd = BufferParser.TokenType.BlockCommentEnd, + ElementName = BufferParser.TokenType.Type, + AttributeName = BufferParser.TokenType.Identifier, + ElementClosing = BufferParser.TokenType.StatementEnding, + Affectation = BufferParser.TokenType.Affectation, + AttributeValueOpening = BufferParser.TokenType.StringLitteralOpening, + AttributeValueClosing = BufferParser.TokenType.StringLitteralClosing, + AttributeValue = BufferParser.TokenType.StringLitteral, + XMLDecl = BufferParser.TokenType.Preprocessor, ElementStart = 50, ElementEnd = 51, } @@ -82,7 +82,7 @@ namespace Crow.Coding } #endregion - public override void SetLineInError (ParsingException ex) + public override void SetLineInError (ParserException ex) { base.SetLineInError (ex); //buffer[ex.Line].Tokens.EndingState = (int)States.init; @@ -111,7 +111,7 @@ namespace Crow.Coding if (Peek () == '\n') { if (currentTok != TokenType.Unknown) - throw new ParsingException (this, "Unexpected end of line"); + throw new ParserException (currentLine, currentColumn, "Unexpected end of line"); Read (); eol = true; continue; @@ -122,7 +122,7 @@ namespace Crow.Coding Debugger.Break (); currentTok.Start = CurrentPosition; - currentTok.Type = (Parser.TokenType)TokenType.BlockComment; + currentTok.Type = (BufferParser.TokenType)TokenType.BlockComment; currentTok += ReadLineUntil ("-->"); if (Peek (3) == "-->") { readToCurrTok (3); @@ -138,11 +138,11 @@ namespace Crow.Coding switch (Peek()) { case '?': if (curState != States.init) - throw new ParsingException (this, "xml decl may appear only on first line"); + throw new ParserException (currentLine, currentColumn, "xml decl may appear only on first line"); readToCurrTok (); currentTok += ReadLineUntil ("?>"); if (Peek (2) != "?>") - throw new ParsingException (this, "expecting '?>'"); + throw new ParserException (currentLine, currentColumn, "expecting '?>'"); readToCurrTok (2); saveAndResetCurrentTok (TokenType.XMLDecl); curState = States.prolog; @@ -153,7 +153,7 @@ namespace Crow.Coding case '-': readToCurrTok (); if (Peek () != '-') - throw new ParsingException (this, "Expecting comment start tag"); + throw new ParserException (currentLine, currentColumn, "Expecting comment start tag"); readToCurrTok (); currentTok += ReadLineUntil ("--"); if (Peek (3) == "-->") { @@ -163,12 +163,12 @@ namespace Crow.Coding saveAndResetCurrentTok (TokenType.BlockComment); break; default: - throw new ParsingException(this, "error"); + throw new ParserException (currentLine, currentColumn, "error"); } break; default: if (!(curState == States.Content || curState == States.XML || curState == States.init || curState == States.prolog)) - throw new ParsingException (this, "Unexpected char: '<'"); + throw new ParserException (currentLine, currentColumn, "Unexpected char: '<'"); if (Peek () == '/') { curState = States.EndTag; readToCurrTok (); @@ -179,7 +179,7 @@ namespace Crow.Coding } if (!nextCharIsValidCharStartName) - throw new ParsingException (this, "Expected element name"); + throw new ParserException (currentLine, currentColumn, "Expected element name"); readToCurrTok (true); while (nextCharIsValidCharName) @@ -191,10 +191,10 @@ namespace Crow.Coding break; case '/': if (curState != States.StartTag) - throw new ParsingException (this, "Unexpected char: '/'"); + throw new ParserException (currentLine, currentColumn, "Unexpected char: '/'"); readToCurrTok (true); if (Peek () != '>') - throw new ParsingException (this, "Expecting '>'"); + throw new ParserException (currentLine, currentColumn, "Expecting '>'"); readAndResetCurrentTok (TokenType.ElementEnd); curState = States.XML; @@ -209,14 +209,14 @@ namespace Crow.Coding curState = States.Content; break; default: - throw new ParsingException (this, "Unexpected char: '>'"); + throw new ParserException (currentLine, currentColumn, "Unexpected char: '>'"); } break; default: switch (curState) { case States.StartTag: if (!nextCharIsValidCharStartName) - throw new ParsingException (this, "Expected attribute name"); + throw new ParserException (currentLine, currentColumn, "Expected attribute name"); readToCurrTok (true); while (nextCharIsValidCharName) readToCurrTok (); @@ -225,14 +225,14 @@ namespace Crow.Coding SkipWhiteSpaces (); if (Peek () != '=') - throw new ParsingException (this, "Expecting: '='"); + throw new ParserException (currentLine, currentColumn, "Expecting: '='"); readAndResetCurrentTok (TokenType.Affectation, true); SkipWhiteSpaces (); char openAttVal = Peek (); if (openAttVal != '"' && openAttVal != '\'') - throw new ParsingException (this, "Expecting attribute value enclosed either in '\"' or in \"'\""); + throw new ParserException (currentLine, currentColumn, "Expecting attribute value enclosed either in '\"' or in \"'\""); readAndResetCurrentTok (TokenType.AttributeValueOpening, true); currentTok.Start = CurrentPosition; @@ -240,11 +240,11 @@ namespace Crow.Coding saveAndResetCurrentTok (TokenType.AttributeValue); if (Peek () != openAttVal) - throw new ParsingException (this, string.Format ("Expecting {0}", openAttVal)); + throw new ParserException (currentLine, currentColumn, string.Format ("Expecting {0}", openAttVal)); readAndResetCurrentTok (TokenType.AttributeValueClosing, true); break; default: - throw new ParsingException (this, "unexpected char: " + Peek ()); + throw new ParserException (currentLine, currentColumn, "unexpected char: " + Peek ()); } break; } @@ -283,7 +283,7 @@ namespace Crow.Coding if (tokPtr < cl.Tokens.Count) { if ((XMLParser.TokenType)cl.Tokens [tokPtr].Type == TokenType.ElementName && cl.Tokens [tokPtr].Content != currentNode.Name) - throw new ParsingException (this, "Closing tag mismatch"); + throw new ParserException (currentLine, currentColumn, "Closing tag mismatch"); } currentNode.EndLine = cl; currentNode = currentNode.Parent; diff --git a/CrowIDE/ui/IDE.style b/CrowIDE/ui/IDE.style index d7212053..ed964dca 100644 --- a/CrowIDE/ui/IDE.style +++ b/CrowIDE/ui/IDE.style @@ -1,25 +1,25 @@ icon { - Width=14; - Height=14; + Width="14"; + Height="14"; } MemberViewLabel { - Margin=1; - Height=Fit; - Width=50%; - Background=White; + Margin="1"; + Height="Fit"; + Width="50%"; + Background="White"; } MemberViewHStack { - Focusable=true; - Height=Fit; - Spacing=1; - MouseEnter={Background=UnitedNationsBlue}; - MouseLeave={Background=Transparent}; + Focusable="true"; + Height="Fit"; + Spacing="1"; + MouseEnter="{Background=UnitedNationsBlue}"; + MouseLeave="{Background=Transparent}"; } IcoBut { - Template = #Crow.Coding.ui.IcoBut.template; - MinimumSize = 10,10; - Width = 8; - Height = 14; - Background = White; + Template = "#Crow.Coding.ui.IcoBut.template"; + MinimumSize = "10,10"; + Width = "8"; + Height = "14"; + Background = "White"; } \ No newline at end of file diff --git a/Default.style b/Default.style index 11a22191..2e9e72a1 100644 --- a/Default.style +++ b/Default.style @@ -1,184 +1,184 @@ Button, CheckBox, RadioButton, ComboBox, Expandable, MessageBox, Popper, Slider, Spinner, TextBox { - Focusable = true; - Height = Fit; + Focusable = "true"; + Height = "Fit"; } Border { - Foreground = Gray; + Foreground = "Gray"; } -CheckBox { Caption = CheckBox; } -RadioButton { Caption = RadioButton; } -Expandable { Caption = Expandable; } -Popper { Caption = Popper;} -GroupBox { Caption = Group Box; } +CheckBox { Caption = "CheckBox"; } +RadioButton { Caption = "RadioButton"; } +Expandable { Caption = "Expandable"; } +Popper { Caption = "Popper";} +GroupBox { Caption = "Group Box"; } ControlBorder { - BorderWidth = 1; - Foreground = Jet; - Background = Transparent; + BorderWidth = "1"; + Foreground = "Jet"; + Background = "Transparent"; } ControlCaption { - Foreground = Gray; - MouseEnter = {Foreground=White}; - MouseLeave = {Foreground=Gray}; + Foreground = "Gray"; + MouseEnter = "{Foreground=White}"; + MouseLeave = "{Foreground=Gray}"; } Icon { - Margin=1; - Width=12; - Height=12; + Margin = "1"; + Width = "12"; + Height = "12"; } Wrapper { - Orientation = Vertical; + Orientation = "Vertical"; } Button { - Caption = Button; - Width = Fit; + Caption = "Button"; + Width = "Fit"; } Label { - Height = Fit; - Width = Fit; - Margin = 0; + Height = "Fit"; + Width = "Fit"; + Margin = "0"; } Menu { - Margin = 1; - Background = vgradient|0:DimGray|1:Onyx; - Height = Fit; - Width = Stretched; - VerticalAlignment = Top; - SelectionBackground = Transparent; + Margin = "1"; + Background = "vgradient|0:DimGray|1:Onyx"; + Height = "Fit"; + Width = "Stretched"; + VerticalAlignment = "Top"; + SelectionBackground = "Transparent"; } MenuItem { - Caption = MenuItem; - Width = Stretched; - Height = Fit; - Background = Transparent; - Foreground = LightGray; - MouseEnter = {Background = vgradient|0:UnitedNationsBlue|1:Onyx;Foreground=White;} - MouseLeave = {Foreground=LightGray;Background=Transparent;} - SelectionBackground = Transparent; + Caption = "MenuItem"; + Width = "Stretched"; + Height = "Fit"; + Background = "Transparent"; + Foreground = "LightGray"; + MouseEnter = "{Background = vgradient|0:UnitedNationsBlue|1:Onyx;Foreground=White;}"; + MouseLeave = "{Foreground=LightGray;Background=Transparent;}"; + SelectionBackground = "Transparent"; } Docker { - AllowDrop = true; + AllowDrop = "true"; } DockWindow { - AllowDrag = true; + AllowDrag = "true"; } MessageBox { - Background = 0.3,0.3,0.3,0.3; - Width = Fit; - Title=MessageBox; - Font = serif, 12; - MinimumSize = 200,120; - AlwaysOnTop = true; + Background = "0.3,0.3,0.3,0.3"; + Width = "Fit"; + Caption="MessageBox"; + Font = "serif, 12"; + MinimumSize = "200,120"; + AlwaysOnTop = "true"; } Slider { - Background = vgradient|0:Black|0.1:Gray|0.9:Gray|1:LightGray; - Foreground = Gray; - Width = Fit; + Background = "vgradient|0:Black|0.1:Gray|0.9:Gray|1:LightGray"; + Foreground = "Gray"; + Width = "Fit"; } Splitter { - Focusable = true; - Background = DimGray; + Focusable = "true"; + Background = "DimGray"; } Spinner { - Foreground = DimGray; + Foreground = "DimGray"; } TabView { - CacheEnabled = false; + CacheEnabled = "false"; } TabItem { - Caption = TabItem; - Focusable = true; - CacheEnabled = false; + Caption = "TabItem"; + Focusable = "true"; + CacheEnabled = "false"; } TextBox { - Background = White; - Foreground = Black; - Selectable = True; - Text = TextBox; - Margin = 1; + Background = "White"; + Foreground = "Black"; + Selectable = "True"; + Text = "TextBox"; + Margin = "1"; } Window { - Caption = Window; - Focusable = true; - MinimumSize=5,5; - Width = 150; - Height = 150; + Caption = "Window"; + Focusable = "true"; + MinimumSize="5,5"; + Width = "150"; + Height = "150"; } ToolWindow { - Caption = Window; - Template = #Crow.ToolWindow.template; - Focusable = true; - MinimumSize=50,50; - Width = 150; - Height = 150; + Caption = "Window"; + Template = "#Crow.ToolWindow.template"; + Focusable = "true"; + MinimumSize="50,50"; + Width = "150"; + Height = "150"; } DocksView { - AllowDrop = true; + AllowDrop = "true"; } DockingView { - Focusable = true; - AllowDrag = true; + Focusable = "true"; + AllowDrag = "true"; } FileDialog { - Template = #Crow.FileDialog.template; - AlwaysOnTop = true; - Focusable = true; - MinimumSize=50,50; - Width = 500; - Height = 300; + Template = "#Crow.FileDialog.template"; + AlwaysOnTop = "true"; + Focusable = "true"; + MinimumSize="50,50"; + Width = "500"; + Height = "300"; } ProgressBar { - Foreground = vgradient|0:BlueCrayola|0.5:SkyBlue|1:BlueCrayola; + Foreground = "vgradient|0:BlueCrayola|0.5:SkyBlue|1:BlueCrayola"; } ScrollBar { - Maximum = 0; - Value = 0; + Maximum = "0"; + Value = "0"; } Scroller { - CacheEnabled = false; + CacheEnabled = "false"; } Control { - Margin=0; - Spacing=3; + Margin="0"; + Spacing="3"; } SaturationValueSelector { - Foreground=Red; + Foreground="Red"; } HueSelector { - ClipToClientRect=False; + ClipToClientRect="False"; } ColorSpinner { - Minimum = 0; - Maximum = 255; - SmallIncrement = 1; + Minimum = "0"; + Maximum = "255"; + SmallIncrement = "1"; } HSVSpinner { - Minimum = 0; - Maximum = 1; - SmallIncrement = 0.01; + Minimum = "0"; + Maximum = "1"; + SmallIncrement = "0.01"; } TxtInFileDialog { - Margine = 1; - Font = droid, 12; + Margine = "1"; + Font = "droid, 12"; } CheckBoxAlt { - Template= #Crow.Templates.CheckBox2.template; - Background = Transparent; - Checked={Background=DarkSlateGray;Foreground=LightGray;}; - Unchecked = {Background=Transparent;Foreground=DimGray;}; + Template= "#Crow.Templates.CheckBox2.template"; + Background = "Transparent"; + Checked="{Background=DarkSlateGray;Foreground=LightGray;}"; + Unchecked = "{Background=Transparent;Foreground=DimGray;}"; } ArrowBut { - MouseRepeat=true; - Height=Fit; - Width=Fit; - Focusable=true; - Foreground=Jet; - Background=hgradient|0:Gray|1:Jet; - MouseDown={Background=hgradient|0:White|0.4:BlueCrayola|1:Jet}; - MouseUp={Background=hgradient|0:Gray|1:Jet}; - MouseEnter={Foreground=Black}; - MouseLeave={Foreground=Jet}; + MouseRepeat="true"; + Height="Fit"; + Width="Fit"; + Focusable="true"; + Foreground="Jet"; + Background="hgradient|0:Gray|1:Jet"; + MouseDown="{Background=hgradient|0:White|0.4:BlueCrayola|1:Jet}"; + MouseUp="{Background=hgradient|0:Gray|1:Jet}"; + MouseEnter="{Foreground=Black}"; + MouseLeave="{Foreground=Jet}"; } \ No newline at end of file diff --git a/src/ParsingException.cs b/src/ParsingException.cs new file mode 100644 index 00000000..e3bd51c9 --- /dev/null +++ b/src/ParsingException.cs @@ -0,0 +1,20 @@ +using System; + +namespace Crow.Coding +{ + public class ParserException : Exception + { + public int Line; + public int Column; + public ParserException(int line, int column, string txt) + : base(string.Format("Parser exception ({0},{1}): {2}", line, column, txt)) + { + Line = line; + Column = column; + } + public ParserException(int line, int column, string txt, Exception innerException) + : base(string.Format("Parser exception ({0},{1}): {2}", line, column, txt), innerException) + {} + } +} + diff --git a/src/StyleReader.cs b/src/StyleReader.cs index 5a00a594..28eaf780 100644 --- a/src/StyleReader.cs +++ b/src/StyleReader.cs @@ -28,6 +28,8 @@ using System; using System.Collections.Generic; using System.IO; using System.Reflection; +using System.Text.RegularExpressions; +using Crow.Coding; namespace Crow { @@ -37,12 +39,49 @@ namespace Crow //TODO: style key shared by different class may use only first encouneter class setter, which can cause bug. public class StyleReader : StreamReader { - enum readerState { classNames, propertyName, expression } - readerState state = readerState.classNames; + enum States { init, classNames, members, value, endOfStatement } + + States curState = States.init; + string resourceId; int column = 1; int line = 1; + #region Character ValidityCheck + static Regex rxValidChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}"); + static Regex rxNameStartChar = new Regex(@"_|\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}"); + static Regex rxNameChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}"); + static Regex rxDecimal = new Regex(@"[0-9]+"); + static Regex rxHexadecimal = new Regex(@"[0-9a-fA-F]+"); + + public bool nextCharIsValidCharStartName + { + get { return rxNameStartChar.IsMatch(new string(new char[]{PeekChar()})); } + } + public bool nextCharIsValidCharName + { + get { return rxNameChar.IsMatch(new string(new char[]{PeekChar()})); } + } + #endregion + + char ReadChar () { + column++; + return (Char)Read(); + } + char PeekChar () { + return (Char)Peek(); + } + void SkipWhiteSpaceAndLineBreak (){ + while (!EndOfStream){ + if (!PeekChar ().IsWhiteSpaceOrNewLine ()) + break; + if (ReadChar () == '\n') { + line++; + column = 0; + } + } + } + public StyleReader (Dictionary styling, Stream stream, string resId) : base(stream) { @@ -52,116 +91,95 @@ namespace Crow List targetsClasses = new List (); string currentProperty = ""; - int curlyBracketCount = 0; - while (!EndOfStream) { - char c = (Char)Read (); - if (c == '/' && !EndOfStream) { - if ((char)Peek () == '/') {//process comment, skip until newline - ReadLine (); - continue; - } - } - switch (state) { - case readerState.classNames: - if (c.IsWhiteSpaceOrNewLine () || c == ',' || c == '{') { - if (!string.IsNullOrEmpty (token)) - targetsClasses.Add (token); - if (c == '{') - state = readerState.propertyName; - token = ""; - }else if (c=='='){ - //this file contains only properties, - //resource Id (minus .style extention) will determine the single target class - if (targetsClasses.Count > 1) - throwParserException ("Unexpected token '='"); - else if (targetsClasses.Count == 1) { - if (!string.IsNullOrEmpty (token)) - throwParserException ("Unexpected token '='"); - currentProperty = targetsClasses [0]; - targetsClasses [0] = styleKey; - }else{ - if (string.IsNullOrEmpty (token)) - throwParserException ("Unexpected token '='"); - targetsClasses.Add (styleKey); - currentProperty = token; - token = ""; - } - state = readerState.expression; - }else - token += c; + SkipWhiteSpaceAndLineBreak (); + if (EndOfStream) break; - case readerState.propertyName: - if (c.IsWhiteSpaceOrNewLine () || c == '=') { - if (!string.IsNullOrEmpty (token)) - currentProperty = token; - if (c == '=') - state = readerState.expression; - token = ""; - }else if (c == '}'){ - if (!string.IsNullOrEmpty (token)) - throwParserException ("Unexpected token '" + c + "'"); - targetsClasses = new List (); - currentProperty = ""; - state = readerState.classNames; - } else - token += c; + switch (Peek()) { + case '/': + ReadChar (); + if (PeekChar () != '/') + throw new ParserException (line, column, "Unexpected char '/'"); + ReadLine (); + break; + case ',': + ReadChar (); + if (!(curState == States.init || curState == States.classNames) || string.IsNullOrEmpty (token)) + throw new ParserException (line, column, "Unexpected char ','"); + targetsClasses.Add (token); + token = ""; + curState = States.classNames; + break; + case '{': + ReadChar (); + if (!(curState == States.init || curState == States.classNames) || string.IsNullOrEmpty (token)) + throw new ParserException (line, column, "Unexpected char '{'"); + targetsClasses.Add (token); + token = ""; + curState = States.members; + break; + case '}': + ReadChar (); + if (curState != States.members) + throw new ParserException (line, column, "Unexpected char '}'"); + curState = States.classNames; + targetsClasses.Clear (); + break; + case '=': + ReadChar (); + if (!(curState == States.init || curState == States.members)) + throw new ParserException (line, column, "Unexpected char '='"); + currentProperty = token; + token = ""; + curState = States.value; break; - case readerState.expression: - bool expressionIsFinished = false; - if (curlyBracketCount == 0) { - if (c == '{'){ - if (!string.IsNullOrEmpty(token.Trim())) - throwParserException ("Unexpected token '{'"); - curlyBracketCount++; - token = "{"; - }else if (c == '}') - throwParserException ("Unexpected token '{'"); - else if (c == ';') { - expressionIsFinished = true; - } else - token += c; - } else { - if (c == '{') - curlyBracketCount++; - else if (c == '}') { - curlyBracketCount--; - if (curlyBracketCount == 0) - expressionIsFinished = true; + case '"': + if (curState != States.value) + throw new ParserException (line, column, "Unexpected char '\"'"); + ReadChar (); + + while (!EndOfStream) { + char c = PeekChar(); + if (c == '\"') { + ReadChar (); + break; } - token += c; + token += ReadChar(); + if (c == '\\' && !EndOfStream) + token += ReadChar(); + } + curState = States.endOfStatement; + break; + case ';': + if (curState != States.endOfStatement) + throw new ParserException (line, column, "Unexpected end of statement"); + ReadChar (); + foreach (string tc in targetsClasses) { + if (!styling.ContainsKey (tc)) + styling [tc] = new Style (); + else if (styling [tc].ContainsKey (currentProperty)) + continue; + styling [tc] [currentProperty] = token; + System.Diagnostics.Debug.WriteLine ("Style: {0}.{1} = {2}", tc, currentProperty, token); } - if (expressionIsFinished) { - if (!string.IsNullOrEmpty (token)) { - string expression = token.Trim (); + token = ""; + curState = States.members; + break; + default: + if (curState == States.value) + throw new ParserException (line, column, "expecting value enclosed in '\"'"); + if (curState == States.endOfStatement) + throw new ParserException (line, column, "expecting end of statement"); - foreach (string tc in targetsClasses) { - if (!styling.ContainsKey (tc)) - styling [tc] = new Style (); - else if (styling [tc].ContainsKey (currentProperty)) - continue; - styling [tc] [currentProperty] = expression; - } - token = ""; - } - //allow omiting ';' if curly bracket close expression - while (!EndOfStream) { - if (Char.IsWhiteSpace((char)Peek())) - Read(); - else - break; - } - if (this.Peek () == ';') - this.Read (); - state = readerState.propertyName; + if (nextCharIsValidCharStartName) { + token += ReadChar(); + while (nextCharIsValidCharName) + token += ReadChar(); } break; } } - - if (curlyBracketCount > 0) - throwParserException ("Unexpected end of file"); } public override int Read () -- 2.47.3