Mercury library  1.0
Translation of CFG grammars into an object model (Bachelor's thesis).
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties
Rule.cs
Go to the documentation of this file.
1 using Mercury.Exceptions;
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 
7 namespace Mercury.Syntax
8 {
9 //=============================================================================
10 // Rule
11 //=============================================================================
12 
23  public class Rule : IEquatable<Rule>, IComparable<Rule>
24  {
25  //--[ Private fields ]-----------------------------------------------
26 
27  private int? memHash = null; // memoized hash value
28 
29  //--[ Private methods ]----------------------------------------------
30 
31  private bool IsValid()
32  {
33  return ((LHS.Type == SymbolType.Nonterminal) && (RHS.Count > 0)
34  && ((RHS.Count == 1) || RHS.All(x => !x.IsEpsilon)));
35  }
36 
37  //--[ Constructors ]-------------------------------------------------
38 
47  public Rule(Symbol lhs, IEnumerable<Symbol> rhs)
48  {
49  if (lhs == null) throw new ArgumentNullException("lhs");
50  if (rhs == null) throw new ArgumentNullException("rhs");
51 
52  LHS = lhs;
53  RHS = rhs.ToList();
54  IsEpsilon = (RHS.Count == 1) && (RHS[0].IsEpsilon);
55 
56  if (RHS.Count == 0) throw new InvalidRuleException(this, "Rule RHS is empty");
57  if (!IsValid()) throw new InvalidRuleException(this);
58 
59 
60  }
61 
62  //--[ Properties ]---------------------------------------------------
63 
66  public Symbol LHS { get; private set; }
67 
70  public IReadOnlyList<Symbol> RHS { get; private set; }
71 
77  public bool IsEpsilon { get; private set; }
78 
79  //--[ Overriden methods ]--------------------------------------------
80 
81  #region [ Object ]
82 
83  public override bool Equals(object obj)
84  {
85  Rule rule = obj as Rule;
86  return rule == null ? false : Equals(rule);
87  }
88 
89  public override int GetHashCode()
90  {
91  if (memHash.HasValue)
92  return memHash.Value;
93 
94  int hash = LHS.GetHashCode();
95  for (int ix = 0; ix < RHS.Count; ++ix)
96  hash = (7919 * hash) + RHS[ix].GetHashCode();
97 
98  memHash = hash;
99  return hash;
100  }
101 
102  public override string ToString()
103  {
104  StringBuilder sb = new StringBuilder();
105  sb.Append(LHS);
106  sb.Append(" ->");
107 
108  for (int ix = 0; ix < RHS.Count; ++ix)
109  sb.Append(' ').Append(RHS[ix]);
110 
111  return sb.ToString();
112  }
113 
114  #endregion
115 
116  //--[ Interface implementation ]-------------------------------------
117 
118  #region [ IEquatable ]
119 
120  public bool Equals(Rule other)
121  {
122  if ((other == null)
123  || (GetHashCode() != other.GetHashCode())
124  || (!LHS.Equals(other.LHS))
125  || (RHS.Count != other.RHS.Count))
126  return false;
127 
128  for (int ix = 0; ix < RHS.Count; ++ix)
129  if (!RHS[ix].Equals(other.RHS[ix]))
130  return false;
131 
132  return true;
133  }
134 
135  #endregion
136 
137  #region [ IComparable ]
138 
151  public int CompareTo(Rule other)
152  {
153  int temp = LHS.CompareTo(other.LHS);
154 
155  if (temp == 0) temp = RHS.Count.CompareTo(other.RHS.Count);
156 
157  for (int ix = 0; (temp == 0) && (ix < RHS.Count); ++ix)
158  temp = RHS[ix].CompareTo(other.RHS[ix]);
159 
160  return temp;
161  }
162 
163  #endregion
164 
165  }
166 }
IReadOnlyList< Symbol > RHS
The Right-Hand Side (RHS) of the rule.
Definition: Rule.cs:70
override int GetHashCode()
Definition: Rule.cs:89
SymbolType
Represents a type of symbol. Implemented as Flags since Symbol type inference is ambiguous.
Definition: Symbol.cs:16
Symbol LHS
The Left-Hand Side (LHS) of the rule.
Definition: Rule.cs:66
An exception thrown when attempting to create an invalid Mercury.Syntax.Rule instance.
override bool Equals(object obj)
Definition: Rule.cs:83
override string ToString()
Definition: Rule.cs:102
Rule(Symbol lhs, IEnumerable< Symbol > rhs)
Creates a rule. If the constructor does not throw any exception, the rule is guaranteed to be valid...
Definition: Rule.cs:47
int CompareTo(Rule other)
Compares the rule with another rule. Defines a lexicographical order as follows:
Definition: Rule.cs:151
Represents a Context-Free Grammar rule. This is an immutable class.
Definition: Rule.cs:23
Represents a single symbol of the grammar. This is an immutable class. For a symbol name to be val...
Definition: Symbol.cs:51
bool Equals(Rule other)
Definition: Rule.cs:120