예제 #1
0
        private RangeParseResult ParseRangeGroup(IEnumerator <Lexem> tokens, string context)
        {
            Type rangeType = null;

            while (tokens.Current.NextLexem != null && RangeTypes.Contains(tokens.Current.NextLexem.Value))
            {
                rangeType = ParseRangeType(tokens, context: context);
            }

            if (rangeType == null)
            {
                ExpectNextToken(tokens, RangeTypes, context);
            }

            return(ParseRangeGroupContents(tokens, rangeType, context));
        }
예제 #2
0
        private RangeParseResult ParseRangeGroupContents(IEnumerator <Lexem> tokens, Type rangeType, string context)
        {
            List <object> minimumValues = new List <object>();
            List <object> maximumValues = new List <object>();

            var range = ParseRange(tokens, rangeType, context: context);

            minimumValues.AddRange(range.Select(r => r.Item1));
            maximumValues.AddRange(range.Select(r => r.Item2));

            if (tokens.Current.NextLexem != null)
            {
                RangeParseResult nextRange = null;
                if (tokens.Current.NextLexem.Value == "(")
                {
                    nextRange = ParseRangeGroupContents(tokens, rangeType, context);
                }
                else if (RangeTypes.Contains(tokens.Current.NextLexem.Value))
                {
                    nextRange = ParseRangeGroup(tokens, context);

                    if (!nextRange.Type.Equals(rangeType))
                    {
                        throw new InvalidDataException("Non-uniform ranges are not supported. First encountered range: " + TypeToRangeDescription(rangeType) + ", next: " + TypeToRangeDescription(nextRange.Type));
                    }
                }

                if (nextRange != null)
                {
                    minimumValues.AddRange(nextRange.MinimumValues);
                    maximumValues.AddRange(nextRange.MaximumValues);
                }
            }

            return(new RangeParseResult()
            {
                Type = rangeType, MinimumValues = minimumValues, MaximumValues = maximumValues
            });
        }
예제 #3
0
        private IEnumerable <Tuple <object, object> > ParseRange(IEnumerator <Lexem> tokens, Type rangeType, string context)
        {
            if (tokens.Current.NextLexem != null && RangeTypes.Contains(tokens.Current.NextLexem.Value))
            {
                return(Enumerable.Empty <Tuple <object, object> >());
            }

            ExpectNextToken(tokens, "(", context: context + " range");

            TypeConverter converter = TypeDescriptor.GetConverter(rangeType);

            List <Tuple <object, object> > result = new List <Tuple <object, object> >();

            List <string> rangeTokens = new List <string>();
            string        token       = GetNextToken(tokens, context: context + " range");

            while (token != ")") // scanner guarantees that all parentheses are matched
            {
                rangeTokens.Add(token);
                token = GetNextToken(tokens, context: context + " range");
            }

            if (rangeTokens.Count == 2)
            {
                result.Add(ParseRangeValues(rangeTokens[0], rangeTokens[1], converter, context: context));
            }
            else if (rangeTokens.Count == 3)
            {
                int count = 0;

                Exception innerException = null;
                try
                {
                    count = int.Parse(rangeTokens[0], CultureInfo.InvariantCulture);
                }
                catch (FormatException e)
                {
                    innerException = e;
                }
                catch (OverflowException e)
                {
                    innerException = e;
                }
                catch (ArgumentNullException e)
                {
                    innerException = e;
                }

                if (innerException != null)
                {
                    throw new InvalidDataException("Could not parse range multiplicity value: '" + rangeTokens[0] + "' when parsing " + context);
                }

                var rangeTuple = ParseRangeValues(rangeTokens[1], rangeTokens[2], converter, context: context);
                for (int i = 0; i < count; ++i)
                {
                    result.Add(rangeTuple);
                }
            }

            return(result);
        }