<Compile Include="src\Parser.cs" />
<Compile Include="src\XMLParser.cs" />
<Compile Include="src\CSharpParser.cs" />
+ <Compile Include="src\TokenList.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="ui\" />
public CSharpParser (CodeTextBuffer _buffer) : base(_buffer)
{
}
- public override void Parse ()
+
+ public override void Parse (int line)
{
throw new NotImplementedException ();
}
namespace Crow
{
- public class CodeTextBuffer : List<string>
- {
+ public class CodeBufferEventArgs : EventArgs {
+ public int LineStart;
+ public int LineCount;
+
+ public CodeBufferEventArgs(int lineNumber) {
+ LineStart = lineNumber;
+ LineCount = 1;
+ }
+ public CodeBufferEventArgs(int lineStart, int lineCount) {
+ LineStart = lineStart;
+ LineCount = lineCount;
+ }
+ }
+ public class CodeTextBuffer
+ {
+ #region Events
+ public event EventHandler<CodeBufferEventArgs> LineUpadateEvent;
+ public event EventHandler<CodeBufferEventArgs> LineRemoveEvent;
+ public event EventHandler<CodeBufferEventArgs> LineAdditionEvent;
+ public event EventHandler BufferCleared;
+ #endregion
#region CTOR
- public CodeTextBuffer () : base(){}
+ public CodeTextBuffer () : base() {}
+ #endregion
+
+
+ List<string> lines = new List<string>();
+
+ public int Length { get { return lines.Count;}}
+
+ public string this[int i]
+ {
+ get { return lines[i]; }
+ set {
+ if (lines [i] == value)
+ return;
+ lines[i] = value;
+ LineUpadateEvent.Raise (this, new CodeBufferEventArgs (i));
+ }
+ }
+
+ public void RemoveAt(int i){
+ lines.RemoveAt(i);
+ LineRemoveEvent.Raise (this, new CodeBufferEventArgs (i));
+ }
+ public void Insert(int i, string item){
+ lines.Insert (i, item);
+ LineAdditionEvent.Raise (this, new CodeBufferEventArgs (i));
+ }
+ public void AddRange (string[] items){
+ int start = lines.Count;
+ lines.AddRange (items);
+ LineAdditionEvent.Raise (this, new CodeBufferEventArgs (start, items.Length));
+ }
+ public void Clear () {
+ lines.Clear();
+ BufferCleared.Raise (this, null);
+ }
+
+
+ public void Load(string rawSource) {
+ this.Clear();
- public CodeTextBuffer (string rawSource) : this (){
if (string.IsNullOrEmpty (rawSource))
return;
-
- this.AddRange (Regex.Split (rawSource, "\r\n|\r|\n|\\\\n"));
+
+ AddRange (Regex.Split (rawSource, "\r\n|\r|\n|\\\\n"));
lineBreak = detectLineBreakKind (rawSource);
findLongestLine ();
}
- #endregion
-
string lineBreak = Interface.LineBreak;
public int longestLineIdx = 0;
void findLongestLine(){
longestLineCharCount = 0;
- for (int i = 0; i < this.Count; i++) {
- if (this[i].Length > longestLineCharCount) {
- longestLineCharCount = this[i].Length;
+ for (int i = 0; i < lines.Count; i++) {
+ if (lines[i].Length > longestLineCharCount) {
+ longestLineCharCount = lines[i].Length;
longestLineIdx = i;
}
}
/// </summary>
public string FullText{
get {
- return this.Count > 0 ? this.Aggregate((i, j) => i + this.lineBreak + j) : "";
+ return lines.Count > 0 ? lines.Aggregate((i, j) => i + this.lineBreak + j) : "";
}
}
}
using System.IO;
using Crow;
using System.Collections.Generic;
+using System.Diagnostics;
namespace CrowEdit
{
}
}
+ #region CTOR
public Parser (CodeTextBuffer _buffer)
{
buffer = _buffer;
- if (buffer.Count > 0)
+ Tokens = new List<TokenList> ();
+ if (buffer.Length > 0)
eof = false;
}
- protected bool parsed = false;
+ #endregion
+
protected int currentLine = 0;
protected int currentColumn = 0;
protected Token currentTok;
CodeTextBuffer buffer;
- public List<List<Token>> Tokens;
- protected List<Token> TokensLine;
+ public List<TokenList> Tokens;
+ protected TokenList TokensLine;
- public bool Parsed { get { return parsed; }}
public Point CurrentPosition { get { return new Point (currentLine, currentColumn); } }
- public abstract void Parse();
+ public virtual void SetLineInError(int lineNumber) {
+ currentTok = default(Token);
+ Tokens [lineNumber] = new TokenList () {new Token () { Content = buffer [lineNumber] }};
+ }
+ public abstract void Parse(int line);
protected void readToCurrTok(bool startOfTok = false){
if (startOfTok)
if (c == '\n') {
currentLine++;
- if (currentLine >= buffer.Count)
+ if (currentLine >= buffer.Length)
eof = true;
currentColumn = 0;
} else
currentColumn++;
return c;
}
- protected virtual string Read(uint length) {
- string tmp = "";
- for (int i = 0; i < length; i++) {
- char c = Peek ();
- if (c == '\n') {
- currentLine++;
- if (currentLine >= buffer.Count)
- eof = true;
- currentColumn = 0;
- } else
- currentColumn++;
- tmp += c;
- }
- return tmp;
- }
protected virtual string ReadUntil (string endExp){
string tmp = "";
while (!eof) {
if (buffer [currentLine].Length - currentColumn - endExp.Length < 0) {
currentLine++;
- if (currentLine >= buffer.Count)
+ if (currentLine >= buffer.Length)
eof = true;
currentColumn = 0;
continue;
formating.Add ((int)XMLParser.TokenType.AttributeValueOpening, new TextFormating (Color.DarkPink, Color.Transparent));
formating.Add ((int)XMLParser.TokenType.AttributeValueClosing, new TextFormating (Color.DarkPink, Color.Transparent));
formating.Add ((int)XMLParser.TokenType.AttributeValue, new TextFormating (Color.DarkPink, Color.Transparent));
+
+ buffer = new CodeTextBuffer ();
+ buffer.LineUpadateEvent += Buffer_LineUpadateEvent;
+ buffer.LineAdditionEvent += Buffer_LineAdditionEvent;;
+ buffer.LineRemoveEvent += Buffer_LineRemoveEvent;
+ buffer.BufferCleared += Buffer_BufferCleared;
+
+ parser = new CrowEdit.XMLParser (buffer);
}
#endregion
if (string.Equals (value, buffer?.FullText, StringComparison.Ordinal))
return;
- buffer = new CodeTextBuffer (value);
- MaxScrollY = Math.Max (0, buffer.Count - visibleLines);
+ buffer.Load (value);
+
+ MaxScrollY = Math.Max (0, buffer.Length - visibleLines);
MaxScrollX = Math.Max (0, buffer.longestLineCharCount - visibleColumns);
OnTextChanged (this, null);
}
}
+ void Buffer_BufferCleared (object sender, EventArgs e)
+ {
+ parser = new CrowEdit.XMLParser (buffer);
+ RegisterForGraphicUpdate ();
+ }
+ void reparseSource () {
+ for (int i = 0; i < parser.Tokens.Count; i++) {
+ if (parser.Tokens[i].Dirty)
+ tryParseBufferLine (i);
+ }
+ }
+ void tryParseBufferLine(int lPtr) {
+ try {
+ parser.Parse (lPtr);
+ } catch (Exception ex) {
+ Debug.WriteLine (ex.ToString ());
+ parser.SetLineInError (lPtr);
+ }
+ RegisterForGraphicUpdate ();
+ }
+ void Buffer_LineAdditionEvent (object sender, CodeBufferEventArgs e)
+ {
+ for (int i = 0; i < e.LineCount; i++) {
+ parser.Tokens.Insert (e.LineStart + i, new TokenList());
+ tryParseBufferLine (e.LineStart + i);
+ }
+ reparseSource ();
+ RegisterForGraphicUpdate ();
+ }
+
+ void Buffer_LineRemoveEvent (object sender, CodeBufferEventArgs e)
+ {
+ for (int i = 0; i < e.LineCount; i++)
+ parser.Tokens.RemoveAt (e.LineStart + i);
+ reparseSource ();
+ RegisterForGraphicUpdate ();
+ }
+
+ void Buffer_LineUpadateEvent (object sender, CodeBufferEventArgs e)
+ {
+ for (int i = 0; i < e.LineCount; i++)
+ tryParseBufferLine (e.LineStart + i);
+ reparseSource ();
+ RegisterForGraphicUpdate ();
+ }
[XmlAttributeAttribute][DefaultValue("BlueGray")]
public virtual Color SelectionBackground {
set {
if (value == _currentLine)
return;
- if (value >= buffer.Count)
- _currentLine = buffer.Count-1;
+ if (value >= buffer.Length)
+ _currentLine = buffer.Length-1;
else if (value < 0)
_currentLine = 0;
else
public bool MoveRight(){
int tmp = _currentCol + 1;
if (tmp > buffer [_currentLine].Length){
- if (CurrentLine == buffer.Count - 1)
+ if (CurrentLine == buffer.Length - 1)
return false;
CurrentLine++;
CurrentColumn = 0;
{
if (selectionIsEmpty) {
if (CurrentColumn == 0) {
- if (CurrentLine == 0 && buffer.Count == 1)
+ if (CurrentLine == 0 && buffer.Length == 1)
return;
CurrentLine--;
CurrentColumn = buffer [CurrentLine].Length;
protected override int measureRawSize(LayoutingType lt)
{
if (lt == LayoutingType.Height)
- return (int)Math.Ceiling(fe.Height * buffer.Count) + Margin * 2;
+ return (int)Math.Ceiling(fe.Height * buffer.Length) + Margin * 2;
return (int)(fe.MaxXAdvance * buffer.longestLineCharCount) + Margin * 2;
}
for (int i = 0; i < visibleLines; i++) {
int curL = i + ScrollY;
- if (curL >= buffer.Count)
+ if (curL >= buffer.Length)
break;
string lstr = buffer[curL];
if (ScrollX < lstr.Length)
#endregion
for (int i = 0; i < visibleLines; i++) {
- int curL = i + ScrollY;
- if (curL >= parser.Tokens.Count)
+ if (i + ScrollY >= parser.Tokens.Count)
break;
- drawTokenLine (gr, curL, selectionInProgress);
+ drawTokenLine (gr, i, selectionInProgress, cb);
}
}
- void drawTokenLine(Context gr, int curL, bool selectionInProgress) {
+ void drawTokenLine(Context gr, int i, bool selectionInProgress, Rectangle cb) {
+ int curL = i + ScrollY;
List<Token> tokens = parser.Tokens[curL];
int lPtr = 0;
double rLineX = x,
rLineY = cb.Y + i * fe.Height,
rLineW = lstr.Length * fe.MaxXAdvance;
+ double startAdjust = 0.0;
- if ((curL == selectionStart.Y) && (selectionStart.X < lPtr + lstr.Length) && (selectionStart.X > lPtr)) {
- rLineX += (selectionStart.X - lPtr) * fe.MaxXAdvance;
- rLineW -= (selectionStart.X - lPtr) * fe.MaxXAdvance;
- }
+ if ((curL == selectionStart.Y) && (selectionStart.X < lPtr + lstr.Length) && (selectionStart.X > lPtr))
+ startAdjust = (selectionStart.X - lPtr) * fe.MaxXAdvance;
+ rLineX += startAdjust;
if ((curL == selectionEnd.Y) && (selectionEnd.X < lPtr + lstr.Length))
rLineW = (selectionEnd.X - lPtr) * fe.MaxXAdvance;
+ rLineW -= startAdjust;
gr.Save ();
gr.Operator = Operator.Source;
{
base.onDraw (gr);
- if (parser?.Parsed == true)
+ if (parser != null)
drawParsed (gr);
else
draw(gr);
this.Insert ("\t");
break;
case Key.F8:
- try {
- parser = new CrowEdit.XMLParser (buffer);
- parser.Parse ();
- } catch (Exception ee) {
- Debug.WriteLine (ee.ToString ());
- parser = null;
- }
- break;
- case Key.F9:
- parser = null;
+ if (parser != null)
+ reparseSource ();
break;
default:
break;
void updateVisibleLines(){
visibleLines = (int)Math.Floor ((double)ClientRectangle.Height / fe.Height);
- MaxScrollY = Math.Max (0, buffer.Count - visibleLines);
+ MaxScrollY = Math.Max (0, buffer.Length - visibleLines);
System.Diagnostics.Debug.WriteLine ("update visible lines: " + visibleLines);
System.Diagnostics.Debug.WriteLine ("update MaxScrollY: " + MaxScrollY);
--- /dev/null
+using System;
+using System.Collections.Generic;
+
+namespace Crow
+{
+ public class TokenList : List<Token>
+ {
+ public bool Dirty = true;
+ public int EndingState;
+
+ public TokenList () : base ()
+ {
+ EndingState = 0;
+ }
+
+ public new void Clear() {
+ EndingState = 0;
+ Dirty = true;
+ base.Clear ();
+ }
+ }
+}
+
using Crow;
using System.Collections.Generic;
using System.Text.RegularExpressions;
+using System.Diagnostics;
namespace CrowEdit
{
// }
#endregion
- public override void Parse ()
+ public override void SetLineInError (int lineNumber)
{
- parsed = false;
- Tokens = new List<List<Token>> ();
- TokensLine = new List<Token> ();
- currentLine = currentColumn = 0;
- currentTok = default(Token);
- curState = States.init;
+ base.SetLineInError (lineNumber);
+ Tokens[lineNumber].EndingState = (int)States.init;
+ }
+
+ public override void Parse (int line)
+ {
+ Debug.WriteLine (string.Format("parsing line:{0}", line));
+
+ currentLine = line;
+ currentColumn = 0;
+ eof = false;
+ bool eol = false;
+
+ if (line > 0)
+ curState = (States)Tokens [line - 1].EndingState;
+ else
+ curState = States.init;
+
+ TokensLine = Tokens [line];
- string tmp = "";
+ States previousEndingState = (States)TokensLine.EndingState;
- while (!eof) {
+ TokensLine.Clear ();
+
+
+
+ while (! (eof||eol)) {
SkipWhiteSpaces ();
if (eof)
if (currentTok != TokenType.Unknown)
throw new ParsingException (this, "Unexpected end of line");
Read ();
- Tokens.Add (TokensLine);
- TokensLine = new List<Token> ();
+ eol = true;
break;
case '<':
readToCurrTok (true);
break;
}
}
- if (TokensLine.Count > 0)
- Tokens.Add (TokensLine);
- parsed = true;
+ TokensLine.EndingState = (int)curState;
+ TokensLine.Dirty = false;
+
+ Debug.WriteLine ("\tState:{0}->{1}", previousEndingState, curState);
+
+ if (previousEndingState != curState && line < Tokens.Count - 1)
+ Tokens [line + 1].Dirty = true;
}
}
}