add: 实现空转移

This commit is contained in:
jackfiled 2023-10-23 13:57:13 +08:00
parent ea516e1bbc
commit ad0b29c10d
4 changed files with 102 additions and 77 deletions

View File

@ -1,8 +1,7 @@
using System.Text.RegularExpressions;
using Katheryne.Abstractions;
using Katheryne.Models;
using Katheryne.Services;
using Microsoft.Extensions.Logging;
using YamlDotNet.Serialization;
namespace Katheryne;
@ -28,7 +27,7 @@ public class KatheryneChatRobot : IChatRobot
{
return new[]
{
_grammarTree[_currentStage]
_grammarTree[_currentStage].Answer
};
}
@ -42,13 +41,51 @@ public class KatheryneChatRobot : IChatRobot
public IEnumerable<string> ChatNext(string input)
{
_logger.LogDebug("Receive input {} on stage {}.", input, _currentStage);
(_currentStage, string answer) = _grammarTree.NextStage(_currentStage, input);
_logger.LogDebug("Change stage to {}.", _currentStage);
List<string> result = new();
return new[]
foreach (InnerTransformer transformer in _grammarTree[_currentStage].Transformers)
{
answer
};
if (transformer.Pattern is null)
{
continue;
}
Match match = transformer.Pattern.Match(input);
if (match.Success)
{
_currentStage = transformer.NextStage;
result.Add(_grammarTree[_currentStage].Answer);
_logger.LogDebug("Moving to stage {}.", _currentStage);
}
}
EmptyTransform(result);
return result;
}
/// <summary>
/// 进行当前阶段的空转移
/// </summary>
/// <param name="result">存放输出回答的列表</param>
private void EmptyTransform(List<string> result)
{
var flag = true;
while (flag)
{
flag = false;
foreach (InnerTransformer transformer in _grammarTree[_currentStage].Transformers)
{
if (string.IsNullOrEmpty(transformer.RowPattern))
{
flag = true;
_currentStage = transformer.NextStage;
result.Add(_grammarTree[_currentStage].Answer);
_logger.LogDebug("Moving to stage {} with empty transform.", _currentStage);
break;
}
}
}
}
}

View File

@ -1,4 +1,3 @@
using System.Text.RegularExpressions;
using Katheryne.Exceptions;
namespace Katheryne.Models;
@ -19,33 +18,9 @@ public class GrammarTree
throw new GrammarException("使用了未声明的阶段名");
}
}
/// <summary>
/// 获得下一个阶段
/// </summary>
/// <param name="currentStage">当前所在阶段</param>
/// <param name="input">用户输入</param>
/// <returns>元组,第一个参数是下一个阶段名称 第二个参数是机器人回答</returns>
/// <exception cref="GrammarException"></exception>
public (string, string) NextStage(string currentStage, string input)
{
List<InnerTransformer> transformers = _stages[currentStage].Transformers;
foreach (InnerTransformer transformer in transformers)
{
Match match = transformer.Pattern.Match(input);
if (match.Success)
{
return (_stages[transformer.NextStage].Name,
_stages[transformer.NextStage].Answer);
}
}
throw new GrammarException("Failed to get next stage.");
}
public string this[string index] => _stages[index].Answer;
internal InnerStage this[string index] => _stages[index];
/// <summary>
/// 主要验证语法的两个特点
@ -65,45 +40,4 @@ public class GrammarTree
return stage.Transformers.All(t => _stages.ContainsKey(t.NextStageName));
});
}
private class InnerStage
{
public string Name { get; }
public List<InnerTransformer> Transformers { get; } = new();
public string Answer { get; }
public InnerStage(Stage stage)
{
Name = stage.Name;
Answer = stage.Answer;
foreach (Transformer transformer in stage.Transformers)
{
Transformers.Add(new InnerTransformer(transformer));
}
}
}
private class InnerTransformer
{
public Regex Pattern { get; }
public string NextStage { get; }
public InnerTransformer(Transformer transformer)
{
NextStage = transformer.NextStageName;
try
{
Pattern = new Regex(transformer.Pattern);
}
catch (ArgumentException e)
{
throw new GrammarException($"Failed to Parse regex:{transformer.Pattern}.", e);
}
}
}
}

View File

@ -0,0 +1,21 @@
namespace Katheryne.Models;
internal class InnerStage
{
public string Name { get; }
public List<InnerTransformer> Transformers { get; } = new();
public string Answer { get; }
public InnerStage(Stage stage)
{
Name = stage.Name;
Answer = stage.Answer;
foreach (Transformer transformer in stage.Transformers)
{
Transformers.Add(new InnerTransformer(transformer));
}
}
}

View File

@ -0,0 +1,33 @@
using System.Text.RegularExpressions;
using Katheryne.Exceptions;
namespace Katheryne.Models;
internal class InnerTransformer
{
public Regex? Pattern { get; }
public string RowPattern { get; }
public string NextStage { get; }
public InnerTransformer(Transformer transformer)
{
NextStage = transformer.NextStageName;
RowPattern = transformer.Pattern;
if (string.IsNullOrEmpty(RowPattern))
{
return;
}
try
{
Pattern = new Regex(transformer.Pattern);
}
catch (ArgumentException e)
{
throw new GrammarException($"Failed to Parse regex:{transformer.Pattern}.", e);
}
}
}