public FunctionGenerationInfo(FunctionNode function, double relevanceLevel) { Contract.Requires<ArgumentNullException>(function != null); Function = function; RelevanceLevel = relevanceLevel; }
public TemplateParserResult Parse(FunctionNode functionNode) { Contract.Requires<ArgumentNullException>(functionNode != null); Contract.Ensures(Contract.Result<TemplateParserResult>() != null); _networkContext = new TemplateParserNetworkNodeContext(functionNode); _currentSentence = null; _sentenceContext.Clear(); return ParseNode(functionNode); }
internal FunctionNode(TaleNode taleNode, string name, FunctionNode baseNode) : base((TalesNetwork)taleNode.Network, name, baseNode) { Network.Edges.Add(this, taleNode, Net.NetworkEdgeType.PartOf); _functionType = baseNode._functionType; _actionNodes = new FunctionNodeContextNodeCollection(this, NetworkEdgeType.Action); _agentNodes = new FunctionNodeContextNodeCollection(this, NetworkEdgeType.Agent); _recipientNodes = new FunctionNodeContextNodeCollection(this, NetworkEdgeType.Recipient); _locativeNodes = new FunctionNodeContextNodeCollection(this, NetworkEdgeType.Locative); }
private ITemplateParserContext ReplaceFunctionContext(FunctionNode function) { Contract.Assume(_currentContext != null); TemplateParserDictionaryContext dictionaryContext = new TemplateParserDictionaryContext(); // TODO: Необходимо добавить учет связи Is-Instance. NetworkNode[] stopNodes = { function.Network.Nodes.GetNode("Персонаж"), function.Network.Nodes.GetNode("Положительный персонаж"), function.Network.Nodes.GetNode("Отрицательный персонаж"), function.Network.Nodes.GetNode("Место"), function.Network.Nodes.GetNode("Действие") }; Action<IEnumerable<NetworkNode>, IEnumerable<NetworkNode>, NetworkEdgeType> fillDictionaryAction = (functionNodes, contextNodes, contextType) => { foreach (NetworkNode functionNode in functionNodes) { NetworkNode contextNode = contextNodes.FirstOrDefault( node => AreHaveCommonAncestor(functionNode, node, stopNodes)); if (contextNode != null && !functionNodes.Contains(contextNode)) { dictionaryContext.Add(contextType, contextNode); } else { dictionaryContext.Add(contextType, functionNode); } } }; // TODO: Пока не уверен, должны ли унаследованные контекстные вершины // также появляться в списке. fillDictionaryAction( function.Agents, _currentContext.ResolvedPersons, NetworkEdgeType.Agent); fillDictionaryAction( function.Recipients, _currentContext.ResolvedPersons, NetworkEdgeType.Recipient); fillDictionaryAction( function.Locatives, _currentContext.ResolvedLocatives, NetworkEdgeType.Locative); fillDictionaryAction( function.Actions, _currentContext.ResolvedActions, NetworkEdgeType.Action); //fillDictionaryAction(function.Recipients, _currentContext.Persons, NetworkEdgeType.Recipient); //fillDictionaryAction(function.Locatives, _currentContext.Locatives, NetworkEdgeType.Locative); //fillDictionaryAction(function.Actions, _currentContext.Actions, NetworkEdgeType.Action); return dictionaryContext; }
private void GetChildContextNode( IDictionary<FunctionNode, TemplateParserResult> parserResults, TaleNode currentTaleNode, FunctionNode baseFunctionNode, NetworkEdgeType edgeType, TemplateParserDictionaryContext newParserContext) { TemplateParserResult baseFunctionNodeParserResult = parserResults[baseFunctionNode]; var currentTaleContextNodes = new List<NetworkNode>(); var baseTaleContextNodes = baseFunctionNode.OutgoingEdges.GetEdges(edgeType).Select(edge => edge.EndNode); bool found = false; foreach (FunctionNode functionNode in currentTaleNode.Functions) { currentTaleContextNodes.AddRange(functionNode.OutgoingEdges.GetEdges(edgeType).Select(edge => edge.EndNode)); } foreach (NetworkNode baseTaleContextNode in baseTaleContextNodes) { if (currentTaleContextNodes.Any(node => node.IsInherit(baseTaleContextNode, false))) { NetworkNode currentNode = null; while (true) { NetworkEdge isAEdge = baseTaleContextNode.OutgoingEdges.GetEdge(NetworkEdgeType.IsA); if (isAEdge != null) { currentNode = isAEdge.StartNode; NetworkNode childNode = currentTaleContextNodes.FirstOrDefault(node => node == currentNode || node.BaseNode == currentNode); if (childNode != null) { found = true; newParserContext.Add(edgeType, childNode); break; } } if (isAEdge == null && currentNode != null) { found = true; newParserContext.Add(edgeType, currentNode); break; } } } } if (!found) { newParserContext.Add(edgeType, baseTaleContextNodes); } }
private string GenerateText(FunctionNode function) { Contract.Assume(_currentContext != null); // 1. Сначала выполняется операция замещения контекста. ITemplateParserContext parserContext = ReplaceFunctionContext(function); // 2. Запомним контекстные вершины текущей функции. // В последующем они будут использоваться для определения // соблюдения принципа монотонности. _currentContext.CurrentContextNodes.AddRange(parserContext.SelectMany(pair => pair.Value)); // 3. Затем текст функции генерируется с учетом измененного контекста. if (parserContext.Count == 0) { // TODO: Контекст генерации должен заполняться в любом случае. throw new InvalidOperationException(); //return _templateParser.Parse(function).Text; } else { return _templateParser.Parse(function, parserContext).Text; } }
protected override void LoadFromXElement(XElement xNetwork) { Contract.Requires<ArgumentNullException>(xNetwork != null); XNamespace xNamespace = SerializableObject.XNamespace; XElement xNodesBase = xNetwork.Element(xNamespace + "Nodes"); var xNodes = xNodesBase.Elements(xNamespace + "Node"); foreach (XElement xNode in xNodes) { XAttribute xNodeKindAttribute = xNode.Attribute("nodeKind"); NetworkNode networkNode = null; if (xNodeKindAttribute == null) { //networkNode = Nodes.Add(); throw new SerializationException(); } else { TaleNodeKind nodeKind = (TaleNodeKind)Enum.Parse(typeof(TaleNodeKind), xNodeKindAttribute.Value); switch (nodeKind) { case TaleNodeKind.Tale: networkNode = new TaleNode(this); break; case TaleNodeKind.TaleItem: networkNode = new TaleItemNode(this); break; case TaleNodeKind.Function: networkNode = new FunctionNode(this); break; } } networkNode.LoadFromXml(xNode); // TODO: Необходимо избавиться от этого костыля. if (!Nodes.Where(node => node.Id == networkNode.Id).Any()) { Nodes.Add(networkNode); } } XElement xEdgesBase = xNetwork.Element(xNamespace + "Edges"); var xEdges = xEdgesBase.Elements(xNamespace + "Edge"); foreach (XElement xEdge in xEdges) { NetworkEdge networkEdge = new TaleItemEdge(this); networkEdge.LoadFromXml(xEdge); // TODO: Необходимо избавиться от этого костыля. if (!Edges.Where(edge => edge.Id == networkEdge.Id).Any()) { Edges.Add(networkEdge); } } SetId(); _isDirty = false; _baseActionNode = (TaleItemNode)Nodes[0]; _baseLocativeNode = (TaleItemNode)Nodes[1]; _basePersonNode = (TaleItemNode)Nodes[2]; _baseFunctionNode = Nodes[3]; _baseTaleNode = Nodes[4]; _baseTemplateNode = Nodes[5]; }
private TemplateParserResult ParseNode(FunctionNode functionNode) { string template = functionNode.Template; Lexer lexer = new Lexer(template); LexerResult lexerResult = null; StringBuilder stringBuilder = new StringBuilder(DefaultTemplateBufferSize); List<NetworkEdgeType> unresolvedContext = new List<NetworkEdgeType>(); _currentSentence = new List<TemplateToken>(); while (lexer.ReadNextToken(out lexerResult)) { switch (lexerResult.Type) { case TokenType.Letter: stringBuilder.Append(lexerResult.Token); break; case TokenType.Colon: // TODO: Костыль. // В случае начала прямой речи, необходимо обновить контекст. stringBuilder.Append(lexerResult.Token); while (lexer.PeekNextToken(out lexerResult) && lexerResult.Type == TokenType.Space) { stringBuilder.Append(lexerResult.Token); } if (lexerResult.Type == TokenType.Quotes) { Contract.Assume(_currentSentence != null); _sentenceContext.Add(_currentSentence); _currentSentence = new List<TemplateToken>(); stringBuilder.Append(lexerResult.Token); } break; case TokenType.Space: case TokenType.Punctuation: stringBuilder.Append(lexerResult.Token); break; case TokenType.Point: Contract.Assume(_currentSentence != null); _sentenceContext.Add(_currentSentence); _currentSentence = new List<TemplateToken>(); stringBuilder.Append(lexerResult.Token); break; case TokenType.LeftBrace: StringBuilder templateBuilder = new StringBuilder(128); bool isOk = false; while (lexer.ReadNextToken(out lexerResult)) { if (lexerResult.Type == TokenType.RightBrace) { isOk = true; break; } templateBuilder.Append(lexerResult.Token); } if (!isOk) { throw new TemplateParserException(); } TemplateParserPluginResult parserResult = ParseTemplateItem(templateBuilder.ToString()); if (parserResult.Text == null) { unresolvedContext.AddRange(parserResult.UnresolvedContext); } else { _currentSentence.AddRange(parserResult.TemplateTokens); stringBuilder.Append(parserResult.Text); } break; } } if (_currentSentence != null && _currentSentence.Count > 0) { _sentenceContext.Add(_currentSentence); } return new TemplateParserResult(stringBuilder.ToString(), _sentenceContext, unresolvedContext); }