2024-03-13 16:41:44 +08:00
|
|
|
|
using Canon.Core.Abstractions;
|
2024-05-01 21:06:27 +08:00
|
|
|
|
using Canon.Core.Enums;
|
|
|
|
|
using Canon.Core.Exceptions;
|
2024-03-11 19:33:02 +08:00
|
|
|
|
|
|
|
|
|
namespace Canon.Core.GrammarParser;
|
2024-03-10 15:37:18 +08:00
|
|
|
|
|
2024-03-13 16:41:44 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 通过LR分析方法建立的语法
|
|
|
|
|
/// </summary>
|
2024-03-10 15:37:18 +08:00
|
|
|
|
public class Grammar
|
|
|
|
|
{
|
2024-03-13 16:41:44 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 起始符
|
|
|
|
|
/// </summary>
|
2024-03-10 15:37:18 +08:00
|
|
|
|
public required NonTerminator Begin { get; init; }
|
|
|
|
|
|
2024-03-13 16:41:44 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 语法中的DFA
|
|
|
|
|
/// </summary>
|
|
|
|
|
public required HashSet<LrState> Automation { get; init; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 起始状态
|
|
|
|
|
/// </summary>
|
2024-03-10 15:37:18 +08:00
|
|
|
|
public required LrState BeginState { get; init; }
|
2024-03-11 19:33:02 +08:00
|
|
|
|
|
2024-04-12 19:01:37 +08:00
|
|
|
|
public IGrammarParser ToGrammarParser()
|
2024-03-11 19:33:02 +08:00
|
|
|
|
{
|
2024-03-13 16:41:44 +08:00
|
|
|
|
Dictionary<LrState, Transformer> transformers = [];
|
2024-03-11 19:33:02 +08:00
|
|
|
|
|
2024-03-13 16:41:44 +08:00
|
|
|
|
foreach (LrState state in Automation)
|
2024-03-11 19:33:02 +08:00
|
|
|
|
{
|
2024-03-13 16:41:44 +08:00
|
|
|
|
ITransformer transformer;
|
|
|
|
|
if (transformers.TryGetValue(state, out Transformer? oldTransformer))
|
2024-03-11 19:33:02 +08:00
|
|
|
|
{
|
2024-03-13 16:41:44 +08:00
|
|
|
|
transformer = oldTransformer;
|
2024-03-11 19:33:02 +08:00
|
|
|
|
}
|
2024-03-13 16:41:44 +08:00
|
|
|
|
else
|
2024-03-11 19:33:02 +08:00
|
|
|
|
{
|
2024-03-13 16:41:44 +08:00
|
|
|
|
Transformer newTransformer = new();
|
|
|
|
|
transformers.Add(state, newTransformer);
|
|
|
|
|
transformer = newTransformer;
|
2024-03-11 19:33:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-13 16:41:44 +08:00
|
|
|
|
// 生成归约的迁移表
|
|
|
|
|
foreach (Expression expression in state.Expressions)
|
2024-03-11 19:33:02 +08:00
|
|
|
|
{
|
2024-03-13 16:41:44 +08:00
|
|
|
|
if (expression.Pos == expression.Right.Count)
|
|
|
|
|
{
|
2024-05-01 21:06:27 +08:00
|
|
|
|
if (transformer.ShiftTable.ContainsKey(expression.LookAhead))
|
|
|
|
|
{
|
|
|
|
|
throw new ReduceAndShiftConflictException();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!transformer.ReduceTable.TryAdd(expression.LookAhead,
|
|
|
|
|
new ReduceInformation(expression.Right.Count, expression.Left)))
|
|
|
|
|
{
|
|
|
|
|
// 发生归约-归约冲突
|
|
|
|
|
throw new ReduceConflictException(state, expression.LookAhead, expression.Left,
|
|
|
|
|
transformer.ReduceTable[expression.LookAhead].Left);
|
|
|
|
|
}
|
2024-03-13 16:41:44 +08:00
|
|
|
|
}
|
2024-03-11 19:33:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-13 16:41:44 +08:00
|
|
|
|
// 生成移进的迁移表
|
2024-05-01 21:06:27 +08:00
|
|
|
|
foreach (KeyValuePair<TerminatorBase, LrState> pair in state.Transformer)
|
2024-03-11 19:33:02 +08:00
|
|
|
|
{
|
2024-03-13 16:41:44 +08:00
|
|
|
|
ITransformer targetTransformer;
|
|
|
|
|
if (transformers.TryGetValue(pair.Value, out Transformer? oldTransformer2))
|
2024-03-11 19:33:02 +08:00
|
|
|
|
{
|
2024-03-13 16:41:44 +08:00
|
|
|
|
targetTransformer = oldTransformer2;
|
2024-03-11 19:33:02 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-03-13 16:41:44 +08:00
|
|
|
|
Transformer newTransformer = new();
|
|
|
|
|
transformers.Add(pair.Value, newTransformer);
|
|
|
|
|
targetTransformer = newTransformer;
|
2024-03-11 19:33:02 +08:00
|
|
|
|
}
|
2024-05-01 21:06:27 +08:00
|
|
|
|
|
|
|
|
|
// 检测移进-归约冲突
|
|
|
|
|
if (pair.Key.IsTerminated)
|
|
|
|
|
{
|
|
|
|
|
Terminator terminator = (Terminator)pair.Key;
|
|
|
|
|
// hack 对于ElsePart的移进-归约冲突
|
|
|
|
|
if (terminator != new Terminator(KeywordType.Else) && transformer.ReduceTable.ContainsKey(terminator))
|
|
|
|
|
{
|
|
|
|
|
throw new ReduceAndShiftConflictException();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
transformer.ShiftTable.Add(pair.Key, targetTransformer);
|
2024-03-11 19:33:02 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-03-13 16:41:44 +08:00
|
|
|
|
|
|
|
|
|
return new GrammarParser(transformers[BeginState], Begin);
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-12 19:01:37 +08:00
|
|
|
|
private class GrammarParser(ITransformer beginTransformer, NonTerminator begin) : IGrammarParser
|
2024-03-13 16:41:44 +08:00
|
|
|
|
{
|
2024-04-12 19:01:37 +08:00
|
|
|
|
public ITransformer BeginTransformer { get; } = beginTransformer;
|
|
|
|
|
public NonTerminator Begin { get; } = begin;
|
2024-03-13 16:41:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class Transformer : ITransformer
|
|
|
|
|
{
|
2024-04-08 19:46:24 +08:00
|
|
|
|
public string Name => string.Empty;
|
|
|
|
|
|
2024-03-13 16:41:44 +08:00
|
|
|
|
public IDictionary<TerminatorBase, ITransformer> ShiftTable { get; }
|
|
|
|
|
= new Dictionary<TerminatorBase, ITransformer>();
|
|
|
|
|
|
|
|
|
|
public IDictionary<Terminator, ReduceInformation> ReduceTable { get; }
|
|
|
|
|
= new Dictionary<Terminator, ReduceInformation>();
|
2024-03-11 19:33:02 +08:00
|
|
|
|
}
|
2024-03-10 15:37:18 +08:00
|
|
|
|
}
|