2020-10-28 06:39:26 +11:00
|
|
|
|
using System.Collections.Generic;
|
2020-10-26 01:07:59 +11:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
2020-11-05 17:33:04 +11:00
|
|
|
|
namespace UnityExplorer.Console.Lexer
|
2020-10-26 01:07:59 +11:00
|
|
|
|
{
|
2020-11-03 20:59:13 +11:00
|
|
|
|
public sealed 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);
|
|
|
|
|
|
|
|
|
|
public string Symbols => @"[ ] ( ) . ? : + - * / % & | ^ ~ = < > ++ -- && || << >> == != <= >=
|
|
|
|
|
+= -= *= /= %= &= |= ^= <<= >>= -> ?? =>";
|
|
|
|
|
|
|
|
|
|
private static readonly List<string> shortlist = new List<string>();
|
|
|
|
|
private static readonly Stack<string> removeList = new Stack<string>();
|
|
|
|
|
private string[] symbolCache = null;
|
|
|
|
|
|
|
|
|
|
public override IEnumerable<char> StartChars
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
BuildSymbolCache();
|
|
|
|
|
foreach (string symbol in symbolCache.Where(x => x.Length > 0))
|
2020-10-28 06:39:26 +11:00
|
|
|
|
{
|
2020-10-26 01:07:59 +11:00
|
|
|
|
yield return symbol[0];
|
2020-10-28 06:39:26 +11:00
|
|
|
|
}
|
2020-10-26 01:07:59 +11:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override IEnumerable<char> EndChars
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
BuildSymbolCache();
|
|
|
|
|
foreach (string symbol in symbolCache.Where(x => x.Length > 0))
|
2020-10-28 06:39:26 +11:00
|
|
|
|
{
|
2020-10-26 01:07:59 +11:00
|
|
|
|
yield return symbol[0];
|
2020-10-28 06:39:26 +11:00
|
|
|
|
}
|
2020-10-26 01:07:59 +11:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-03 20:59:13 +11:00
|
|
|
|
public override bool IsImplicitMatch(InputLexer lexer)
|
2020-10-26 01:07:59 +11:00
|
|
|
|
{
|
|
|
|
|
if (lexer == null)
|
2020-10-28 06:39:26 +11:00
|
|
|
|
{
|
2020-10-26 01:07:59 +11:00
|
|
|
|
return false;
|
2020-10-28 06:39:26 +11:00
|
|
|
|
}
|
2020-10-26 01:07:59 +11:00
|
|
|
|
|
|
|
|
|
BuildSymbolCache();
|
|
|
|
|
|
|
|
|
|
if (!char.IsWhiteSpace(lexer.Previous) &&
|
|
|
|
|
!char.IsLetter(lexer.Previous) &&
|
|
|
|
|
!char.IsDigit(lexer.Previous) &&
|
|
|
|
|
!lexer.IsSpecialSymbol(lexer.Previous, SpecialCharacterPosition.End))
|
2020-10-28 06:39:26 +11:00
|
|
|
|
{
|
2020-10-26 01:07:59 +11:00
|
|
|
|
return false;
|
2020-10-28 06:39:26 +11:00
|
|
|
|
}
|
2020-10-26 01:07:59 +11:00
|
|
|
|
|
|
|
|
|
shortlist.Clear();
|
|
|
|
|
|
|
|
|
|
int currentIndex = 0;
|
|
|
|
|
char currentChar = lexer.ReadNext();
|
|
|
|
|
|
|
|
|
|
for (int i = symbolCache.Length - 1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
if (symbolCache[i][0] == currentChar)
|
2020-10-28 06:39:26 +11:00
|
|
|
|
{
|
2020-10-26 01:07:59 +11:00
|
|
|
|
shortlist.Add(symbolCache[i]);
|
2020-10-28 06:39:26 +11:00
|
|
|
|
}
|
2020-10-26 01:07:59 +11:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (shortlist.Count == 0)
|
2020-10-28 06:39:26 +11:00
|
|
|
|
{
|
2020-10-26 01:07:59 +11:00
|
|
|
|
return false;
|
2020-10-28 06:39:26 +11:00
|
|
|
|
}
|
2020-10-26 01:07:59 +11:00
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
if (lexer.EndOfStream)
|
|
|
|
|
{
|
|
|
|
|
RemoveLongStrings(currentIndex + 1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
currentChar = lexer.ReadNext();
|
|
|
|
|
currentIndex++;
|
|
|
|
|
|
|
|
|
|
if (char.IsWhiteSpace(currentChar) ||
|
|
|
|
|
char.IsLetter(currentChar) ||
|
|
|
|
|
char.IsDigit(currentChar) ||
|
|
|
|
|
lexer.IsSpecialSymbol(currentChar, SpecialCharacterPosition.Start))
|
|
|
|
|
{
|
|
|
|
|
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-28 06:39:26 +11:00
|
|
|
|
{
|
2020-10-26 01:07:59 +11:00
|
|
|
|
shortlist.Remove(removeList.Pop());
|
2020-10-28 06:39:26 +11:00
|
|
|
|
}
|
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-28 06:39:26 +11:00
|
|
|
|
{
|
2020-10-26 01:07:59 +11:00
|
|
|
|
shortlist.Remove(removeList.Pop());
|
2020-10-28 06:39:26 +11:00
|
|
|
|
}
|
2020-10-26 01:07:59 +11:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void BuildSymbolCache()
|
|
|
|
|
{
|
|
|
|
|
if (symbolCache != null)
|
2020-10-28 06:39:26 +11:00
|
|
|
|
{
|
2020-10-26 01:07:59 +11:00
|
|
|
|
return;
|
2020-10-28 06:39:26 +11:00
|
|
|
|
}
|
2020-10-26 01:07:59 +11:00
|
|
|
|
|
2020-10-28 06:39:26 +11:00
|
|
|
|
string[] symSplit = Symbols.Split(' ');
|
|
|
|
|
List<string> list = new List<string>();
|
|
|
|
|
foreach (string sym in symSplit)
|
2020-10-26 01:07:59 +11:00
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(sym) && sym.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
list.Add(sym);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
symbolCache = list.ToArray();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|