//----------------------------------------------------------------------- // ----------------------------------------------------------------------- // file="ExpSchemaSource" // Project: StgSharp // AuthorGroup: Nitload Space // Copyright (c) Nitload Space. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- using StgSharp.Collections; using StgSharp.Graphics.OpenGL; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.Tracing; using System.Text; using System.Text.RegularExpressions; namespace StgSharp.Script.Express { public partial class ExpSchemaSource { private static Regex _constDefineBegin = GetConstDefineBegin(), _constDefineEnd = GetConstDefineEnd(), _schemaBegin = GetSchemaBegin(), _schemaEnd = GetSchemaEnd(), _entityDefineBegin = GetEntityDefineBegin(), _entityDefineEnd = GetEntityDefineEnd(), _typeDefineBegin = GetTypeDefineBegin(), _typeDefineEnd = GetTypeDefineEnd(), _functionDefineBegin = GetFunctionDefineBegin(), _functionDefineEnd = GetFunctionDefineEnd(), _ruleDefineBegin = GetRuleDefineBegin(), _ruleDefineEnd = GetRuleDefineEnd(); private readonly GeneratedExpSchema _compileResult = new GeneratedExpSchema(); private List _sourceCache = []; private string name; public ExpSchemaSource() { } public List Cache { get => _sourceCache; } public string Name { get => _compileResult.Name; internal set => _compileResult.Name = value; } public ExpSchema Organize() { _compileResult.LoadFromSource(this); return _compileResult; } public void ReadSchema(ExpFileSource reader) { string line = reader.ReadLine(); while (!_schemaBegin.IsMatch(line)) { line = reader.ReadLine(); } name = _schemaBegin.Match(line).Groups["namespace"].Value; while (!_schemaEnd.IsMatch(line)) { if (TryReadConst(line, reader, out IExpElementSource source)) { _sourceCache.Add(source); } else if (TryReadType(line, reader, out source)) { _sourceCache.Add(source); } else if (TryReadEntity(line, reader, out source)) { _sourceCache.Add(source); } else if (TryReadRule(line, reader, out source)) { _sourceCache.Add(source); } else if (TryReadFunction(line, reader, out source)) { _sourceCache.Add(source); } line = reader.ReadLine(); } } public static bool TryReadSchema(string firstLine, ExpFileSource reader, out ExpSchemaSource source) { if (!_schemaBegin.IsMatch(firstLine)) { source = null!; return false; } ExpSchemaSource _source = new ExpSchemaSource(); _source.name = _schemaBegin.Match(firstLine).Groups["namespace"].Value; while (!_schemaEnd.IsMatch(firstLine)) { if (_source.TryReadConst(firstLine, reader, out IExpElementSource _elementSource)) { _source._sourceCache.Add(_elementSource); } else if (_source.TryReadType(firstLine, reader, out _elementSource)) { _source._sourceCache.Add(_elementSource); } else if (_source.TryReadEntity(firstLine, reader, out _elementSource)) { _source._sourceCache.Add(_elementSource); } else if (_source.TryReadRule(firstLine, reader, out _elementSource)) { _source._sourceCache.Add(_elementSource); } else if (_source.TryReadFunction(firstLine, reader, out _elementSource)) { _source._sourceCache.Add(_elementSource); } firstLine = reader.ReadLine(); } source = _source; return true; } [GeneratedRegex(@"\s*CONSTANT")] private static partial Regex GetConstDefineBegin(); [GeneratedRegex(@"\s*END_CONSTANT;")] private static partial Regex GetConstDefineEnd(); [GeneratedRegex(@"\s*ENTITY\s*(?[A-Za-z0-9_]+)\s*", RegexOptions.Compiled)] private static partial Regex GetEntityDefineBegin(); [GeneratedRegex(@"\s*END_ENTITY;\s*--\s*(?[A-Za-z0-9_]+)\s*", RegexOptions.Compiled)] private static partial Regex GetEntityDefineEnd(); [GeneratedRegex(@"\s*FUNCTION\s*\s*(?[a-zA-Z0-9_]+)\s*(?.*)", RegexOptions.Compiled)] private static partial Regex GetFunctionDefineBegin(); [GeneratedRegex(@"\s*END_FUNCTION\s*;\s*--\s*(?[a-zA-Z0-9_]+)", RegexOptions.Compiled)] private static partial Regex GetFunctionDefineEnd(); [GeneratedRegex( @"\s*RULE\s*(?[a-zA-Z0-9_]+)\s*FOR\s*\((?[a-zA-Z0-9_]*(?:\s*\)\s*;)?)", RegexOptions.Compiled)] private static partial Regex GetRuleDefineBegin(); [GeneratedRegex(@"\s*END_RULE\s*;\s*--\s*(?[A-Za-z0-9_]+)", RegexOptions.Compiled)] private static partial Regex GetRuleDefineEnd(); [GeneratedRegex(@"\s*SCHEMA\s*(?[A-Za-z0-9_]+)\s?;")] private static partial Regex GetSchemaBegin(); [GeneratedRegex(@"END_SCHEMA;\s*--\s*(?[A-Za-z0-9_]+)", RegexOptions.Compiled)] private static partial Regex GetSchemaEnd(); [GeneratedRegex(@"\s*TYPE\s+(?[A-Za-z0-9_]+)\s*=\s*(?[A-Z]+)", RegexOptions.Compiled)] private static partial Regex GetTypeDefineBegin(); [GeneratedRegex(@"\s*END_TYPE\s*;\s*--\s*(?[a-zA-Z0-9_]+)", RegexOptions.Compiled)] private static partial Regex GetTypeDefineEnd(); private bool TryReadConst(string firstLine, ExpFileSource reader, out IExpElementSource source) { Match match = _constDefineBegin.Match(firstLine); if (match.Success) { ScriptSourceTransmitter transmitter = new ScriptSourceTransmitter( "END_CONSTANT", reader.Location); ExpConstantCollectionSource _source = new ExpConstantCollectionSource(transmitter); string line = reader.ReadLine(); while (!_constDefineEnd.IsMatch(line)) { transmitter.WriteLine(line); line = reader.ReadLine(); } transmitter.WriteLine("END_CONSTANT"); source = _source; return true; } source = null!; return false; } private bool TryReadEntity(string firstLine, ExpFileSource reader, out IExpElementSource source) { Match match = _entityDefineBegin.Match(firstLine); if (match.Success) { ScriptSourceTransmitter transmitter = new ScriptSourceTransmitter( "END_ENTITY", reader.Location); ExpEntitySource _source = new ExpEntitySource( match.Groups["TypeName"].ToString(), transmitter); string line = reader.ReadLine(); match = _entityDefineEnd.Match(line); while (!match.Success) { transmitter.WriteLine(line); line = reader.ReadLine(); match = _entityDefineEnd.Match(line); } string endedName = match.Groups["TypeName"].ToString(); if (!string.Equals(endedName, _source.Name)) { throw new ExpInvalidElementDeclareEndingExceptions(_source.Name, endedName); } transmitter.WriteLine("END_ENTITY"); source = _source; return true; } source = null!; return false; } private bool TryReadFunction(string firstLine, ExpFileSource reader, out IExpElementSource source) { Match match = _functionDefineBegin.Match(firstLine); if (match.Success) { ScriptSourceTransmitter transmitter = new ScriptSourceTransmitter( "END_FUNCTION", reader.Location); ExpFunctionSource _source = new ExpFunctionSource( match.Groups["FunctionName"].ToString(), transmitter); transmitter.WriteLine(match.Groups["Remaining"].ToString()); string line = reader.ReadLine(); match = _functionDefineEnd.Match(line); while (!match.Success) { transmitter.WriteLine(line); line = reader.ReadLine(); match = _functionDefineEnd.Match(line); } string endedName = match.Groups["FunctionName"].ToString(); if (!string.Equals(endedName, _source.Name)) { throw new ExpInvalidElementDeclareEndingExceptions(_source.Name, endedName); } transmitter.WriteLine("END_FUNCTION"); source = _source; return true; } source = null!; return false; } private bool TryReadRule(string firstLine, ExpFileSource reader, out IExpElementSource source) { Match match = _ruleDefineBegin.Match(firstLine); if (match.Success) { ScriptSourceTransmitter transmitter = new ScriptSourceTransmitter( "END_RULE", reader.Location); ExpRuleSource _source = new ExpRuleSource( match.Groups["RuleName"].ToString(), transmitter); string target = match.Groups["Target"].ToString(); if (!string.IsNullOrEmpty(target)) { transmitter.WriteLine(target); } string line = reader.ReadLine(); match = _ruleDefineEnd.Match(line); while (!match.Success) { transmitter.WriteLine(line); line = reader.ReadLine(); match = _ruleDefineEnd.Match(line); } string endedName = match.Groups["RuleName"].ToString(); if (!string.Equals(endedName, _source.Name)) { throw new ExpInvalidElementDeclareEndingExceptions(_source.Name, endedName); } transmitter.WriteLine("END_RULE"); source = _source; return true; } source = null!; return false; } private bool TryReadType(string firstLine, ExpFileSource reader, out IExpElementSource source) { Match match = _typeDefineBegin.Match(firstLine); if (match.Success) { ScriptSourceTransmitter transmitter = new ScriptSourceTransmitter( "END_ENTITY", reader.Location); ExpTypeSource _source = new ExpTypeSource( match.Groups["TypeName"].ToString(), transmitter); transmitter.WriteLine(match.Groups["Remaining"].ToString()); string line = reader.ReadLine(); match = _typeDefineEnd.Match(line); while (!match.Success) { transmitter.WriteLine(line); line = reader.ReadLine(); match = _typeDefineEnd.Match(line); } string endedName = match.Groups["TypeName"].ToString(); if (!string.Equals(endedName, _source.Name)) { throw new ExpInvalidElementDeclareEndingExceptions(_source.Name, endedName); } transmitter.WriteLine("END_ENTITY"); source = _source; return true; } source = null!; return false; } } }