feat: 语法分析的详细错误信息 (#63)

Reviewed-on: PostGuard/Canon#63
This commit is contained in:
2024-04-28 15:13:09 +08:00
parent 73dba8b1db
commit d84b254716
4 changed files with 219 additions and 21 deletions

View File

@@ -1,12 +1,71 @@
using System.Text;
using Canon.Core.Abstractions;
using Canon.Core.GrammarParser;
using Canon.Core.LexicalParser;
namespace Canon.Core.Exceptions;
/// <summary>
/// 语法分析中引发的异常
/// </summary>
public class GrammarException : Exception
{
public GrammarException() { }
public override string Message { get; }
public GrammarException(string message) : base(message) { }
/// <summary>
/// 语法分析错误时的分析状态
/// </summary>
public ITransformer CurrentState { get; }
public GrammarException(string message, Exception innerException) : base(message, innerException) { }
/// <summary>
/// 语法分析错误时的输入符号
/// </summary>
public SemanticToken CurrentToken { get; }
public GrammarException(ITransformer currentState)
{
CurrentState = currentState;
CurrentToken = SemanticToken.End;
StringBuilder builder = new();
builder.Append("Except ");
foreach (TerminatorBase terminatorBase in ListNextTerminators(CurrentState))
{
builder.Append('\'').Append(terminatorBase).Append("' ");
}
Message = builder.ToString();
}
public GrammarException(ITransformer currentState, SemanticToken currentToken)
{
CurrentState = currentState;
CurrentToken = currentToken;
StringBuilder builder = new();
builder.Append("Expect ");
foreach (TerminatorBase terminatorBase in ListNextTerminators(CurrentState))
{
builder.Append('\'').Append(terminatorBase).Append("',");
}
if (!CurrentToken.Equals(SemanticToken.End))
{
builder.Append("but '").Append(CurrentToken.LiteralValue).Append("' found.");
}
Message = builder.ToString();
}
private static List<TerminatorBase> ListNextTerminators(ITransformer state)
{
List<TerminatorBase> result = [];
result.AddRange(state.ShiftTable.Keys);
result.AddRange(state.ReduceTable.Keys);
return result;
}
}