1 using Mercury.Exceptions;
3 using System.Collections.Generic;
7 namespace Mercury.Syntax
23 public class Rule : IEquatable<Rule>, IComparable<Rule>
27 private int? memHash = null;
31 private bool IsValid()
33 return ((LHS.Type ==
SymbolType.Nonterminal) && (RHS.Count > 0)
34 && ((RHS.Count == 1) || RHS.All(x => !x.IsEpsilon)));
49 if (lhs == null)
throw new ArgumentNullException(
"lhs");
50 if (rhs == null)
throw new ArgumentNullException(
"rhs");
54 IsEpsilon = (RHS.Count == 1) && (RHS[0].IsEpsilon);
66 public Symbol LHS {
get;
private set; }
70 public IReadOnlyList<Symbol> RHS {
get;
private set; }
77 public bool IsEpsilon {
get;
private set; }
83 public override bool Equals(
object obj)
86 return rule == null ?
false : Equals(rule);
94 int hash = LHS.GetHashCode();
95 for (
int ix = 0; ix < RHS.Count; ++ix)
96 hash = (7919 * hash) + RHS[ix].GetHashCode();
104 StringBuilder sb =
new StringBuilder();
108 for (
int ix = 0; ix < RHS.Count; ++ix)
109 sb.Append(
' ').Append(RHS[ix]);
111 return sb.ToString();
118 #region [ IEquatable ]
124 || (!LHS.Equals(other.
LHS))
125 || (RHS.Count != other.
RHS.Count))
128 for (
int ix = 0; ix < RHS.Count; ++ix)
129 if (!RHS[ix].Equals(other.
RHS[ix]))
137 #region [ IComparable ]
153 int temp = LHS.CompareTo(other.LHS);
155 if (temp == 0) temp = RHS.Count.CompareTo(other.RHS.Count);
157 for (
int ix = 0; (temp == 0) && (ix < RHS.Count); ++ix)
158 temp = RHS[ix].CompareTo(other.
RHS[ix]);
IReadOnlyList< Symbol > RHS
The Right-Hand Side (RHS) of the rule.
override int GetHashCode()
SymbolType
Represents a type of symbol. Implemented as Flags since Symbol type inference is ambiguous.
Symbol LHS
The Left-Hand Side (LHS) of the rule.
An exception thrown when attempting to create an invalid Mercury.Syntax.Rule instance.
override bool Equals(object obj)
override string ToString()
Rule(Symbol lhs, IEnumerable< Symbol > rhs)
Creates a rule. If the constructor does not throw any exception, the rule is guaranteed to be valid...
int CompareTo(Rule other)
Compares the rule with another rule. Defines a lexicographical order as follows:
Represents a Context-Free Grammar rule. This is an immutable class.
Represents a single symbol of the grammar. This is an immutable class. For a symbol name to be val...