add: Terminator and Expression
This commit is contained in:
		
							
								
								
									
										37
									
								
								Canon.Core/Enums/GrammarEnums.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								Canon.Core/Enums/GrammarEnums.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					namespace Canon.Core.Enums;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public enum NonTerminatorType
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ProgramStruct,
 | 
				
			||||||
 | 
					    ProgramHead,
 | 
				
			||||||
 | 
					    ProgramBody,
 | 
				
			||||||
 | 
					    IdentifierList,
 | 
				
			||||||
 | 
					    ConstDeclarations,
 | 
				
			||||||
 | 
					    VarDeclarations,
 | 
				
			||||||
 | 
					    SubprogramDeclarations,
 | 
				
			||||||
 | 
					    CompoundStatement,
 | 
				
			||||||
 | 
					    ConstDeclaration,
 | 
				
			||||||
 | 
					    ConstValue,
 | 
				
			||||||
 | 
					    VarDeclaration,
 | 
				
			||||||
 | 
					    Type,
 | 
				
			||||||
 | 
					    BasicType,
 | 
				
			||||||
 | 
					    Range,
 | 
				
			||||||
 | 
					    Subprogram,
 | 
				
			||||||
 | 
					    SubprogramHead,
 | 
				
			||||||
 | 
					    SubprogramBody,
 | 
				
			||||||
 | 
					    FormalParameter,
 | 
				
			||||||
 | 
					    ParameterList,
 | 
				
			||||||
 | 
					    Parameter,
 | 
				
			||||||
 | 
					    VarParameter,
 | 
				
			||||||
 | 
					    ValueParameter,
 | 
				
			||||||
 | 
					    StatementList,
 | 
				
			||||||
 | 
					    Statement,
 | 
				
			||||||
 | 
					    Variable,
 | 
				
			||||||
 | 
					    Expression,
 | 
				
			||||||
 | 
					    ProcedureCall,
 | 
				
			||||||
 | 
					    ElsePart,
 | 
				
			||||||
 | 
					    ExpressionList,
 | 
				
			||||||
 | 
					    SimpleExpression,
 | 
				
			||||||
 | 
					    Term,
 | 
				
			||||||
 | 
					    Factor
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										78
									
								
								Canon.Core/GrammarParser/Expression.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								Canon.Core/GrammarParser/Expression.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					namespace Canon.Core.GrammarParser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An expression in the LR, like 'program_struct -> ~program_head ; program_body.'
 | 
				
			||||||
 | 
					/// The '~' is the shift position now.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class Expression : IEquatable<Expression>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public required NonTerminator Left { get; init; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public required Terminator LookAhead { get; init; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public required List<TerminatorBase> Right { get; init; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public int Pos { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach (TerminatorBase terminator in Right)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            hash ^= terminator.GetHashCode();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return hash;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static bool operator ==(Expression a, Expression b)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return a.Equals(b);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static bool operator !=(Expression a, Expression b)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return !a.Equals(b);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										137
									
								
								Canon.Core/GrammarParser/Terminator.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								Canon.Core/GrammarParser/Terminator.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,137 @@
 | 
				
			|||||||
 | 
					using Canon.Core.Enums;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Canon.Core.GrammarParser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public abstract class TerminatorBase
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public abstract bool IsTerminated { get; }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A terminator in grammar and it always represents a semantic token.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class Terminator : TerminatorBase, IEquatable<Terminator>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public override bool IsTerminated => true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly bool _isKeyword;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly KeywordType _keywordType;
 | 
				
			||||||
 | 
					    private readonly DelimiterType _delimiterType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Terminator(KeywordType keywordType)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _isKeyword = true;
 | 
				
			||||||
 | 
					        _keywordType = keywordType;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Terminator(DelimiterType delimiterType)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _isKeyword = false;
 | 
				
			||||||
 | 
					        _delimiterType = delimiterType;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public override int GetHashCode()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (_isKeyword)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _keywordType.GetHashCode();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _delimiterType.GetHashCode();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public bool Equals(Terminator? other)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (other is null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (_isKeyword != other._isKeyword)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (_isKeyword)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _keywordType == other._keywordType;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _delimiterType == other._delimiterType;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public override bool Equals(object? obj)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (obj is not Terminator other)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Equals(other);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static bool operator ==(Terminator a, Terminator b)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return a.Equals(b);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static bool operator !=(Terminator a, Terminator b)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return !a.Equals(b);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A non-terminator in grammar like the 'ProgramStruct'.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class NonTerminator : TerminatorBase, IEquatable<NonTerminator>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public override bool IsTerminated => false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly NonTerminatorType _type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public NonTerminator(NonTerminatorType type)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _type = type;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public override int GetHashCode()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return _type.GetHashCode();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public bool Equals(NonTerminator? other)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (other is null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return _type == other._type;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public override bool Equals(object? obj)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (obj is not NonTerminator other)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Equals(other);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static bool operator ==(NonTerminator a, NonTerminator b)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return a.Equals(b);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static bool operator !=(NonTerminator a, NonTerminator b)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return !a.Equals(b);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user