Mercury library 1.0 Translation of CFG grammars into an object model (Bachelor's thesis).

- Main Page
- Packages
- Classes
- Files

- File List

All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties
Element.cs
Go to the documentation of this file.
1 using Mercury.Exceptions;
2 using Mercury.Nucleus.Trees;
3 using Mercury.Syntax;
4 using System;
5 using System.Collections.Generic;
6 using System.Linq;
7 using System.Text;
8
9 namespace Mercury.Interpreting
10 {
11
12 //==<< ElementType >>========================================================
13
15 public enum ElementType
16 {
18 Constant,
20 Variable,
22 Wildcard,
24 Structure,
25 }
26
27 //=============================================================================
28 // IElement
29 //=============================================================================
30
32 public interface IElement : IEquatable<IElement>
33 {
34 //--[ Properties ]---------------------------------------------------
35
37 ElementType Type { get; }
38 }
39
40 //=============================================================================
41 // Alternative
42 //=============================================================================
43
48 public abstract class Alternative : IEquatable<Alternative>
49 {
50 //--[ Private methods ]----------------------------------------------
51
52 private int? memhash = null;
53 protected HashSet<Symbol> smset;
54
55 //--[ Constructors ]-------------------------------------------------
56
67 public Alternative(SymbolType sm, IEnumerable<Symbol> symbols)
68 {
69 if (symbols == null) throw new ArgumentNullException("symbols");
70
71 smset = new HashSet<Symbol>();
72 foreach(var symbol in symbols)
73 {
74 if (symbol == null) throw new ArgumentException("Argument 'symbols' contains null");
75 if (!sm.HasFlag(symbol.Type)) smset.Add(symbol);
76 }
77
78 if ((sm == SymbolType.None) && (smset.Count == 0))
79 throw new ArgumentException("Empty alternative is not allowed");
80
81 SymbolMask = sm;
82 Symbols = smset.ToList();
83 }
84
85 //--[ Properties ]---------------------------------------------------
86
92 public SymbolType SymbolMask { get; private set; }
93
96 public IReadOnlyList<Symbol> Symbols { get; private set; }
97
98 //--[ Methods ]------------------------------------------------------
99
105 public bool MatchesSymbol(Symbol s)
106 { return (s != null) && (SymbolMask.HasFlag(s.Type) || smset.Contains(s)); }
107
108 //--[ Overriden methods ]--------------------------------------------
109
110 #region [ Object ]
111
112 public override bool Equals(object obj)
113 {
114 Alternative other = obj as Alternative;
115 return (obj == null) ? false : Equals(other);
116 }
117
118 public override int GetHashCode()
119 {
120 if (!memhash.HasValue)
121 {
122 memhash = 17 + 7 * (int) SymbolMask;
123 for (int ix = 0; ix < Symbols.Count; ++ix)
124 memhash = 31 * memhash + Symbols[ix].GetHashCode();
125 }
126
127 return memhash.Value;
128 }
129
130 public override string ToString()
131 {
132 StringBuilder sb = new StringBuilder();
133
134 if (Symbols.Count != 0)
135 {
136 sb.Append(Symbols[0]);
137
138 for (int ix = 1; ix < Symbols.Count; ++ix)
139 sb.Append('|').Append(Symbols[ix]);
140 }
141
142 if (SymbolMask != SymbolType.None)
143 {
144 sb.Append(':');
145 if (SymbolMask.HasFlag(SymbolType.Nonterminal)) sb.Append('N');
146 if (SymbolMask.HasFlag(SymbolType.Terminal)) sb.Append('T');
147 if (SymbolMask.HasFlag(SymbolType.Epsilon)) sb.Append('e');
148 }
149
150 return sb.ToString();
151 }
152
153 #endregion
154
155 //--[ Interface implementation ]-------------------------------------
156
157 #region [ IEquatable ]
158
159 public bool Equals(Alternative other)
160 {
161 return (SymbolMask == other.SymbolMask)
162 && (Symbols.Count == other.Symbols.Count)
163 && (Symbols.Zip(other.Symbols, (x, y) => x.Equals(y)).All(x => x));
164 }
165
166 #endregion
167
168 }
169
170 //=============================================================================
171 // Constant
172 //=============================================================================
173
178 public class Constant : Alternative, IElement, IEquatable<Constant>
179 {
180 //--[ Constructors ]-------------------------------------------------
181
186 public Constant(Symbol symbol)
187 : this(new[] { symbol })
188 { }
189
192 public Constant(IEnumerable<Symbol> symbols)
193 : this(SymbolType.None, symbols)
194 { }
195
203 public Constant(SymbolType sm, IEnumerable<Symbol> symbols)
204 : base(sm, symbols)
205 { Type = ElementType.Constant; }
206
207 //--[ Overriden methods ]--------------------------------------------
208
209 #region [ Object ]
210
211 public override bool Equals(object obj)
212 {
213 Constant other = obj as Constant;
214 return other == null ? false : Equals(other);
215 }
216
217 public override int GetHashCode()
218 { return 23 * base.GetHashCode(); }
219
220 public override string ToString()
221 { return base.ToString(); }
222
223 #endregion
224
225 //--[ Interface implementation ]-------------------------------------
226
227 #region [ IElement ]
228
229 public ElementType Type { get; private set; }
230
231 #endregion
232
233 #region [ IEquatable ]
234
235 public bool Equals(IElement other)
236 {
237 return ((other != null) && (other.Type == ElementType.Constant))
238 ? Equals(other as Constant)
239 : false;
240 }
241
242 public bool Equals(Constant other)
243 {
244 return (other != null)
245 && (GetHashCode() == other.GetHashCode())
246 && (base.Equals(other as Alternative));
247 }
248
249 #endregion
250
251 }
252
253 //=============================================================================
254 // Variable
255 //=============================================================================
256
261 public class Variable : Alternative, IElement, IEquatable<Variable>
262 {
263 //--[ Constructors ]-------------------------------------------------
264
269 public Variable()
270 : this(Extensions.RandomString("FS.%.*"), SymbolType.Any, new Symbol[0])
271 { }
272
282 public Variable(string name, SymbolType ws, IEnumerable<Symbol> symbols)
283 : base(ws, symbols)
284 {
285 if (!IsValidName(name)) throw new ArgumentException(string.Format("Invalid variable name '{0}'", name));
286 Type = ElementType.Variable;
287 Name = name;
288 }
289
290 //--[ Properties ]---------------------------------------------------
291
293 public string Name { get; private set; }
294
295 //--[ Methods ]------------------------------------------------------
296
307 public static bool IsValidName(string name)
308 {
309 return !string.IsNullOrEmpty(name)
310 && char.IsLetter(name[0])
311 && name.All(x => char.IsLetterOrDigit(x));
312 }
313
314 //--[ Overriden methods ]--------------------------------------------
315
316 #region [ Object ]
317
318 public override bool Equals(object obj)
319 {
320 Variable other = obj as Variable;
321 return other == null ? false : Equals(other);
322 }
323
324 public override int GetHashCode()
325 { return Name.GetHashCode() + 89 * base.GetHashCode(); }
326
327 public override string ToString()
328 { return (new StringBuilder()).Append('#').Append(Name).Append(':').Append(base.ToString()).ToString(); }
329
330 #endregion
331
332 //--[ Interface implementation ]-------------------------------------
333
334 #region [ IElement ]
335
336 public ElementType Type { get; protected set; }
337
338 #endregion
339
340 #region [ IEquatable ]
341
342 public bool Equals(IElement other)
343 {
344 return ((other != null) && (other.Type == ElementType.Variable))
345 ? Equals(other as Variable)
346 : false;
347 }
348
349 public bool Equals(Variable other)
350 {
351 return (other != null)
352 && (GetHashCode() == other.GetHashCode())
353 && (Name == other.Name)
354 && (base.Equals(other));
355 }
356
357 #endregion
358
359 }
360
361 //=============================================================================
362 // Wildcard
363 //=============================================================================
364
370 public class Wildcard : Variable
371 {
372 //--[ Constructors ]-------------------------------------------------
373
375 public Wildcard()
376 : this(null, SymbolType.Any, new Symbol[0])
377 { }
378
387 public Wildcard(string name, SymbolType ws, IEnumerable<Symbol> symbols)
388 : base(name ?? Extensions.RandomString("WR.%.*"), ws, symbols)
389 { Type = ElementType.Wildcard; }
390
391 //--[ Overriden methods ]--------------------------------------------
392
393 #region [ Object ]
394
395 public override bool Equals(object obj)
396 {
397 Wildcard other = obj as Wildcard;
398 return other == null ? false : Equals(other);
399 }
400
401 public override int GetHashCode()
402 { return 7 * (base.GetHashCode() / 5); }
403
404 public override string ToString()
405 { return "*" + base.ToString().Substring(1); }
406
407 #endregion
408
409 //--[ Interface implementation ]-------------------------------------
410
411 #region [ IEquatable ]
412
413 public new bool Equals(IElement other)
414 {
415 return ((other != null) && (other.Type == ElementType.Wildcard))
416 ? Equals(other as Wildcard)
417 : false;
418 }
419
420 public bool Equals(Wildcard other)
421 {
422 return (other != null)
423 && (GetHashCode() == other.GetHashCode())
424 && (base.Equals(other));
425 }
426
427 #endregion
428
429 }
430
431 //=============================================================================
432 // Structure
433 //=============================================================================
434
439 public class Structure : Tree<IElement>, IElement
440 {
441 //--[ Private fields ]-----------------------------------------------
442
443 private static Func<IElement, Tree<IElement>> transform =
444 x => x as Structure ?? new Tree<IElement>(x);
445
446 //--[ Constructors ]-------------------------------------------------
447
452 public Structure(IElement head)
453 : this (head, new IElement[0])
454 { }
455
463 public Structure(IElement head, IEnumerable<IElement> subelements)
464 : base(head, subelements.Select(x => transform(x)))
465 {
466 if (head == null) throw new ArgumentNullException("value");
467
468 this.Type = ElementType.Structure;
469 this.HasWildcard = Children.Any(x => x.Value.Type == ElementType.Wildcard);
470
471 if ((head as Alternative) == null)
472 throw new InvalidElementException(this, "structure root must be an Alternative");
473 }
474
475 //--[ Properties ]---------------------------------------------------
476
484 public bool HasWildcard { get; private set; }
485
486 //--[ Interface implementation ]-------------------------------------
487
488 #region [ IElement ]
489
490 public ElementType Type { get; private set; }
491
492 #endregion
493
494 #region [ IEquatable ]
495
496 public bool Equals(IElement other)
497 {
498 return (other != null)
499 && (other.Type == ElementType.Structure)
500 && base.Equals(other as Tree<IElement>);
501 }
502
503 #endregion
504
505 }
506 }
Mercury.Interpreting.Alternative.SymbolMask
SymbolType SymbolMask
Mask of symbol types this alternative matches regardless the symbol name.
Definition: Element.cs:92
Mercury.Interpreting.Structure.Structure
Structure(IElement head)
Creates a new Structure structure with root only.
Definition: Element.cs:452
Mercury.Interpreting.Wildcard.Equals
override bool Equals(object obj)
Definition: Element.cs:395
Mercury.Syntax.All
Maps token to symbol, keyword, number and string
Mercury.Interpreting.Alternative.GetHashCode
override int GetHashCode()
Definition: Element.cs:118
Mercury.Interpreting.Constant.Constant
Constant(IEnumerable< Symbol > symbols)
Constant that matches any of the specified symbols.
Definition: Element.cs:192
Mercury.Interpreting.Variable.Equals
override bool Equals(object obj)
Definition: Element.cs:318
Mercury.Interpreting.Constant.Equals
bool Equals(Constant other)
Definition: Element.cs:242
Mercury.Interpreting.Constant.GetHashCode
override int GetHashCode()
Definition: Element.cs:217
Mercury.Interpreting.Alternative.Equals
bool Equals(Alternative other)
Definition: Element.cs:159
Mercury.Interpreting.Alternative
Represents an alternative of elements. It may match specified symbols or symboltypes (Nonterminals...
Definition: Element.cs:48
Mercury.Interpreting.Structure
Represents a tree of Mercury.Interpreting.IElement instances. Must match precisely to the parse tree...
Definition: Element.cs:439
Mercury.Interpreting.Alternative.Alternative
Alternative(SymbolType sm, IEnumerable< Symbol > symbols)
Initializes a new instance of the Alternative class. If symbols contains symbols of type that is pre...
Definition: Element.cs:67
Mercury.Interpreting.Constant.Constant
Constant(Symbol symbol)
Creates a Constant made of one symbol.
Definition: Element.cs:186
Mercury.Interpreting.Alternative.MatchesSymbol
bool MatchesSymbol(Symbol s)
Indicates whether this alternative matches the given symbol.
Definition: Element.cs:105
Mercury.Interpreting.Variable.Variable
Variable(string name, SymbolType ws, IEnumerable< Symbol > symbols)
Initializes a new instance of the variable class. See Mercury.Interpreting.Alternative's constructor ...
Definition: Element.cs:282
Mercury.Syntax.SymbolType
SymbolType
Represents a type of symbol. Implemented as Flags since Symbol type inference is ambiguous.
Definition: Symbol.cs:16
Mercury.Interpreting.IElement.Type
ElementType Type
Element type
Definition: Element.cs:37
Mercury.Interpreting.Structure.Structure
Structure(IElement head, IEnumerable< IElement > subelements)
Creates a new Structure.
Definition: Element.cs:463
Mercury.Interpreting.Variable.IsValidName
static bool IsValidName(string name)
Determines whether the specified string is a valid variable name.
Definition: Element.cs:307
Mercury.Interpreting.Wildcard.Equals
new bool Equals(IElement other)
Definition: Element.cs:413
Mercury.Interpreting.Variable
Represents a variable element that captures value and can be used on the RHS of the RewriteRule as an...
Definition: Element.cs:261
Mercury.Interpreting.Alternative.Symbols
IReadOnlyList< Symbol > Symbols
List of specific symbols this alternative matches.
Definition: Element.cs:96
Mercury.Interpreting.Constant.ToString
override string ToString()
Definition: Element.cs:220
Mercury.Interpreting.Structure.Equals
bool Equals(IElement other)
Definition: Element.cs:496
Mercury.Interpreting.ElementType
ElementType
Element Type enumeration
Definition: Element.cs:15
Mercury.Interpreting.Wildcard.Equals
bool Equals(Wildcard other)
Definition: Element.cs:420
Mercury.Interpreting.Wildcard.ToString
override string ToString()
Definition: Element.cs:404
Mercury.Interpreting.Wildcard
An element that matches zero or more values. Can be used as a variable, but the actioncall must be of...
Definition: Element.cs:370
Mercury.Interpreting.Wildcard.Wildcard
Wildcard(string name, SymbolType ws, IEnumerable< Symbol > symbols)
Creates a new the Wildcard. See the Mercury.Interpreting.Alternative's constructor for more details...
Definition: Element.cs:387
Mercury.Interpreting.Constant.Constant
Constant(SymbolType sm, IEnumerable< Symbol > symbols)
Initializes a new instance of the Constant class. See Mercury.Interpreting.Alternative's constructor ...
Definition: Element.cs:203
Mercury.Interpreting.Variable.Equals
bool Equals(Variable other)
Definition: Element.cs:349
Mercury.Interpreting.Alternative.ToString
override string ToString()
Definition: Element.cs:130
Mercury.Interpreting.Constant.Equals
bool Equals(IElement other)
Definition: Element.cs:235
Mercury.Interpreting.Wildcard.Wildcard
Wildcard()
Creates a new Wildcard with a random name
Definition: Element.cs:375
Mercury.Interpreting.IElement
Element interface
Definition: Element.cs:32
Mercury.Interpreting.Variable.ToString
override string ToString()
Definition: Element.cs:327
Mercury.Interpreting.Tree
A derivation tree
Mercury.Exceptions.InvalidElementException
An exception representing a problem with Mercury.Interpreting.IElement descendants.
Definition: InterpretingExceptions.cs:87
Mercury.Interpreting.Alternative.Equals
override bool Equals(object obj)
Definition: Element.cs:112
Mercury.Interpreting.Variable.GetHashCode
override int GetHashCode()
Definition: Element.cs:324
Mercury.Interpreting.Alternative.smset
HashSet< Symbol > smset
Definition: Element.cs:53
Mercury.Interpreting.Any
Any argument
Mercury.Extensions
Provides extension methods for the Mercury library.
Definition: Extensions.cs:12
Mercury.Interpreting.Variable.Equals
bool Equals(IElement other)
Definition: Element.cs:342
Mercury.Interpreting.Constant.Equals
override bool Equals(object obj)
Definition: Element.cs:211
Mercury.Syntax.Symbol
Represents a single symbol of the grammar. This is an immutable class. For a symbol name to be val...
Definition: Symbol.cs:51
Mercury.None
No failure
Mercury.Interpreting.Wildcard.GetHashCode
override int GetHashCode()
Definition: Element.cs:401
Mercury.Interpreting.Constant
Constant element. Basically equivalent of Mercury.Interpreting.Alternative.
Definition: Element.cs:178
Mercury.Interpreting.Variable.Variable
Variable()
Creates an anonymous variable, an equivalent of Mercury.Interpreting.Wildcard that matches exactly on...
Definition: Element.cs:269