UnityExplorer/src/CSConsole/Lexer/SymbolMatch.cs

107 lines
3.2 KiB
C#
Raw Normal View History

using System.Collections.Generic;
2020-10-26 01:07:59 +11:00
using System.Linq;
using UnityEngine;
namespace UnityExplorer.CSConsole.Lexer
2020-10-26 01:07:59 +11:00
{
2020-11-11 00:16:01 +11:00
public class SymbolMatch : Matcher
2020-10-26 01:07:59 +11:00
{
public override Color HighlightColor => new Color(0.58f, 0.47f, 0.37f, 1.0f);
2020-11-11 00:16:01 +11:00
private readonly string[] symbols = new[]
{
"[", "]", "(", ")", ".", "?", ":", "+", "-", "*", "/", "%", "&", "|", "^", "~", "=", "<", ">",
"++", "--", "&&", "||", "<<", ">>", "==", "!=", "<=", ">=", "+=", "-=", "*=", "/=", "%=", "&=",
"|=", "^=", "<<=", ">>=", "->", "??", "=>",
};
2020-10-26 01:07:59 +11:00
private static readonly List<string> shortlist = new List<string>();
private static readonly Stack<string> removeList = new Stack<string>();
2020-11-11 00:16:01 +11:00
public override IEnumerable<char> StartChars => symbols.Select(s => s[0]);
public override IEnumerable<char> EndChars => symbols.Select(s => s[0]);
2020-10-26 01:07:59 +11:00
2020-11-11 00:16:01 +11:00
public override bool IsImplicitMatch(CSharpLexer lexer)
2020-10-26 01:07:59 +11:00
{
if (lexer == null)
return false;
if (!char.IsWhiteSpace(lexer.Previous) &&
!char.IsLetter(lexer.Previous) &&
!char.IsDigit(lexer.Previous) &&
2020-11-11 00:16:01 +11:00
!lexer.IsSpecialSymbol(lexer.Previous, DelimiterType.End))
{
2020-10-26 01:07:59 +11:00
return false;
}
2020-10-26 01:07:59 +11:00
shortlist.Clear();
int currentIndex = 0;
char currentChar = lexer.ReadNext();
2020-11-11 00:16:01 +11:00
for (int i = symbols.Length - 1; i >= 0; i--)
2020-10-26 01:07:59 +11:00
{
2020-11-11 00:16:01 +11:00
if (symbols[i][0] == currentChar)
shortlist.Add(symbols[i]);
2020-10-26 01:07:59 +11:00
}
if (shortlist.Count == 0)
return false;
do
{
if (lexer.EndOfStream)
{
RemoveLongStrings(currentIndex + 1);
break;
}
currentChar = lexer.ReadNext();
currentIndex++;
if (char.IsWhiteSpace(currentChar) ||
char.IsLetter(currentChar) ||
char.IsDigit(currentChar) ||
2020-11-11 00:16:01 +11:00
lexer.IsSpecialSymbol(currentChar, DelimiterType.Start))
2020-10-26 01:07:59 +11:00
{
RemoveLongStrings(currentIndex);
lexer.Rollback(1);
break;
}
foreach (string symbol in shortlist)
{
if (currentIndex >= symbol.Length || symbol[currentIndex] != currentChar)
{
removeList.Push(symbol);
}
}
while (removeList.Count > 0)
{
2020-10-26 01:07:59 +11:00
shortlist.Remove(removeList.Pop());
}
2020-10-26 01:07:59 +11:00
}
while (shortlist.Count > 0);
return shortlist.Count > 0;
}
private void RemoveLongStrings(int length)
{
foreach (string keyword in shortlist)
{
if (keyword.Length > length)
{
removeList.Push(keyword);
}
}
while (removeList.Count > 0)
{
2020-10-26 01:07:59 +11:00
shortlist.Remove(removeList.Pop());
}
2020-10-26 01:07:59 +11:00
}
}
}