Canon/Canon.Core/GrammarParser/Expression.cs
jackfiled 315deaabf2 add: 抽象语法树节点 (#5)
fix:
- Expression格式化过程中如果Pos在最右边就不显示
- Expression中不考虑Pos

Reviewed-on: PostGuard/Canon#5
2024-03-11 21:57:47 +08:00

118 lines
2.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

namespace Canon.Core.GrammarParser;
/// <summary>
/// LR语法中的一个表达式例如 'program_struct -> ~program_head ; program_body'
/// 其中'~'标识当前移进到达的位置
/// </summary>
public class Expression : IEquatable<Expression>
{
/// <summary>
/// 表达式的左部
/// </summary>
public required NonTerminator Left { get; init; }
/// <summary>
/// 表达式的向前看字符串
/// </summary>
public required Terminator LookAhead { get; init; }
/// <summary>
/// 表达式的右部
/// </summary>
public required List<TerminatorBase> Right { get; init; }
/// <summary>
/// 当前移进的位置
/// </summary>
public required int Pos { get; init; }
public bool Equals(Expression? other)
{
if (other is null)
{
return false;
}
if (Right.Count != other.Right.Count)
{
return false;
}
for (int i = 0; i < Right.Count; i++)
{
if (Right[i].IsTerminated != other.Right[i].IsTerminated)
{
return false;
}
if (!Right[i].Equals(other.Right[i]))
{
return false;
}
}
return Left == other.Left
&& LookAhead == other.LookAhead
&& Pos == other.Pos;
}
public override bool Equals(object? obj)
{
if (obj is not Expression other)
{
return false;
}
return Equals(other);
}
public override int GetHashCode()
{
int hash = Left.GetHashCode();
hash ^= LookAhead.GetHashCode();
hash ^= Pos.GetHashCode();
foreach (TerminatorBase terminator in Right)
{
hash ^= terminator.GetHashCode();
}
return hash;
}
public override string ToString()
{
string result = $"{Left} -> ";
for (int i = 0; i < Right.Count; i++)
{
if (i == Pos)
{
result += '~';
}
result += ' ';
result += Right[i].ToString();
}
if (Pos == Right.Count)
{
result += '~';
}
result += $", {LookAhead}";
return result;
}
public static bool operator ==(Expression a, Expression b)
{
return a.Equals(b);
}
public static bool operator !=(Expression a, Expression b)
{
return !a.Equals(b);
}
}