public Alternation(IEBNFItem left, IEBNFItem right) { this._left = left; this._right = right; this.MinimalLength = this._left.MinimalLength <= this._right.MinimalLength ? this._left.MinimalLength : this._right.MinimalLength; this.IsOptional = this._left.IsOptional && this._right.IsOptional; }
/// <summary> /// Recursive function for finding sequence of Terminals and NonTerminals by rule. Result is IEBNFItem which containst sequence /// </summary> private IEBNFItem GetEBNFItem(string rule, List <NonTerminal> listOfExistedTerminals, string endNotation = null) { IEBNFItem result = null; var left = GetStartEBNFItem(rule, listOfExistedTerminals); var lengthOfLeftRule = left.Rebuild().Length; var restOfRule = rule.Substring(lengthOfLeftRule, rule.Length - lengthOfLeftRule); if (string.IsNullOrEmpty(restOfRule)) { throw new GrammarParseException("Can't find IEBNFItem, rest of rule is null or empty. Check termination charatcter."); } var firstChar = restOfRule[0].ToString(); if (!string.IsNullOrEmpty(endNotation) && firstChar.Equals(endNotation)) { result = left; } else if (IsTermination(firstChar)) { result = left; } else { var newRule = restOfRule.Substring(1, restOfRule.Length - 1); var right = GetEBNFItem(newRule, listOfExistedTerminals, endNotation); switch (firstChar) { case Alternation.notation: result = new Alternation(left, right); break; case Concatenation.notation: result = new Concatenation(left, right, this._cacheLength); break; } } return(result); }
public Concatenation(IEBNFItem left, IEBNFItem right, int cacheLength) { this._left = left; this._right = right; this._cache = new SmartFixedCollectionPair <string, CacheItem <string>[]>(cacheLength); this.MinimalLength = this._left.MinimalLength + this._right.MinimalLength; this.IsOptional = this._left.IsOptional && this._right.IsOptional; }
public Optional(IEBNFItem item) { this._item = item; }
public Grouping(IEBNFItem item) { this._item = item; this.MinimalLength = this._item.MinimalLength; this.IsOptional = this._item.IsOptional; }
/// <summary> /// Allows to set right side rule /// </summary> internal void SetRightSide(IEBNFItem item) { this._rightSide = item; this.MinimalLength = item.MinimalLength; this.IsOptional = this._rightSide.IsOptional; }
public Repetition(IEBNFItem item, int cacheLength) { this._item = item; this._cache = new SmartFixedCollectionPair <string, string[]>(cacheLength); }
/// <summary> /// Try to find EBNFItem which can be on right side /// Its part of recursion it calls GetEBNFItem /// </summary> /// <returns></returns> private IEBNFItem GetStartEBNFItem(string rule, List <NonTerminal> listOfExistedTerminals) { IEBNFItem result = null; switch (rule[0].ToString()) { case "\"": { var builder = new StringBuilder(); for (var i = 1; i < rule.Length; i++) { if (rule[i].Equals('"')) { break; } builder.Append(rule[i]); } result = new Terminal(builder.ToString()); } break; case var endItem when endItem.Equals(EndRecursion.Current.Notation): result = EndRecursion.Current; break; case var nonItem when Regex.IsMatch(nonItem.ToString(), "[a-zA-Z]"): { var builder = new StringBuilder(); foreach (var t in rule) { if (Regex.IsMatch(t.ToString(), @"[,;|\[\]\{\}\(\)]")) { break; } builder.Append(t); } result = (from item in listOfExistedTerminals where item.Name.Equals(builder.ToString()) select item).SingleOrDefault(); if (result == null) { var emptyNonTerm = this._actualDefinition.GetNewNonTerminalInstance(builder.ToString()); result = emptyNonTerm; } } break; case var groupItem when Regex.IsMatch(groupItem, @"[\[\{\(]"): { var restOfRepRule = rule.Substring(1, rule.Length - 1); switch (groupItem) { case Repetition.notation: var repItem = GetEBNFItem(restOfRepRule, listOfExistedTerminals, Repetition.endNotation); result = new Repetition(repItem, this._cacheLength); break; case Optional.notation: var opItem = GetEBNFItem(restOfRepRule, listOfExistedTerminals, Optional.endNotation); result = new Optional(opItem); break; case Grouping.notation: var grItem = GetEBNFItem(restOfRepRule, listOfExistedTerminals, Grouping.endNotation); result = new Grouping(grItem); break; } } break; default: throw new GrammarParseException($"Grammar parse error. Can't recognize character: {rule[0]}. Check missing rules characters.", new ArgumentException()); } return(result); }