2025-07-03 21:50:26 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace Convention.Symbolization.Internal
|
|
|
|
|
{
|
|
|
|
|
public class SymbolizationReader
|
|
|
|
|
{
|
2025-07-04 21:39:02 +08:00
|
|
|
|
#region Read Script Words
|
|
|
|
|
|
2025-07-03 21:50:26 +08:00
|
|
|
|
private string buffer = "";
|
2025-07-04 21:39:02 +08:00
|
|
|
|
private int lineContext = 1;
|
2025-07-03 21:50:26 +08:00
|
|
|
|
private bool isOutOfStringline = true;
|
2025-07-04 23:00:41 +08:00
|
|
|
|
public Dictionary<int, Dictionary<int, Variable>> ScriptWords = new() { { 1, new() } };
|
2025-07-03 21:50:26 +08:00
|
|
|
|
|
|
|
|
|
private static HashSet<char> ControllerCharSet = new()
|
|
|
|
|
{
|
|
|
|
|
'{','}','(',')','[',']',
|
|
|
|
|
'+','-','*','/','%',
|
|
|
|
|
'=',
|
|
|
|
|
'!','<','>','&','|',
|
|
|
|
|
'^',
|
|
|
|
|
':',',','.','?',/*'\'','"',*/
|
|
|
|
|
'@','#','$',
|
2025-07-04 21:39:02 +08:00
|
|
|
|
';'
|
2025-07-03 21:50:26 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
public void ReadChar(char ch)
|
|
|
|
|
{
|
|
|
|
|
if (isOutOfStringline)
|
|
|
|
|
{
|
|
|
|
|
if (ControllerCharSet.Contains(ch))
|
|
|
|
|
CompleteSingleSymbol(ch);
|
2025-07-04 21:39:02 +08:00
|
|
|
|
else if (ch == '\n')
|
|
|
|
|
CompleteLine();
|
|
|
|
|
else if (char.IsWhiteSpace(ch) || ch == '\r' || ch == '\t')
|
2025-07-03 21:50:26 +08:00
|
|
|
|
CompleteWord();
|
|
|
|
|
else if (buffer.Length == 0 && ch == '"')
|
|
|
|
|
BeginString();
|
|
|
|
|
else if (char.IsLetter(ch) || char.IsDigit(ch))
|
|
|
|
|
PushChar(ch);
|
|
|
|
|
else
|
2025-07-04 21:39:02 +08:00
|
|
|
|
throw new NotImplementedException($"{lineContext + 1} line, {buffer} + <{ch}> not implemented");
|
2025-07-03 21:50:26 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ((buffer.Length > 0 && buffer.Last() == '\\') || ch != '"')
|
|
|
|
|
PushChar(ch);
|
|
|
|
|
else if (ch == '"')
|
|
|
|
|
EndString();
|
|
|
|
|
else
|
2025-07-04 21:39:02 +08:00
|
|
|
|
throw new NotImplementedException($"{lineContext + 1} line, \"{buffer}\" + \'{ch}\' not implemented");
|
2025-07-03 21:50:26 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CompleteSingleSymbol(char ch)
|
|
|
|
|
{
|
|
|
|
|
CompleteWord();
|
|
|
|
|
buffer = ch.ToString();
|
|
|
|
|
CompleteWord();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PushChar(char ch)
|
|
|
|
|
{
|
|
|
|
|
buffer += ch;
|
|
|
|
|
}
|
|
|
|
|
void CompleteWord()
|
|
|
|
|
{
|
|
|
|
|
if (buffer.Length > 0)
|
|
|
|
|
{
|
2025-07-04 21:39:02 +08:00
|
|
|
|
if (ScriptWords.TryGetValue(lineContext, out var line) == false)
|
|
|
|
|
{
|
|
|
|
|
ScriptWords.Add(lineContext, line = new());
|
|
|
|
|
}
|
|
|
|
|
if (Internal.Keyword.Keywords.TryGetValue(buffer, out var keyword))
|
|
|
|
|
{
|
2025-07-04 23:00:41 +08:00
|
|
|
|
line.Add(line.Count + 1, keyword.Clone() as Internal.Variable);
|
2025-07-04 21:39:02 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2025-07-04 23:00:41 +08:00
|
|
|
|
line.Add(line.Count + 1, new ScriptWordVariable(buffer));
|
2025-07-04 21:39:02 +08:00
|
|
|
|
}
|
2025-07-03 21:50:26 +08:00
|
|
|
|
buffer = "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void CompleteLine()
|
|
|
|
|
{
|
|
|
|
|
CompleteWord();
|
2025-07-04 21:39:02 +08:00
|
|
|
|
lineContext++; ;
|
2025-07-03 21:50:26 +08:00
|
|
|
|
}
|
|
|
|
|
void BeginString()
|
|
|
|
|
{
|
|
|
|
|
if (buffer.Length > 0)
|
|
|
|
|
throw new InvalidGrammarException($"String must start with nothing: {buffer}");
|
|
|
|
|
isOutOfStringline = false;
|
|
|
|
|
}
|
|
|
|
|
void EndString()
|
|
|
|
|
{
|
|
|
|
|
isOutOfStringline = true;
|
|
|
|
|
CompleteWord();
|
|
|
|
|
}
|
2025-07-04 21:39:02 +08:00
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Read Scope Words
|
|
|
|
|
|
|
|
|
|
public void CompleteScopeWord(SymbolizationContext rootContext)
|
|
|
|
|
{
|
|
|
|
|
int wordCounter = 1;
|
|
|
|
|
Internal.Keyword currentKey = null;
|
|
|
|
|
foreach(var line in ScriptWords)
|
|
|
|
|
{
|
|
|
|
|
foreach (var word in line.Value)
|
|
|
|
|
{
|
|
|
|
|
if (currentKey == null)
|
|
|
|
|
{
|
|
|
|
|
if(currentKey is Internal.Keyword cky)
|
|
|
|
|
{
|
|
|
|
|
currentKey = cky;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidGrammarException($"Line {line.Key}, word {wordCounter}: Expected a keyword, but got {word}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2025-07-04 23:00:41 +08:00
|
|
|
|
currentKey = currentKey.ControlContext(rootContext, line.Key, word.Key, word.Value);
|
2025-07-04 21:39:02 +08:00
|
|
|
|
}
|
|
|
|
|
wordCounter++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
2025-07-03 21:50:26 +08:00
|
|
|
|
}
|
|
|
|
|
}
|