1 using Mercury.Exceptions;
2 using Mercury.Scanning;
5 namespace Mercury.Syntax
51 public class Symbol : IEquatable<Symbol>, IComparable<Symbol>
55 private bool IsValid()
58 || (Type == SymbolType.Terminal)
68 Type = SymbolType.Epsilon;
93 if (name == null)
throw new ArgumentNullException(
"name");
94 Type = InferType(name) & type;
95 Name = (Type == SymbolType.Terminal) ? name.ToLower() : name;
112 if (token == null)
throw new ArgumentNullException(
"token");
115 Name = token.Value.ToLowerInvariant();
116 Type = InferType(Name) & SymbolType.Terminal;
136 if (
string.IsNullOrEmpty(name))
return SymbolType.None;
139 bool anyLetter =
false;
140 bool allLetDig =
true;
141 bool allLetDigEx =
true;
142 bool allDigits =
true;
147 for (
int ix = 0; ix < name.Length; ++ix )
150 if (
char.IsControl(c) ||
char.IsSeparator(c))
return SymbolType.None;
151 if (c ==
'.') ++dotcount;
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));
160 if ((dotcount <= 1) && allDigits && (name[name.Length - 1] !=
'.'))
161 return SymbolType.Terminal;
164 if ((name.Length == 1) && (!char.IsLetterOrDigit(name[0])))
168 if (allLetDig && (
char.IsLower(name[0]) || char.IsDigit(name[0])))
172 if (allLetDigEx && anyLetter && (
char.IsUpper(name[0]) || (
"@_".IndexOf(name[0]) != -1)))
173 return SymbolType.Nonterminal;
176 return SymbolType.None;
183 public string Name {
get;
protected set; }
191 public bool IsEpsilon {
get {
return Type == SymbolType.Epsilon; } }
206 return other == null ?
false : Equals(other);
210 {
return Name.GetHashCode(); }
214 var src =
Token == null ? Name : Token.Value;
216 return ((src.Length == 1)
217 && !
char.IsLetterOrDigit(src[0])
218 && (Defaults.alphastr.IndexOf(src[0]) == -1))
219 ?
"'" + src.
ToString() +
"'" : src.ToString();
226 #region [ IEquatable ]
229 {
return (other != null) && Name.Equals(other.Name); }
233 #region [ IComparable ]
236 {
return Name.CompareTo(other.Name); }
override string ToString()
Token, a part of an input text recognized by tokenizer
override int GetHashCode()
Symbol()
Creates an epsilon symbol.
int CompareTo(Symbol other)
SymbolType
Represents a type of symbol. Implemented as Flags since Symbol type inference is ambiguous.
static SymbolType InferType(string name)
Infers the type of symbol according to conditions described in the constructor documentation.
bool Equals(Symbol other)
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.
static string Epsilon
Default epsilon symbol name
Symbol(Token token)
Creates a new terminal symbol from a token. If the constructor does not throw any exception...
override bool Equals(object obj)
An exception thrown when attempting to create an invalid Mercury.Syntax.Symbol instance.
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.
Represents a single symbol of the grammar. This is an immutable class. For a symbol name to be val...
override string ToString()