<Compile Include="src\DragDropEventArgs.cs" />
<Compile Include="src\GraphicObjects\Docker.cs" />
<Compile Include="src\GraphicObjects\DockWindow.cs" />
+ <Compile Include="src\ParsingException.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Compile Include="src\SourceEditor\CodeLine.cs" />
<Compile Include="src\SourceEditor\CSharpParser.cs" />
<Compile Include="src\SourceEditor\Node.cs" />
- <Compile Include="src\SourceEditor\Parser.cs" />
- <Compile Include="src\SourceEditor\ParsingException.cs" />
<Compile Include="src\SourceEditor\SourceEditor.cs" />
<Compile Include="src\SourceEditor\TextFormatting.cs" />
<Compile Include="src\SourceEditor\Token.cs" />
<Compile Include="src\SourceEditor\XMLParser.cs" />
<Compile Include="src\SourceEditor\StyleParser.cs" />
<Compile Include="src\PropertyContainer.cs" />
+ <Compile Include="src\SourceEditor\BufferParser.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="ui\" />
// }
public void GetStyling () {
- foreach (ProjectFile pi in flattenNodes.OfType<ProjectFile> ().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<ProjectFile> ().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<ProjectReference>()) {
Project p = solution.Projects.FirstOrDefault (pp => pp.ProjectGuid == pr.ProjectGUID);
--- /dev/null
+using System;
+using System.IO;
+using Crow;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+
+namespace Crow.Coding
+{
+ /// <summary>
+ /// base class for tokenizing sources
+ /// </summary>
+ public abstract class BufferParser
+ {
+ /// <summary>
+ /// Default tokens, this enum may be overriden in derived parser with the new keyword,
+ /// see XMLParser for example.
+ /// </summary>
+ public enum TokenType {
+ Unknown = 0,
+ WhiteSpace = 1,
+ NewLine = 2,
+ LineComment = 3,
+ BlockCommentStart = 4,
+ BlockComment = 5,
+ BlockCommentEnd = 6,
+ Type = 7,
+ Identifier = 8,
+ Indexer = 9,
+ OpenBlock = 10,
+ CloseBlock = 11,
+ StatementEnding = 12,
+ UnaryOp = 13,
+ BinaryOp = 14,
+ Affectation = 15,
+ StringLitteralOpening = 16,
+ StringLitteralClosing = 17,
+ StringLitteral = 18,
+ NumericLitteral = 19,
+ Preprocessor = 20,
+ Keyword = 21,
+ }
+
+ #region CTOR
+ public BufferParser (CodeBuffer _buffer)
+ {
+ buffer = _buffer;
+
+ buffer.LineUpadateEvent += Buffer_LineUpadateEvent;
+ //buffer.LineAdditionEvent += Buffer_LineAdditionEvent;;
+ buffer.LineRemoveEvent += Buffer_LineRemoveEvent;
+ buffer.BufferCleared += Buffer_BufferCleared;
+ }
+
+ #endregion
+
+ #region Buffer events handlers
+ void Buffer_BufferCleared (object sender, EventArgs e)
+ {
+
+ }
+ void Buffer_LineAdditionEvent (object sender, CodeBufferEventArgs e)
+ {
+
+ }
+ void Buffer_LineRemoveEvent (object sender, CodeBufferEventArgs e)
+ {
+ reparseSource ();
+ }
+ void Buffer_LineUpadateEvent (object sender, CodeBufferEventArgs e)
+ {
+ for (int i = 0; i < e.LineCount; i++)
+ tryParseBufferLine (e.LineStart + i);
+ reparseSource ();
+ }
+ #endregion
+
+ void updateFolding () {
+ // Stack<TokenList> foldings = new Stack<TokenList>();
+ // bool inStartTag = false;
+ //
+ // for (int i = 0; i < parser.Tokens.Count; i++) {
+ // TokenList tl = parser.Tokens [i];
+ // tl.foldingTo = null;
+ // int fstTK = tl.FirstNonBlankTokenIndex;
+ // if (fstTK > 0 && fstTK < tl.Count - 1) {
+ // if (tl [fstTK + 1] != XMLParser.TokenType.ElementName)
+ // continue;
+ // if (tl [fstTK] == XMLParser.TokenType.ElementStart) {
+ // //search closing tag
+ // int tkPtr = fstTK+2;
+ // while (tkPtr < tl.Count) {
+ // if (tl [tkPtr] == XMLParser.TokenType.ElementClosing)
+ //
+ // tkPtr++;
+ // }
+ // if (tl.EndingState == (int)XMLParser.States.Content)
+ // foldings.Push (tl);
+ // else if (tl.EndingState == (int)XMLParser.States.StartTag)
+ // inStartTag = true;
+ // continue;
+ // }
+ // if (tl [fstTK] == XMLParser.TokenType.ElementEnd) {
+ // TokenList tls = foldings.Pop ();
+ // int fstTKs = tls.FirstNonBlankTokenIndex;
+ // if (tls [fstTK + 1].Content == tl [fstTK + 1].Content) {
+ // tl.foldingTo = tls;
+ // continue;
+ // }
+ // parser.CurrentPosition = tls [fstTK + 1].Start;
+ // parser.SetLineInError(new ParserException(parser, "closing tag not corresponding"));
+ // }
+ //
+ // }
+ // }
+ }
+ public void reparseSource () {
+ for (int i = 0; i < buffer.LineCount; i++) {
+ if (!buffer[i].IsParsed)
+ tryParseBufferLine (i);
+ }
+ try {
+ SyntaxAnalysis ();
+ } catch (Exception ex) {
+ Debug.WriteLine ("Syntax Error: " + ex.ToString ());
+ if (ex is ParserException)
+ SetLineInError (ex as ParserException);
+ }
+ }
+ public void tryParseBufferLine(int lPtr) {
+ buffer [lPtr].exception = null;
+ currentLine = lPtr;
+ currentColumn = 0;
+ eol = false;
+
+ try {
+ ParseCurrentLine ();
+ } catch (Exception ex) {
+ Debug.WriteLine (ex.ToString ());
+ if (ex is ParserException)
+ SetLineInError (ex as ParserException);
+ }
+
+ }
+
+ protected CodeBuffer buffer;
+
+ internal int currentLine = 0;
+ internal int currentColumn = 0;
+ protected Token currentTok;
+ protected bool eol = true;
+
+ public Node RootNode;
+
+ protected Point CurrentPosition {
+ get { return new Point (currentLine, currentColumn); }
+ set {
+ currentLine = value.Y;
+ currentColumn = value.X;
+ }
+ }
+
+ public abstract void ParseCurrentLine();
+ public abstract void SyntaxAnalysis ();
+
+ public virtual void SetLineInError(ParserException ex) {
+ currentTok = default(Token);
+ if (ex.Line >= buffer.LineCount)
+ ex.Line = buffer.LineCount - 1;
+ if (buffer [ex.Line].IsFolded)
+ buffer.ToogleFolding (ex.Line);
+ buffer [ex.Line].SetLineInError (ex);
+ }
+
+ #region low level parsing
+ /// <summary>
+ /// Read one char from current position in buffer and store it into the current token
+ /// </summary>
+ /// <param name="startOfTok">if true, set the Start position of the current token to the current position</param>
+ protected void readToCurrTok(bool startOfTok = false){
+ if (startOfTok)
+ currentTok.Start = CurrentPosition;
+ currentTok += Read();
+ }
+ /// <summary>
+ /// read n char from the buffer and store it into the current token
+ /// </summary>
+ protected void readToCurrTok(int length) {
+ for (int i = 0; i < length; i++)
+ currentTok += Read ();
+ }
+ /// <summary>
+ /// Save current token into current TokensLine and raz current token
+ /// </summary>
+ protected void saveAndResetCurrentTok() {
+ currentTok.End = CurrentPosition;
+ buffer[currentLine].Tokens.Add (currentTok);
+ currentTok = default(Token);
+ }
+ /// <summary>
+ /// read one char and add current token to current TokensLine, current token is reset
+ /// </summary>
+ /// <param name="type">Type of the token</param>
+ /// <param name="startToc">set start of token to current position</param>
+ protected void readAndResetCurrentTok(System.Enum type, bool startToc = false) {
+ readToCurrTok ();
+ saveAndResetCurrentTok (type);
+ }
+ /// <summary>
+ /// Save current tok
+ /// </summary>
+ /// <param name="type">set the type of the tok</param>
+ protected void saveAndResetCurrentTok(System.Enum type) {
+ currentTok.Type = (TokenType)type;
+ saveAndResetCurrentTok ();
+ }
+ /// <summary>
+ /// Peek next char, emit '\n' if current column > buffer's line length
+ /// Throw error if eof is true
+ /// </summary>
+ protected virtual char Peek() {
+ if (eol)
+ throw new ParserException (currentLine, currentColumn, "Unexpected End of line");
+ return currentColumn < buffer [currentLine].Length ?
+ buffer [currentLine] [currentColumn] : '\n';
+ }
+ /// <summary>
+ /// Peek n char from buffer or less if remaining char in buffer's line is less than requested
+ /// if end of line is reached, no '\n' will be emitted, instead, empty string is returned. '\n' should be checked only
+ /// with single char Peek().
+ /// Throw error is eof is true
+ /// </summary>
+ /// <param name="length">Length.</param>
+ protected virtual string Peek(int length) {
+ if (eol)
+ 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 "";
+ return buffer [currentLine].Content.Substring (currentColumn, lg);
+ }
+ /// <summary>
+ /// read one char from buffer at current position, if '\n' is read, current line is incremented
+ /// and column is reset to 0
+ /// </summary>
+ protected virtual char Read() {
+ char c = Peek ();
+ if (c == '\n')
+ eol = true;
+ currentColumn++;
+ return c;
+ }
+ /// <summary>
+ /// read until end of line is reached
+ /// </summary>
+ /// <returns>string read</returns>
+ protected virtual string ReadLine () {
+ StringBuilder tmp = new StringBuilder();
+ char c = Read ();
+ while (!eol) {
+ tmp.Append (c);
+ c = Read ();
+ }
+ return tmp.ToString();
+ }
+ /// <summary>
+ /// read until end expression is reached or end of line.
+ /// </summary>
+ /// <returns>string read minus the ending expression that has to be read after</returns>
+ /// <param name="endExp">Expression to search for</param>
+ protected virtual string ReadLineUntil (string endExp){
+ string tmp = "";
+
+ while (!eol) {
+ if (buffer [currentLine].Length - currentColumn - endExp.Length < 0) {
+ tmp += ReadLine();
+ break;
+ }
+ if (string.Equals (Peek (endExp.Length), endExp))
+ return tmp;
+ tmp += Read();
+ }
+ return tmp;
+ }
+ /// <summary>
+ /// skip white spaces, but not line break. Save spaces in a WhiteSpace token.
+ /// </summary>
+ protected void SkipWhiteSpaces () {
+ if (currentTok.Type != TokenType.Unknown)
+ 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;
+ readToCurrTok (currentTok.Type == TokenType.Unknown);
+ currentTok.Type = TokenType.WhiteSpace;
+ }
+ if (currentTok.Type != TokenType.Unknown)
+ saveAndResetCurrentTok ();
+ }
+ #endregion
+ }
+}
\ No newline at end of file
namespace Crow.Coding
{
- public class CSharpParser : Parser
+ public class CSharpParser : BufferParser
{
#region keywords
string[] keywords = new string[] {
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;
Debugger.Break ();
currentTok.Start = CurrentPosition;
- currentTok.Type = (Parser.TokenType)TokenType.BlockComment;
+ currentTok.Type = (BufferParser.TokenType)TokenType.BlockComment;
currentTok += ReadLineUntil ("*/");
if (Peek (2) == "*/") {
readToCurrTok (2);
public List<Token> Tokens;
public int EndingState = 0;
public Node SyntacticNode;
- public ParsingException exception;
+ public ParserException exception;
public CodeLine (string _content){
Content = _content;
}
}
- public void SetLineInError (ParsingException ex) {
+ public void SetLineInError (ParserException ex) {
Tokens = null;
exception = ex;
}
+++ /dev/null
-using System;
-using System.IO;
-using Crow;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Text;
-
-namespace Crow.Coding
-{
- /// <summary>
- /// base class for tokenizing sources
- /// </summary>
- public abstract class Parser
- {
- /// <summary>
- /// Default tokens, this enum may be overriden in derived parser with the new keyword,
- /// see XMLParser for example.
- /// </summary>
- public enum TokenType {
- Unknown = 0,
- WhiteSpace = 1,
- NewLine = 2,
- LineComment = 3,
- BlockCommentStart = 4,
- BlockComment = 5,
- BlockCommentEnd = 6,
- Type = 7,
- Identifier = 8,
- Indexer = 9,
- OpenBlock = 10,
- CloseBlock = 11,
- StatementEnding = 12,
- UnaryOp = 13,
- BinaryOp = 14,
- Affectation = 15,
- StringLitteralOpening = 16,
- StringLitteralClosing = 17,
- StringLitteral = 18,
- NumericLitteral = 19,
- Preprocessor = 20,
- Keyword = 21,
- }
-
- #region CTOR
- public Parser (CodeBuffer _buffer)
- {
- buffer = _buffer;
-
- buffer.LineUpadateEvent += Buffer_LineUpadateEvent;
- //buffer.LineAdditionEvent += Buffer_LineAdditionEvent;;
- buffer.LineRemoveEvent += Buffer_LineRemoveEvent;
- buffer.BufferCleared += Buffer_BufferCleared;
- }
-
- #endregion
-
- #region Buffer events handlers
- void Buffer_BufferCleared (object sender, EventArgs e)
- {
-
- }
- void Buffer_LineAdditionEvent (object sender, CodeBufferEventArgs e)
- {
-
- }
- void Buffer_LineRemoveEvent (object sender, CodeBufferEventArgs e)
- {
- reparseSource ();
- }
- void Buffer_LineUpadateEvent (object sender, CodeBufferEventArgs e)
- {
- for (int i = 0; i < e.LineCount; i++)
- tryParseBufferLine (e.LineStart + i);
- reparseSource ();
- }
- #endregion
-
- void updateFolding () {
- // Stack<TokenList> foldings = new Stack<TokenList>();
- // bool inStartTag = false;
- //
- // for (int i = 0; i < parser.Tokens.Count; i++) {
- // TokenList tl = parser.Tokens [i];
- // tl.foldingTo = null;
- // int fstTK = tl.FirstNonBlankTokenIndex;
- // if (fstTK > 0 && fstTK < tl.Count - 1) {
- // if (tl [fstTK + 1] != XMLParser.TokenType.ElementName)
- // continue;
- // if (tl [fstTK] == XMLParser.TokenType.ElementStart) {
- // //search closing tag
- // int tkPtr = fstTK+2;
- // while (tkPtr < tl.Count) {
- // if (tl [tkPtr] == XMLParser.TokenType.ElementClosing)
- //
- // tkPtr++;
- // }
- // if (tl.EndingState == (int)XMLParser.States.Content)
- // foldings.Push (tl);
- // else if (tl.EndingState == (int)XMLParser.States.StartTag)
- // inStartTag = true;
- // continue;
- // }
- // if (tl [fstTK] == XMLParser.TokenType.ElementEnd) {
- // TokenList tls = foldings.Pop ();
- // int fstTKs = tls.FirstNonBlankTokenIndex;
- // if (tls [fstTK + 1].Content == tl [fstTK + 1].Content) {
- // tl.foldingTo = tls;
- // continue;
- // }
- // parser.CurrentPosition = tls [fstTK + 1].Start;
- // parser.SetLineInError(new ParsingException(parser, "closing tag not corresponding"));
- // }
- //
- // }
- // }
- }
- public void reparseSource () {
- for (int i = 0; i < buffer.LineCount; i++) {
- if (!buffer[i].IsParsed)
- tryParseBufferLine (i);
- }
- try {
- SyntaxAnalysis ();
- } catch (Exception ex) {
- Debug.WriteLine ("Syntax Error: " + ex.ToString ());
- if (ex is ParsingException)
- SetLineInError (ex as ParsingException);
- }
- }
- public void tryParseBufferLine(int lPtr) {
- buffer [lPtr].exception = null;
- currentLine = lPtr;
- currentColumn = 0;
- eol = false;
-
- try {
- ParseCurrentLine ();
- } catch (Exception ex) {
- Debug.WriteLine (ex.ToString ());
- if (ex is ParsingException)
- SetLineInError (ex as ParsingException);
- }
-
- }
-
- protected CodeBuffer buffer;
-
- internal int currentLine = 0;
- internal int currentColumn = 0;
- protected Token currentTok;
- protected bool eol = true;
-
- public Node RootNode;
-
- protected Point CurrentPosition {
- get { return new Point (currentLine, currentColumn); }
- set {
- currentLine = value.Y;
- currentColumn = value.X;
- }
- }
-
- public abstract void ParseCurrentLine();
- public abstract void SyntaxAnalysis ();
-
- public virtual void SetLineInError(ParsingException ex) {
- currentTok = default(Token);
- if (ex.Line >= buffer.LineCount)
- ex.Line = buffer.LineCount - 1;
- if (buffer [ex.Line].IsFolded)
- buffer.ToogleFolding (ex.Line);
- buffer [ex.Line].SetLineInError (ex);
- }
-
- #region low level parsing
- /// <summary>
- /// Read one char from current position in buffer and store it into the current token
- /// </summary>
- /// <param name="startOfTok">if true, set the Start position of the current token to the current position</param>
- protected void readToCurrTok(bool startOfTok = false){
- if (startOfTok)
- currentTok.Start = CurrentPosition;
- currentTok += Read();
- }
- /// <summary>
- /// read n char from the buffer and store it into the current token
- /// </summary>
- protected void readToCurrTok(int length) {
- for (int i = 0; i < length; i++)
- currentTok += Read ();
- }
- /// <summary>
- /// Save current token into current TokensLine and raz current token
- /// </summary>
- protected void saveAndResetCurrentTok() {
- currentTok.End = CurrentPosition;
- buffer[currentLine].Tokens.Add (currentTok);
- currentTok = default(Token);
- }
- /// <summary>
- /// read one char and add current token to current TokensLine, current token is reset
- /// </summary>
- /// <param name="type">Type of the token</param>
- /// <param name="startToc">set start of token to current position</param>
- protected void readAndResetCurrentTok(System.Enum type, bool startToc = false) {
- readToCurrTok ();
- saveAndResetCurrentTok (type);
- }
- /// <summary>
- /// Save current tok
- /// </summary>
- /// <param name="type">set the type of the tok</param>
- protected void saveAndResetCurrentTok(System.Enum type) {
- currentTok.Type = (TokenType)type;
- saveAndResetCurrentTok ();
- }
- /// <summary>
- /// Peek next char, emit '\n' if current column > buffer's line length
- /// Throw error if eof is true
- /// </summary>
- protected virtual char Peek() {
- if (eol)
- throw new ParsingException (this, "Unexpected End of line");
- return currentColumn < buffer [currentLine].Length ?
- buffer [currentLine] [currentColumn] : '\n';
- }
- /// <summary>
- /// Peek n char from buffer or less if remaining char in buffer's line is less than requested
- /// if end of line is reached, no '\n' will be emitted, instead, empty string is returned. '\n' should be checked only
- /// with single char Peek().
- /// Throw error is eof is true
- /// </summary>
- /// <param name="length">Length.</param>
- protected virtual string Peek(int length) {
- if (eol)
- throw new ParsingException (this, "Unexpected End of Line");
- int lg = Math.Min(length, Math.Max (buffer [currentLine].Length - currentColumn, buffer [currentLine].Length - currentColumn - length));
- if (lg == 0)
- return "";
- return buffer [currentLine].Content.Substring (currentColumn, lg);
- }
- /// <summary>
- /// read one char from buffer at current position, if '\n' is read, current line is incremented
- /// and column is reset to 0
- /// </summary>
- protected virtual char Read() {
- char c = Peek ();
- if (c == '\n')
- eol = true;
- currentColumn++;
- return c;
- }
- /// <summary>
- /// read until end of line is reached
- /// </summary>
- /// <returns>string read</returns>
- protected virtual string ReadLine () {
- StringBuilder tmp = new StringBuilder();
- char c = Read ();
- while (!eol) {
- tmp.Append (c);
- c = Read ();
- }
- return tmp.ToString();
- }
- /// <summary>
- /// read until end expression is reached or end of line.
- /// </summary>
- /// <returns>string read minus the ending expression that has to be read after</returns>
- /// <param name="endExp">Expression to search for</param>
- protected virtual string ReadLineUntil (string endExp){
- string tmp = "";
-
- while (!eol) {
- if (buffer [currentLine].Length - currentColumn - endExp.Length < 0) {
- tmp += ReadLine();
- break;
- }
- if (string.Equals (Peek (endExp.Length), endExp))
- return tmp;
- tmp += Read();
- }
- return tmp;
- }
- /// <summary>
- /// skip white spaces, but not line break. Save spaces in a WhiteSpace token.
- /// </summary>
- protected void SkipWhiteSpaces () {
- if (currentTok.Type != TokenType.Unknown)
- throw new ParsingException (this, "current token should be reset to unknown (0) before skiping white spaces");
- while (!eol) {
- if (!char.IsWhiteSpace (Peek ())||Peek()=='\n')
- break;
- readToCurrTok (currentTok.Type == TokenType.Unknown);
- currentTok.Type = TokenType.WhiteSpace;
- }
- if (currentTok.Type != TokenType.Unknown)
- saveAndResetCurrentTok ();
- }
- #endregion
- }
-}
\ No newline at end of file
+++ /dev/null
-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);
- }
- }
-}
-
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");
int printedCurrentLine = 0;//Index of the currentline in the PrintedLines array
CodeBuffer buffer;
- Parser parser;
+ BufferParser parser;
List<CodeLine> PrintedLines;//list of lines visible in the Editor depending on scrolling and folding
Dictionary<int, TextFormatting> formatting = new Dictionary<int, TextFormatting>();
}
}
- Parser getParserFromExt (string extension) {
+ BufferParser getParserFromExt (string extension) {
if (string.IsNullOrEmpty(extension))
return null;
if (!parsing.ContainsKey(extension))
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
namespace Crow.Coding
{
- public class StyleParser : Parser
+ public class StyleParser : BufferParser
{
enum States { init, classNames, members, value, endOfStatement }
{
}
- #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()})); }
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;
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) {
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);
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);
{
public struct Token
{
- public Parser.TokenType Type;
+ public BufferParser.TokenType Type;
public string Content;
public Point Start;
public Point End;
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,
}
}
#endregion
- public override void SetLineInError (ParsingException ex)
+ public override void SetLineInError (ParserException ex)
{
base.SetLineInError (ex);
//buffer[ex.Line].Tokens.EndingState = (int)States.init;
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;
Debugger.Break ();
currentTok.Start = CurrentPosition;
- currentTok.Type = (Parser.TokenType)TokenType.BlockComment;
+ currentTok.Type = (BufferParser.TokenType)TokenType.BlockComment;
currentTok += ReadLineUntil ("-->");
if (Peek (3) == "-->") {
readToCurrTok (3);
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;
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) == "-->") {
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 ();
}
if (!nextCharIsValidCharStartName)
- throw new ParsingException (this, "Expected element name");
+ throw new ParserException (currentLine, currentColumn, "Expected element name");
readToCurrTok (true);
while (nextCharIsValidCharName)
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;
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 ();
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;
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;
}
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;
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
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
--- /dev/null
+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)
+ {}
+ }
+}
+
using System.Collections.Generic;
using System.IO;
using System.Reflection;
+using System.Text.RegularExpressions;
+using Crow.Coding;
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<string, Style> styling, Stream stream, string resId)
: base(stream)
{
List<string> targetsClasses = new List<string> ();
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<string> ();
- 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 ()