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
Symbol.cs
Go to the documentation of this file.
1 using Mercury.Exceptions;
2 using Mercury.Scanning;
3 using System;
4
5 namespace Mercury.Syntax
6 {
7 //=============================================================================
8 // Symbol
9 //=============================================================================
10
15 [Flags]
16 public enum SymbolType
17 {
19 None = 0,
21 Epsilon = 1,
23 Terminal = 2,
25 Nonterminal = 4,
27 Any = Epsilon | Terminal | Nonterminal
28 }
29
51 public class Symbol : IEquatable<Symbol>, IComparable<Symbol>
52 {
53 //--[ Private methods ]----------------------------------------------
54
55 private bool IsValid()
56 {
57 return (Type == SymbolType.Epsilon)
58 || (Type == SymbolType.Terminal)
59 || (Type == SymbolType.Nonterminal);
60 }
61
62 //--[ Constructors ]-------------------------------------------------
63
65 public Symbol()
66 {
67 Name = Defaults.Epsilon;
68 Type = SymbolType.Epsilon;
69 Token = null;
70 }
71
77 public Symbol(string name)
78 : this(name, SymbolType.Nonterminal | SymbolType.Terminal)
79 { }
80
91 public Symbol(string name, SymbolType type)
92 {
93 if (name == null) throw new ArgumentNullException("name");
94 Type = InferType(name) & type;
95 Name = (Type == SymbolType.Terminal) ? name.ToLower() : name;
96 Token = null;
97
98 if (!IsValid()) throw new InvalidSymbolException(this);
99 }
100
110 public Symbol(Token token)
111 {
112 if (token == null) throw new ArgumentNullException("token");
113
114 Token = token;
115 Name = token.Value.ToLowerInvariant();
116 Type = InferType(Name) & SymbolType.Terminal;
117
118 if (!IsValid()) throw new InvalidSymbolException(this);
119 }
120
121 //--[ Methods ]------------------------------------------------------
122
133 public static SymbolType InferType(string name)
134 {
135 // reject empty name
136 if (string.IsNullOrEmpty(name)) return SymbolType.None;
137
138 // some cool flags for convenience
139 bool anyLetter = false;
140 bool allLetDig = true;
141 bool allLetDigEx = true;
142 bool allDigits = true;
143 int dotcount = 0;
144
145 // reject name containing special characters or separators
146 // meanwhile compute predicate values
147 for (int ix = 0; ix < name.Length; ++ix )
148 {
149 char c = name[ix];
150 if (char.IsControl(c) || char.IsSeparator(c)) return SymbolType.None;
151 if (c == '.') ++dotcount;
152
153 anyLetter |= char.IsLetter(c);
154 allDigits &= (char.IsDigit(c) || (dotcount == 1) || ((ix == 0) && ("+-".IndexOf(c) != -1)));
155 allLetDig &= char.IsLetterOrDigit(c);
156 allLetDigEx &= (char.IsLetterOrDigit(c) || ("@_".IndexOf(c) != -1));
157 }
158
159 // check terminal b) condition
160 if ((dotcount <= 1) && allDigits && (name[name.Length - 1] != '.'))
161 return SymbolType.Terminal;
162
163 // check terminal c) condition
164 if ((name.Length == 1) && (!char.IsLetterOrDigit(name[0])))
165 return SymbolType.Terminal;
166
167 // check terminal a) condition (= epsilon condition)
168 if (allLetDig && (char.IsLower(name[0]) || char.IsDigit(name[0])))
169 return SymbolType.Epsilon | SymbolType.Terminal;
170
171 // check nonterminal condition
172 if (allLetDigEx && anyLetter && (char.IsUpper(name[0]) || ("@_".IndexOf(name[0]) != -1)))
173 return SymbolType.Nonterminal;
174
175 // no condition holds, give up
176 return SymbolType.None;
177 }
178
179 //--[ Properties ]---------------------------------------------------
180
183 public string Name { get; protected set; }
184
187 public SymbolType Type { get; protected set; }
188
191 public bool IsEpsilon { get { return Type == SymbolType.Epsilon; } }
192
197 public Token Token { get; protected set; }
198
199 //--[ Overriden methods ]--------------------------------------------
200
201 #region [ Object ]
202
203 public override bool Equals(object obj)
204 {
205 Symbol other = obj as Symbol;
206 return other == null ? false : Equals(other);
207 }
208
209 public override int GetHashCode()
210 { return Name.GetHashCode(); }
211
212 public override string ToString()
213 {
214 var src = Token == null ? Name : Token.Value;
215
216 return ((src.Length == 1)
217 && !char.IsLetterOrDigit(src[0])
218 && (Defaults.alphastr.IndexOf(src[0]) == -1))
219 ? "'" + src.ToString() + "'" : src.ToString();
220 }
221
222 #endregion
223
224 //--[ Interface implementation ]-------------------------------------
225
226 #region [ IEquatable ]
227
228 public bool Equals(Symbol other)
229 { return (other != null) && Name.Equals(other.Name); }
230
231 #endregion
232
233 #region [ IComparable ]
234
235 public int CompareTo(Symbol other)
236 { return Name.CompareTo(other.Name); }
237
238 #endregion
239
240 }
241 }
Mercury.Scanning.Token.ToString
override string ToString()
Definition: Token.cs:75
Mercury.Scanning.Token
Token, a part of an input text recognized by tokenizer
Definition: Token.cs:29
Mercury.Syntax.Symbol.GetHashCode
override int GetHashCode()
Definition: Symbol.cs:209
Mercury.Syntax.Symbol.Symbol
Symbol()
Creates an epsilon symbol.
Definition: Symbol.cs:65
Mercury.Syntax.Terminal
A nonterminal symbol.
Mercury.Syntax.Symbol.CompareTo
int CompareTo(Symbol other)
Definition: Symbol.cs:235
Mercury.Syntax.SymbolType
SymbolType
Represents a type of symbol. Implemented as Flags since Symbol type inference is ambiguous.
Definition: Symbol.cs:16
Mercury.Syntax.Symbol.InferType
static SymbolType InferType(string name)
Infers the type of symbol according to conditions described in the constructor documentation.
Definition: Symbol.cs:133
Mercury.Syntax.Symbol.Equals
bool Equals(Symbol other)
Definition: Symbol.cs:228
Mercury.Interpreting.Flags
All flags
Mercury.Syntax.Symbol.Symbol
Symbol(string name)
Creates a new symbol and infers its type. If the constructor does not throw any exception, the symbol is guaranteed to be valid.
Definition: Symbol.cs:77
Mercury.Defaults.Epsilon
static string Epsilon
Default epsilon symbol name
Definition: Defaults.cs:50
Mercury.Syntax.Symbol.Symbol
Symbol(Token token)
Creates a new terminal symbol from a token. If the constructor does not throw any exception...
Definition: Symbol.cs:110
Mercury.Syntax.Epsilon
The epsilon symbol.
Mercury.Syntax.Nonterminal
A terminal symbol.
Mercury.Syntax.Symbol.Equals
override bool Equals(object obj)
Definition: Symbol.cs:203
Mercury.Exceptions.InvalidSymbolException
An exception thrown when attempting to create an invalid Mercury.Syntax.Symbol instance.
Definition: SyntaxExceptions.cs:63
Mercury.Syntax.Symbol.Symbol
Symbol(string name, SymbolType type)
Creates a new symbol with desired type. If the constructor does not throw any exception, the symbol is guaranteed to be valid.
Definition: Symbol.cs:91
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.Syntax.Symbol.ToString
override string ToString()
Definition: Symbol.cs:212