using System.Text;
using Canon.Core.Abstractions;
using Canon.Core.GrammarParser;
using Canon.Core.LexicalParser;
namespace Canon.Core.Exceptions;
///
/// 语法分析中引发的异常
///
public class GrammarException : CanonException
{
public override string Message { get; }
///
/// 语法分析错误时的分析状态
///
public ITransformer CurrentState { get; }
///
/// 语法分析错误时的输入符号
///
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 ListNextTerminators(ITransformer state)
{
List result = [];
result.AddRange(state.ShiftTable.Keys);
result.AddRange(state.ReduceTable.Keys);
return result;
}
}