/// <summary> /// Creates context condition from text representation /// </summary> /// <param name="sourceModuleSection">string representing module between left and right context</param> /// <param name="leftContextSection">string with names of modules which should be on left side of source</param> /// <param name="rightContextSection">string with names of modules which should be on right side of source</param> /// <returns>Delegate which returns true if given GenerationIndex meets condition described by provided /// representation</returns> /// <exception cref="ParserException">Thrown if some module in left or right context contains bracket</exception> internal Rule <T> .ContextCondition ParseContextCondition(string sourceModuleSection, string leftContextSection, string rightContextSection) { int sourceId = _moduleParser.GetModuleId( HelperMethods.ReadModuleName(sourceModuleSection, 0, out var tmp)); var leftContext = _moduleParser.ParseModules(leftContextSection); var leftContextIds = new List <int>(); foreach (var module in leftContext) { var details = module.Parameters; if (details != null && details.Length > 0) { throw new ParserException("Parameters are not allowed in context conditions"); } leftContextIds.Add(module.Id); } var rightContext = _moduleParser.ParseModules(rightContextSection); var rightContextIds = new List <int>(); foreach (var module in rightContext) { var details = module.Parameters; if (details != null && details.Length > 0) { throw new ParserException("Parameters are not allowed in context conditions"); } rightContextIds.Add(module.Id); } return(generationIndex => { if (generationIndex.Module.Id != sourceId) { return false; } int start = generationIndex.Index; //Not enough modules to the left of source module if (leftContextIds.Count > start) { return false; } //Not enough modules to the right of source module if (rightContextIds.Count > generationIndex.Count - start - 1) { return false; } for (int i = 0; i < leftContextIds.Count; i++) { if (generationIndex[start - i - 1].Id != leftContextIds[leftContext.Length - i - 1]) { return false; } } for (int i = 0; i < rightContextIds.Count; i++) { if (generationIndex[start + i + 1].Id != rightContextIds[i]) { return false; } } return true; }); }