diff --git a/Convention/[Symbolization]/Detail/Keyword.cs b/Convention/[Symbolization]/Detail/Keyword.cs index 274ed7b..0b20edd 100644 --- a/Convention/[Symbolization]/Detail/Keyword.cs +++ b/Convention/[Symbolization]/Detail/Keyword.cs @@ -1,6 +1,7 @@ using System; -using System.IO; using System.Collections.Generic; +using System.IO; +using static System.Net.Mime.MediaTypeNames; namespace Convention.Symbolization.Internal { @@ -10,17 +11,17 @@ namespace Convention.Symbolization.Internal public static readonly Dictionary Keywords = new() { - { "import", new Convention.Symbolization.Keyword.Import() }, - { "namespace", new Convention.Symbolization.Keyword.Namespace() }, - { "def", new Convention.Symbolization.Keyword.FunctionDef() }, - { "return", new Convention.Symbolization.Keyword.Return() }, - { "if", new Convention.Symbolization.Keyword.If() }, - { "elif", new Convention.Symbolization.Keyword.Elif() }, - { "else", new Convention.Symbolization.Keyword.Else() }, - { "while", new Convention.Symbolization.Keyword.While() }, - { "break", new Convention.Symbolization.Keyword.Break() }, - { "continue", new Convention.Symbolization.Keyword.Continue() }, - { "struct", new Convention.Symbolization.Keyword.Structure() } + { "import", new Convention.Symbolization.Keyword.Import(0,0) }, + { "namespace", new Convention.Symbolization.Keyword.Namespace(0,0) }, + { "def", new Convention.Symbolization.Keyword.FunctionDef(0,0) }, + { "return", new Convention.Symbolization.Keyword.Return(0,0) }, + { "if", new Convention.Symbolization.Keyword.If(0,0) }, + { "elif", new Convention.Symbolization.Keyword.Elif(0,0) }, + { "else", new Convention.Symbolization.Keyword.Else(0,0) }, + { "while", new Convention.Symbolization.Keyword.While(0,0) }, + { "break", new Convention.Symbolization.Keyword.Break(0,0) }, + { "continue", new Convention.Symbolization.Keyword.Continue(0,0) }, + { "struct", new Convention.Symbolization.Keyword.Structure(0,0) } }; public override bool Equals(Keyword other) @@ -28,19 +29,14 @@ namespace Convention.Symbolization.Internal return this.GetType() == other.GetType(); } - public virtual bool ControlScope(SymbolizationContext context, int line, int wordIndex, Variable next) - { - return ControlScope(context, next); - } - protected virtual bool ControlScope(SymbolizationContext context, Variable next) - { - return true; - } + public abstract bool ControlScope(Variable next); + + public abstract void BuildScope(SymbolizationContext context, List scopeWords); } public abstract class Keyword : Keyword where T : Keyword { - protected Keyword(string keyword,int lineIndex,int wordIndex) : base(keyword, lineIndex, wordIndex) { } + protected Keyword(string keyword, int lineIndex, int wordIndex) : base(keyword, lineIndex, wordIndex) { } public override bool Equals(Variable other) { @@ -53,33 +49,47 @@ namespace Convention.Symbolization.Keyword { public abstract class SingleKeyword : Internal.Keyword where T : SingleKeyword { - protected SingleKeyword(string keyword,int lineIndex,int wordIndex) : base(keyword, lineIndex, wordIndex) + protected SingleKeyword(string keyword, int lineIndex, int wordIndex) : base(keyword, lineIndex, wordIndex) { } - protected override bool ControlScope(SymbolizationContext context, Internal.Variable next) + public override bool ControlScope(Internal.Variable next) { - if (next is not Internal.ScriptWordVariable swv ||swv.Word!=";") - throw new InvalidGrammarException($"Expected ';' but got {next}"); - return true; + if (next is Internal.ScriptWordVariable swv && swv.Word == ";") + return true; + throw new InvalidGrammarException($"Expected ';' but got {next}"); + } + + public abstract void BuildScope(); + + public sealed override void BuildScope(SymbolizationContext context, List scopeWords) + { + BuildScope(); } } public abstract class SentenceKeyword : Internal.Keyword where T : SentenceKeyword { - protected SentenceKeyword(string keyword,int lineIndex,int wordIndex) : base(keyword, lineIndex, wordIndex) + protected SentenceKeyword(string keyword, int lineIndex, int wordIndex) : base(keyword, lineIndex, wordIndex) { } - protected override bool ControlScope(SymbolizationContext context, Internal.Variable next) + public override bool ControlScope(Internal.Variable next) { if (next is not Internal.ScriptWordVariable swv) throw new InvalidGrammarException($"Not expected a key Word: {next}"); return swv.Word != ";"; } + + public abstract void BuildSentence(SymbolizationContext context, List sentence); + + public sealed override void BuildScope(SymbolizationContext context, List scopeWords) + { + BuildSentence(context, scopeWords.GetRange(0, scopeWords.Count - 1)); + } } public abstract class NamespaceKeyword : Internal.Keyword where T : NamespaceKeyword { - protected NamespaceKeyword(string keyword,int lineIndex,int wordIndex) : base(keyword, lineIndex, wordIndex) + protected NamespaceKeyword(string keyword, int lineIndex, int wordIndex) : base(keyword, lineIndex, wordIndex) { } private enum Pause @@ -90,7 +100,7 @@ namespace Convention.Symbolization.Keyword private Pause pause = Pause.Name; private int layer = 0; - protected override bool ControlScope(SymbolizationContext context, Internal.Variable next) + public override bool ControlScope(Internal.Variable next) { if (pause == Pause.Name) { @@ -124,11 +134,58 @@ namespace Convention.Symbolization.Keyword return true; } } + + public abstract void BuildSpace( + SymbolizationContext context, + List spaceExpression, + Dictionary scopeStartAndEnd, + List insideScopeWords + ); + + public override void BuildScope(SymbolizationContext context, List scopeWords) + { + List spaceExpression = new(); + Dictionary scopeStartAndEnd = new(); + Stack stack = new(); + bool IsSpaceExpression = true; + foreach (var word in scopeWords) + { + var swv = word as Internal.ScriptWordVariable; + if (IsSpaceExpression) + { + if (swv.Word == "{") + { + IsSpaceExpression = false; + stack.Push(swv); + layer++; + } + else + { + spaceExpression.Add(swv); + } + } + else + { + if (swv.Word == "{") + { + stack.Push(swv); + layer++; + } + else if (swv.Word == "}") + { + scopeStartAndEnd.Add(stack.Pop(), swv); + layer--; + } + } + } + BuildSpace(context, spaceExpression, scopeStartAndEnd, + scopeWords.GetRange(spaceExpression.Count, scopeWords.Count - spaceExpression.Count)); + } } public abstract class VerbObjectScopeKeyword : Internal.Keyword where T : VerbObjectScopeKeyword { - protected VerbObjectScopeKeyword(string keyword,int lineIndex,int wordIndex) : base(keyword, lineIndex, wordIndex) + protected VerbObjectScopeKeyword(string keyword, int lineIndex, int wordIndex) : base(keyword, lineIndex, wordIndex) { } @@ -140,7 +197,7 @@ namespace Convention.Symbolization.Keyword private Pause pause = Pause.BeforeExpression; private int layer = 0; - protected override bool ControlScope(SymbolizationContext context, Internal.Variable next) + public override bool ControlScope(Internal.Variable next) { if (pause == Pause.BeforeExpression) { @@ -191,6 +248,62 @@ namespace Convention.Symbolization.Keyword } return true; } + + public override void BuildScope(SymbolizationContext context, List scopeWords) + { + pause = Pause.BeforeExpression; + layer = 0; + foreach (var word in scopeWords) + { + if (pause == Pause.BeforeExpression) + { + if (next is not Internal.ScriptWordVariable swv) + throw new InvalidGrammarException($"Not expected a key Word: {next}"); + if (swv.Word == "(") + pause = Pause.Expression; + else + throw new InvalidGrammarException($"Expected '(' symbol for expression start, but got {next}"); + } + else if (pause == Pause.Expression) + { + if (next is Internal.ScriptWordVariable swv && swv.Word == ")") + { + pause = Pause.BeforeBody; + } + } + else if (pause == Pause.BeforeBody) + { + if (next is not Internal.ScriptWordVariable swv) + throw new InvalidGrammarException($"Not expected keyword for body start, but got {next}"); + if (swv.Word == "{") + { + pause = Pause.Body; + layer++; + } + else + pause = Pause.SingleSentence; + } + else if (pause == Pause.Body) + { + if (next is Internal.ScriptWordVariable swv) + { + if (swv.Word == "{") + layer++; + else if (swv.Word == "}") + layer--; + if (layer == 0) + return false; + } + } + else if (pause == Pause.SingleSentence) + { + if (next is Internal.ScriptWordVariable swv && swv.Word == ";") + { + return false; + } + } + } + } } /// @@ -198,7 +311,7 @@ namespace Convention.Symbolization.Keyword /// public sealed class Import : SentenceKeyword { - public Import(int lineIndex,int wordIndex) : base("import",lineIndex,wordIndex) + public Import(int lineIndex, int wordIndex) : base("import", lineIndex, wordIndex) { } @@ -213,7 +326,7 @@ namespace Convention.Symbolization.Keyword /// public sealed class Namespace : NamespaceKeyword { - public Namespace(int lineIndex,int wordIndex) : base("namespace", lineIndex, wordIndex) + public Namespace(int lineIndex, int wordIndex) : base("namespace", lineIndex, wordIndex) { } public override Internal.Keyword CloneVariable(string targetSymbolName, int lineIndex, int wordIndex) @@ -227,7 +340,7 @@ namespace Convention.Symbolization.Keyword /// public sealed class FunctionDef : NamespaceKeyword { - public FunctionDef(int lineIndex,int wordIndex) : base("def", lineIndex, wordIndex) + public FunctionDef(int lineIndex, int wordIndex) : base("def", lineIndex, wordIndex) { } public override Internal.Keyword CloneVariable(string targetSymbolName, int lineIndex, int wordIndex) @@ -241,7 +354,7 @@ namespace Convention.Symbolization.Keyword /// public sealed class Return : SentenceKeyword { - public Return(int lineIndex,int wordIndex) : base("return", lineIndex, wordIndex) + public Return(int lineIndex, int wordIndex) : base("return", lineIndex, wordIndex) { } public override Internal.Keyword CloneVariable(string targetSymbolName, int lineIndex, int wordIndex) @@ -255,7 +368,7 @@ namespace Convention.Symbolization.Keyword /// public sealed class If : VerbObjectScopeKeyword { - public If(int lineIndex,int wordIndex) : base("if", lineIndex, wordIndex) + public If(int lineIndex, int wordIndex) : base("if", lineIndex, wordIndex) { } public override Internal.Keyword CloneVariable(string targetSymbolName, int lineIndex, int wordIndex) @@ -270,7 +383,7 @@ namespace Convention.Symbolization.Keyword /// public sealed class Elif : VerbObjectScopeKeyword { - public Elif(int lineIndex,int wordIndex) : base("elif", lineIndex, wordIndex) + public Elif(int lineIndex, int wordIndex) : base("elif", lineIndex, wordIndex) { } public override Internal.Keyword CloneVariable(string targetSymbolName, int lineIndex, int wordIndex) @@ -285,7 +398,7 @@ namespace Convention.Symbolization.Keyword /// public sealed class Else : NamespaceKeyword { - public Else(int lineIndex,int wordIndex) : base("else", lineIndex, wordIndex) + public Else(int lineIndex, int wordIndex) : base("else", lineIndex, wordIndex) { } public override Internal.Keyword CloneVariable(string targetSymbolName, int lineIndex, int wordIndex) @@ -299,7 +412,7 @@ namespace Convention.Symbolization.Keyword /// public sealed class While : VerbObjectScopeKeyword { - public While(int lineIndex,int wordIndex) : base("while", lineIndex, wordIndex) + public While(int lineIndex, int wordIndex) : base("while", lineIndex, wordIndex) { } public override Internal.Keyword CloneVariable(string targetSymbolName, int lineIndex, int wordIndex) @@ -313,7 +426,7 @@ namespace Convention.Symbolization.Keyword /// public sealed class Break : SingleKeyword { - public Break(int lineIndex,int wordIndex) : base("break", lineIndex, wordIndex) + public Break(int lineIndex, int wordIndex) : base("break", lineIndex, wordIndex) { } public override Internal.Keyword CloneVariable(string targetSymbolName, int lineIndex, int wordIndex) @@ -327,7 +440,7 @@ namespace Convention.Symbolization.Keyword /// public sealed class Continue : SingleKeyword { - public Continue(int lineIndex,int wordIndex) : base("continue", lineIndex, wordIndex) + public Continue(int lineIndex, int wordIndex) : base("continue", lineIndex, wordIndex) { } public override Internal.Keyword CloneVariable(string targetSymbolName, int lineIndex, int wordIndex) @@ -341,7 +454,7 @@ namespace Convention.Symbolization.Keyword /// public sealed class Structure : NamespaceKeyword { - public Structure(int lineIndex,int wordIndex) : base("struct", lineIndex, wordIndex) + public Structure(int lineIndex, int wordIndex) : base("struct", lineIndex, wordIndex) { } public override Internal.Keyword CloneVariable(string targetSymbolName, int lineIndex, int wordIndex) diff --git a/Convention/[Symbolization]/Runner/SymbolizationContext.cs b/Convention/[Symbolization]/Runner/SymbolizationContext.cs index c9989b6..7c8878b 100644 --- a/Convention/[Symbolization]/Runner/SymbolizationContext.cs +++ b/Convention/[Symbolization]/Runner/SymbolizationContext.cs @@ -17,27 +17,49 @@ namespace Convention.Symbolization private readonly SymbolizationContext ParentContext; public readonly Internal.Namespace CurrentNamespace; - private void Compile(Internal.SymbolizationReader reader) + private void CompileToParent() { - reader.CompleteScopeWord(this); + if (ParentContext == null) + return; } - public void Compile(Dictionary> scriptWords) + // Compile begin at scope words to sub context + public void Compile(Dictionary> scopeWords) { - // Turn the script words into scope words - Compile(new Internal.SymbolizationReader() { ScriptWords = scriptWords }); + foreach (var (keyword, words) in scopeWords) + { + + } } + // Compile begin at script words to scope words + private void CompileBeginAtScript2Scope(Internal.SymbolizationReader reader) + { + foreach (var word in reader.ScriptWords) + { + reader.ReadWord(word); + } + this.Compile(reader.ScopeWords); + } + + // Compile begin at script words to scope words + public void Compile(List scriptWords) + { + this.CompileBeginAtScript2Scope(new() { ScriptWords = scriptWords }); + } + + // Compile begin at text to script words public void Compile(string allText) { - // Create a new reader to parse the script words Internal.SymbolizationReader reader = new(); + reader ??= new(); foreach (char ch in allText) reader.ReadChar(ch); // Turn the script words into scope words - Compile(reader); + this.CompileBeginAtScript2Scope(reader); } + // Compile begin at text to script words public void Compile(ToolFile file) { if (file.Exists() == false) diff --git a/Convention/[Symbolization]/Runner/SymbolizationReader.cs b/Convention/[Symbolization]/Runner/SymbolizationReader.cs index 4f6dd2e..45f0801 100644 --- a/Convention/[Symbolization]/Runner/SymbolizationReader.cs +++ b/Convention/[Symbolization]/Runner/SymbolizationReader.cs @@ -12,10 +12,11 @@ namespace Convention.Symbolization.Internal private string buffer = ""; private int lineContext = 1; + private int wordContext = 0; private bool isOutOfStringline = true; - public Dictionary> ScriptWords = new() { { 1, new() } }; + public List ScriptWords = new(); - private static HashSet ControllerCharSet = new() + private readonly static HashSet ControllerCharSet = new() { '{','}','(',')','[',']', '+','-','*','/','%', @@ -61,7 +62,6 @@ namespace Convention.Symbolization.Internal buffer = ch.ToString(); CompleteWord(); } - void PushChar(char ch) { buffer += ch; @@ -70,25 +70,23 @@ namespace Convention.Symbolization.Internal { if (buffer.Length > 0) { - if (ScriptWords.TryGetValue(lineContext, out var line) == false) - { - ScriptWords.Add(lineContext, line = new()); - } if (Internal.Keyword.Keywords.TryGetValue(buffer, out var keyword)) { - line.Add(line.Count + 1, keyword.Clone() as Internal.Variable); + ScriptWords.Add(keyword.CloneVariable(buffer, lineContext, wordContext)); } else { - line.Add(line.Count + 1, new ScriptWordVariable(buffer)); + ScriptWords.Add(new ScriptWordVariable(buffer, lineContext, wordContext + 1)); } buffer = ""; + wordContext++; } } void CompleteLine() { CompleteWord(); - lineContext++; ; + lineContext++; + wordContext = 0; } void BeginString() { @@ -106,52 +104,31 @@ namespace Convention.Symbolization.Internal #region Read Scope Words - public class KeywordEntry - { - public int line = 1; - public int wordIndex = 1; - public Dictionary> Container = new(); - public KeywordEntry(int line, int wordIndex) - { - this.line = line; - this.wordIndex = wordIndex; - } - } + public Dictionary> ScopeWords = new(); + public Keyword currentKey = null; + public bool isNextKeyword = true; - public void CompleteScopeWord(SymbolizationContext rootContext) + public void ReadWord(Variable word) { - Dictionary ScopeWords = new(); - Keyword currentKey = null; - bool isNextKeyword = true; - foreach(var line in ScriptWords) + if (isNextKeyword) { - int wordCounter = 1; - foreach (var word in line.Value) + if (word is Keyword cky) { - if (isNextKeyword) - { - if (word.Value is Keyword cky) - { - currentKey = cky; - ScopeWords.Add(currentKey, new(line.Key, wordCounter)); - isNextKeyword = false; - } - else - { - throw new InvalidGrammarException($"Line {line.Key}, Word {wordCounter}: Expected a keyword, but got {word.Value}"); - } - } - else - { - var container = ScopeWords[currentKey].Container; - if (container.ContainsKey(line.Key) == false) - container.Add(line.Key, new() { { wordCounter, word.Value } }); - else - container[line.Key][wordCounter] = word.Value; - isNextKeyword = currentKey.ControlScope(rootContext, line.Key, word.Key, word.Value) == false; - } - wordCounter++; + 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; } } diff --git a/[Test]/Program.cs b/[Test]/Program.cs index 4520452..3e72f3a 100644 --- a/[Test]/Program.cs +++ b/[Test]/Program.cs @@ -10,10 +10,10 @@ public class Program { static void Main(string[] args) { - var context = new SymbolizationRunner(); + var runner = new SymbolizationRunner(); try { - context.Compile("example_script.txt"); + runner.Compile("example_script.txt"); Console.WriteLine("Script compiled successfully."); } catch (FileNotFoundException ex)