Пример #1
0
 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;
 }
Пример #2
0
        /// <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);
        }
Пример #3
0
 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;
 }
Пример #4
0
 public Optional(IEBNFItem item)
 {
     this._item = item;
 }
Пример #5
0
 public Grouping(IEBNFItem item)
 {
     this._item         = item;
     this.MinimalLength = this._item.MinimalLength;
     this.IsOptional    = this._item.IsOptional;
 }
Пример #6
0
 /// <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;
 }
Пример #7
0
 public Repetition(IEBNFItem item, int cacheLength)
 {
     this._item  = item;
     this._cache = new SmartFixedCollectionPair <string, string[]>(cacheLength);
 }
Пример #8
0
        /// <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);
        }