Exemplo n.º 1
0
		public override void VisitLeave(LimitingRepetition expression)
		{
			Int32? max = expression.Max;
			Int32? min = expression.Min;
			IsMatchPredicate local = _matchStack.Pop();

			_matchStack.Push(
				delegate(IInputIterator iterator)
				{
					Int32 cnt = 0;
					Int32 savePosition = iterator.Index;
					Boolean result = false;
					if (expression.VariableLengthExpression == null)
					{
						if (min != null)
						{
							if (max == null)
							{
								// has a minimum but no max cap
								savePosition = iterator.Index;
								while (local(iterator))
								{
									cnt++;
									if (savePosition == iterator.Index)
									{
										//InfiniteLoopDetectedException
										break;
									}
									savePosition = iterator.Index;
								}

								iterator.Index = savePosition;
								result = (cnt >= min);
							}
							else
							{
								// has a minimum and a max specified

								if (max < min)
								{
									throw new ArgumentException(
										"A Max property must be larger than Min when using LimitingRepetition.");
								}

								savePosition = iterator.Index;
								while (local(iterator))
								{
									cnt++;
									savePosition = iterator.Index;

									if (cnt >= max)
									{
										break;
									}
								}

								iterator.Index = savePosition;
								result = (cnt <= max && cnt >= min);
							}
						}
						else // min == null
						{
							if (max == null)
							{
								throw new ArgumentException(
									"A Min and/or Max must be specified when using LimitingRepetition.");
							}

							// zero or up to a max matches of e.
							savePosition = iterator.Index;
							while (local(iterator))
							{
								cnt++;
								savePosition = iterator.Index;

								if (cnt >= max)
								{
									break;
								}
							}

							iterator.Index = savePosition;
							result = (cnt <= max);
						}
					}
					else
					{
						var variableValues = _sandbox.Peek().ToArray().SelectMany(x=>x.Children).ToList();

						var varLengthBytes = Encoding.UTF8.GetBytes(expression.VariableLengthExpression);
						var varLengthIterator = new ByteInputIterator(varLengthBytes);

						var varLengthParser = new LimitingRepetitionVariableLengthExpressionParser();
						var varLengthParseTree = varLengthParser.Parse(varLengthIterator);

						var varLengthSolver = new LimitingRepetitionVariableLengthExpressionSolver(varLengthIterator, iterator, variableValues);
						varLengthParseTree.Accept(varLengthSolver);


						var value = (int)varLengthSolver.Result;
						savePosition = iterator.Index;
						while (value > cnt && local(iterator))
						{
							cnt++;
							savePosition = iterator.Index;

							if (cnt == value)
							{
								break;
							}
						}

						iterator.Index = savePosition;
						result = (cnt == value);

					}
					return result;
				}
				);
		}
        public override void VisitLeave(LimitingRepetition expression)
        {
            Int32?           max   = expression.Max;
            Int32?           min   = expression.Min;
            IsMatchPredicate local = _matchStack.Pop();

            _matchStack.Push(
                delegate(IInputIterator iterator)
            {
                Int32 cnt          = 0;
                Int32 savePosition = iterator.Index;
                Boolean result     = false;
                if (expression.VariableLengthExpression == null)
                {
                    if (min != null)
                    {
                        if (max == null)
                        {
                            // has a minimum but no max cap
                            savePosition = iterator.Index;
                            while (local(iterator))
                            {
                                cnt++;
                                if (savePosition == iterator.Index)
                                {
                                    //InfiniteLoopDetectedException
                                    break;
                                }
                                savePosition = iterator.Index;
                            }

                            iterator.Index = savePosition;
                            result         = (cnt >= min);
                        }
                        else
                        {
                            // has a minimum and a max specified

                            if (max < min)
                            {
                                throw new ArgumentException(
                                    "A Max property must be larger than Min when using LimitingRepetition.");
                            }

                            savePosition = iterator.Index;
                            while (local(iterator))
                            {
                                cnt++;
                                savePosition = iterator.Index;

                                if (cnt >= max)
                                {
                                    break;
                                }
                            }

                            iterator.Index = savePosition;
                            result         = (cnt <= max && cnt >= min);
                        }
                    }
                    else                             // min == null
                    {
                        if (max == null)
                        {
                            throw new ArgumentException(
                                "A Min and/or Max must be specified when using LimitingRepetition.");
                        }

                        // zero or up to a max matches of e.
                        savePosition = iterator.Index;
                        while (local(iterator))
                        {
                            cnt++;
                            savePosition = iterator.Index;

                            if (cnt >= max)
                            {
                                break;
                            }
                        }

                        iterator.Index = savePosition;
                        result         = (cnt <= max);
                    }
                }
                else
                {
                    var variableValues = _sandbox.Peek().ToArray().SelectMany(x => x.Children).ToList();

                    var varLengthBytes    = Encoding.UTF8.GetBytes(expression.VariableLengthExpression);
                    var varLengthIterator = new ByteInputIterator(varLengthBytes);

                    var varLengthParser    = new LimitingRepetitionVariableLengthExpressionParser();
                    var varLengthParseTree = varLengthParser.Parse(varLengthIterator);

                    var varLengthSolver = new LimitingRepetitionVariableLengthExpressionSolver(varLengthIterator, iterator, variableValues);
                    varLengthParseTree.Accept(varLengthSolver);


                    var value    = (int)varLengthSolver.Result;
                    savePosition = iterator.Index;
                    while (value > cnt && local(iterator))
                    {
                        cnt++;
                        savePosition = iterator.Index;

                        if (cnt == value)
                        {
                            break;
                        }
                    }

                    iterator.Index = savePosition;
                    result         = (cnt == value);
                }
                return(result);
            }
                );
        }