コード例 #1
0
ファイル: NdAnalyzer.cs プロジェクト: Jos635/SharpPeg
        private bool Analyze(OptimizationContext context, NdState initialState)
        {
            var processed = new List <NdState> [context.Count];

            for (var i = 0; i < processed.Length; i++)
            {
                processed[i] = new List <NdState>();
            }

            var overflowProtection = 0;

            var stack = new Stack <NdState>();

            stack.Push(initialState);
            while (stack.Count > 0)
            {
                if (stack.Count > context.Count)
                {
                    // Bailout if stack starts to explode
                    return(false);
                }
                else if (overflowProtection++ >= context.Count * 250)
                {
                    // Or if we're just taking too long
                    return(false);
                }

                var current = stack.Pop();
                if (current.AAndBAreSameState() || !validPositionsForB[current.PositionB] || processed[current.PositionA].Any(item => current.PracticallyEquivalent(item, context, stack)))
                {
                    // Already processed this state.
                    continue;
                }

                processed[current.PositionA].Add(current);

                NdStateView view;
                if (current.AdvancesB < current.AdvancesA || context[current.PositionA].Matches(InstructionType.Return))
                {
                    view = current.B;
                }
                else
                {
                    view = current.A;
                }

                if (!Step(context, stack, view, current))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #2
0
ファイル: NdAnalyzer.cs プロジェクト: Jos635/SharpPeg
        // TODO: Not used anywhere
        public NdAnalyzer(OptimizationContext context, int posA, int posB, ushort variable)
        {
            this.Variable = variable;
            var graphs       = CreateVariableUsageGraphs(context);
            var initialState = new NdState(Variable, graphs, context.VariableAllocator, posA, posB);

            validPositionsForB = CalculatePositionsWhereBMightHaveBeen(context, posA, variable);

            var bounds = context.Backtracer.GetBoundsAt(posB, false);

            initialState = initialState
                           .SetMinBounds(bounds.MinBounds)
                           .SetMaxBounds(bounds.MaxBounds);

            Result = Analyze(context, initialState);
        }
コード例 #3
0
ファイル: NdAnalyzer.cs プロジェクト: Jos635/SharpPeg
        private bool Step(OptimizationContext context, Stack <NdState> stack, NdStateView view, NdState state)
        {
            var instruction = context[view.Position];

            switch (instruction.Type)
            {
            case InstructionType.BoundsCheck:
                switch (state.CheckBounds(instruction.Offset + view.Advances))
                {
                case EvaluationResult.Success:
                    stack.Push(view.Move(1));
                    break;

                case EvaluationResult.Fail:
                    stack.Push(view.WithPosition(context.GetLabelPosition(instruction.Label)));
                    break;

                case EvaluationResult.Inconclusive:
                    stack.Push(view.Move(1).SetMinBounds(instruction.Offset + view.Advances));
                    stack.Push(view.WithPosition(context.GetLabelPosition(instruction.Label)).SetMaxBounds(instruction.Offset + view.Advances));
                    break;
                }
                break;

            case InstructionType.Char:
                switch (state.CheckChars(context, instruction, instruction.Offset + view.Advances))
                {
                case EvaluationResult.Success:
                    stack.Push(view.Move(1));
                    break;

                case EvaluationResult.Fail:
                    stack.Push(view.WithPosition(context.GetLabelPosition(instruction.Label)));
                    break;

                case EvaluationResult.Inconclusive:
                    stack.Push(view.Move(1).MatchSuccess(context, instruction, instruction.Offset + view.Advances));
                    stack.Push(view.WithPosition(context.GetLabelPosition(instruction.Label)).MatchFail(context, instruction, instruction.Offset + view.Advances));
                    break;
                }
                break;

            case InstructionType.Jump:
                stack.Push(view.WithPosition(context.GetLabelPosition(instruction.Label)));
                break;

            case InstructionType.Call:
                return(false);

            case InstructionType.Advance:
                if (instruction.Offset < 0)
                {
                    return(false);
                }

                stack.Push(view.AdvanceAndMoveOneForward(instruction.Offset));
                break;

            case InstructionType.StorePosition:
                stack.Push(view.StoreAndMoveOneForward(instruction.Data1));
                break;

            case InstructionType.RestorePosition:
                if (view.Vars[instruction.Data1] == -1)
                {
                    return(false);
                }

                stack.Push(view.WithAdvancesAndMoveOneForward(view.Vars[instruction.Data1]));
                break;

            case InstructionType.MarkLabel:
            case InstructionType.Capture:
                if (instruction.Data2 != Variable)
                {
                    return(false);
                }
                break;

            case InstructionType.Return:
                stack.Push(state);
                break;

            default:
                throw new NotImplementedException();
            }

            return(true);
        }
コード例 #4
0
 public ViewB(NdState state)
 {
     this.state = state;
 }
コード例 #5
0
        public bool PracticallyEquivalent(NdState other, OptimizationContext context, Stack <NdState> stack)
        {
            var diff = AdvancesB - other.AdvancesB;

            if (PositionA == other.PositionA &&
                PositionB == other.PositionB &&
                AdvancesA - other.AdvancesA == AdvancesB - other.AdvancesB &&
                ((MinBounds == -1 && other.MinBounds == -1) || (MinBounds == other.MinBounds + diff)) &&
                ((MaxBounds == int.MaxValue && other.MaxBounds == int.MaxValue) || (MaxBounds == other.MaxBounds + diff)) &&
                MatchingCharacters.Count >= other.MatchingCharacters.Count &&
                FailingCharacters.Count >= other.FailingCharacters.Count)
            {
                for (var i = 0; i < VarAs.Length; i++)
                {
                    if (VarAs[i] != other.VarAs[i] && VarAs[i] != other.VarAs[i] + diff)
                    {
                        return(false);
                    }
                }

                for (var i = 0; i < VarBs.Length; i++)
                {
                    if (VarBs[i] != other.VarBs[i] && VarBs[i] != other.VarBs[i] + diff)
                    {
                        return(false);
                    }
                }

                var newState = new Lazy <NdState>(() => new NdState(other.Variable, other.Vug, other.PositionA, other.PositionB, other.AdvancesA, other.AdvancesB, other.MinBounds, other.MaxBounds, other.VarAs, other.VarBs, other.MatchingCharacters.Clone(), other.FailingCharacters.Clone()));
                var addAdditionalCondition = false;

                // TODO: Check that this has at least every match / fail that other has too.
                for (var i = 0; i < other.MatchingCharacters.Count; i++)
                {
                    for (var j = 0; j < other.MatchingCharacters[i].Count; j++)
                    {
                        var current = other.MatchingCharacters[i][j];
                        if (!MatchingCharacters[i].Any(item => item.Data1 == current.Data1 && item.Data2 == current.Data2))
                        {
                            if (diff == 0)
                            {
                                return(false);
                            }

                            addAdditionalCondition = true;
                            newState.Value.MatchingCharacters[i] = newState.Value.MatchingCharacters[i].Where(item => item != current).ToList();
                        }
                    }
                }

                for (var i = 0; i < other.FailingCharacters.Count; i++)
                {
                    for (var j = 0; j < other.FailingCharacters[i].Count; j++)
                    {
                        var current = other.FailingCharacters[i][j];
                        if (!FailingCharacters[i].Any(item => item.Data1 == current.Data1 && item.Data2 == current.Data2))
                        {
                            if (diff == 0)
                            {
                                return(false);
                            }

                            addAdditionalCondition = true;
                            newState.Value.FailingCharacters[i] = newState.Value.FailingCharacters[i].Where(item => item != current).ToList();
                        }
                    }
                }

                if (addAdditionalCondition)
                {
                    stack.Push(newState.Value);
                }

                return(true);
            }

            return(false);
        }