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 ScriptWords = new(); private readonly static HashSet 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> 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 } }