UnityExplorer/src/UI/Main/Console/Lexer/KeywordMatch.cs

117 lines
3.2 KiB
C#
Raw Normal View History

using System.Collections.Generic;
2020-10-26 01:07:59 +11:00
using UnityEngine;
namespace UnityExplorer.UI.Main.Console.Lexer
2020-10-26 01:07:59 +11:00
{
public sealed class KeywordMatch : Matcher
2020-10-26 01:07:59 +11:00
{
public string keywords;
public override Color HighlightColor => highlightColor;
2020-10-26 01:07:59 +11:00
public Color highlightColor;
private readonly HashSet<string> shortlist = new HashSet<string>();
private readonly Stack<string> removeList = new Stack<string>();
public string[] keywordCache = null;
2020-10-26 01:07:59 +11:00
public override bool IsImplicitMatch(InputLexer lexer)
2020-10-26 01:07:59 +11:00
{
BuildKeywordCache();
if (!char.IsWhiteSpace(lexer.Previous) &&
!lexer.IsSpecialSymbol(lexer.Previous, SpecialCharacterPosition.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();
for (int i = 0; i < keywordCache.Length; i++)
{
if (keywordCache[i][0] == currentChar)
{
2020-10-26 01:07:59 +11:00
shortlist.Add(keywordCache[i]);
}
}
2020-10-26 01:07:59 +11:00
if (shortlist.Count == 0)
{
2020-10-26 01:07:59 +11:00
return false;
}
2020-10-26 01:07:59 +11:00
do
{
if (lexer.EndOfStream)
{
RemoveLongStrings(currentIndex + 1);
break;
}
currentChar = lexer.ReadNext();
currentIndex++;
if (char.IsWhiteSpace(currentChar) ||
lexer.IsSpecialSymbol(currentChar, SpecialCharacterPosition.Start))
{
RemoveLongStrings(currentIndex);
lexer.Rollback(1);
break;
}
foreach (string keyword in shortlist)
{
if (currentIndex >= keyword.Length || keyword[currentIndex] != currentChar)
2020-10-26 01:07:59 +11:00
{
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
}
while (shortlist.Count > 0);
return shortlist.Count > 0;
}
private void RemoveLongStrings(int length)
{
foreach (string keyword in shortlist)
{
2020-10-26 01:07:59 +11:00
if (keyword.Length > length)
{
2020-10-26 01:07:59 +11:00
removeList.Push(keyword);
}
}
2020-10-26 01:07:59 +11:00
while (removeList.Count > 0)
{
2020-10-26 01:07:59 +11:00
shortlist.Remove(removeList.Pop());
}
2020-10-26 01:07:59 +11:00
}
private void BuildKeywordCache()
{
if (keywordCache == null)
{
string[] kwSplit = keywords.Split(' ');
2020-10-26 01:07:59 +11:00
List<string> list = new List<string>();
foreach (string kw in kwSplit)
2020-10-26 01:07:59 +11:00
{
if (!string.IsNullOrEmpty(kw) && kw.Length > 0)
{
list.Add(kw);
}
}
keywordCache = list.ToArray();
}
}
}
}