using ln.collections; using ln.parse.tokenizer; using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace ln.application.configuration { public class ConfigurationParser { public ConfigurationContainer RootContainer { get; } public ConfigurationParser() { RootContainer = new ConfigurationContainer(); } public ConfigurationParser(ConfigurationContainer rootContainer) { RootContainer = rootContainer; } public void Parse(String source) { Parse(configurationTokenizer.Parse(source, (token) => !(token is Token.WhiteSpaceToken))); } public void Parse(Token[] tokens) { Queue queue = new Queue(tokens); ParseContainer(queue, RootContainer); } private void ParseContainer(Queue queue,ConfigurationContainer container) { Token identifier; while (queue.Count > 0) { identifier = queue.Dequeue(); if (identifier is Token.BracketToken && "}".Equals(identifier.Value)) return; if (identifier is Token.IdentifierToken) { Token t2 = queue.Dequeue(); if (t2 is Token.OperatorToken && ":".Equals(t2.Value)) { List arguments = new List(); Token arg; while (!(((arg = queue.Dequeue()) is Token.OperatorToken) && ";".Equals(arg.Value))) { arguments.Add(arg.NativeValue); } container.AddStatement(identifier.Value,arguments.ToArray()); } else { Token key = null; if (!t2.Is("{")) { key = t2; t2 = queue.Dequeue(); } if (!t2.Is("{")) { throw new FormatException(String.Format("expected '{{' at {0}", t2.TextPosition)); } ConfigurationContainer childContainer = new ConfigurationContainer(container,identifier.Value,key.NativeValue); ParseContainer(queue, childContainer); // if (queue.Count == 0) // throw new FormatException(String.Format("Missing '}}'")); } } else { throw new FormatException(String.Format("unexepected token: {0}", identifier.Value)); } } } static Tokenizer configurationTokenizer; static ConfigurationParser() { configurationTokenizer = Tokenizer.CreateDefaultTokenizer(); } } }