Files
Convention-CSharp/Convention/[Symbolization]/Runner/SymbolizationReader.cs

138 lines
4.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Convention.Symbolization.Internal
{
public class SymbolizationReader
{
#region Read Script Words
private string buffer = "";
private int lineContext = 1;
private int wordContext = 0;
private bool isOutOfStringline = true;
public List<Variable> ScriptWords = new();
private readonly static HashSet<char> ControllerCharSet = new()
{
'{','}','(',')','[',']',
'+','-','*','/','%',
'=',
'!','<','>','&','|',
'^',
':',',','.','?',/*'\'','"',*/
'@','#','$',
';'
};
public void ReadChar(char ch)
{
if (isOutOfStringline)
{
if (ControllerCharSet.Contains(ch))
CompleteSingleSymbol(ch);
else if (ch == '\n')
CompleteLine();
else if (char.IsWhiteSpace(ch) || ch == '\r' || ch == '\t')
CompleteWord();
else if (buffer.Length == 0 && ch == '"')
BeginString();
else if (char.IsLetter(ch) || char.IsDigit(ch))
PushChar(ch);
else
throw new NotImplementedException($"{lineContext + 1} line, {buffer} + <{ch}> not implemented");
}
else
{
if ((buffer.Length > 0 && buffer.Last() == '\\') || ch != '"')
PushChar(ch);
else if (ch == '"')
EndString();
else
throw new NotImplementedException($"{lineContext + 1} line, \"{buffer}\" + \'{ch}\' not implemented");
}
}
void CompleteSingleSymbol(char ch)
{
CompleteWord();
buffer = ch.ToString();
CompleteWord();
}
void PushChar(char ch)
{
buffer += ch;
}
void CompleteWord()
{
if (buffer.Length > 0)
{
if (Internal.Keyword.Keywords.TryGetValue(buffer, out var keyword))
{
ScriptWords.Add(keyword.CloneVariable(buffer, lineContext, wordContext));
}
else
{
ScriptWords.Add(new ScriptWordVariable(buffer, lineContext, wordContext + 1));
}
buffer = "";
wordContext++;
}
}
void CompleteLine()
{
CompleteWord();
lineContext++;
wordContext = 0;
}
void BeginString()
{
if (buffer.Length > 0)
throw new InvalidGrammarException($"String must start with nothing: {buffer}");
isOutOfStringline = false;
}
void EndString()
{
isOutOfStringline = true;
CompleteWord();
}
#endregion
#region Read Scope Words
public Dictionary<Keyword, List<Variable>> ScopeWords = new();
public Keyword currentKey = null;
public bool isNextKeyword = true;
public void ReadWord(Variable word)
{
if (isNextKeyword)
{
if (word is Keyword cky)
{
currentKey = cky;
ScopeWords.Add(currentKey, new());
isNextKeyword = false;
}
else
{
throw new InvalidGrammarException(
$"Line {word.SymbolInfo.LineIndex}, Word {word.SymbolInfo.WordIndex}: Expected a keyword, but got {word}"
);
}
}
else
{
ScopeWords[currentKey].Add(word);
isNextKeyword = currentKey.ControlScope(word) == false;
}
}
#endregion
}
}