/// <summary>
        /// New sets of arcs are added after the last arc
        /// </summary>
        internal virtual void AddArc(Arc start, Arc end)
        {
            State state = null;

            if (_startArc == null)
            {
                _startArc = start;
                _endArc   = end;
            }
            else
            {
                bool done = false;

                // Successive <one-of> have 2 epsilon transition
                if (_endArc.IsEpsilonTransition && start.IsEpsilonTransition)
                {
                    // Trim the start tag.
                    start = TrimStart(start, _backend);

                    // If Trimming didn't create a non epsilon, try to trim the end
                    if (start.IsEpsilonTransition)
                    {
                        _endArc = TrimEnd(_endArc, _backend);

                        // start and end are still epsilon transition
                        if (_endArc.IsEpsilonTransition)
                        {
                            // we do the merging
                            State from = _endArc.Start;
                            State to   = start.End;
                            done = true;

                            if (from == null)
                            {
                                // Ignore the current _start _end
                                Arc.CopyTags(_endArc, start, Direction.Right);
                                _startArc = start;
                            }
                            else if (to == null)
                            {
                                // Ignore the old _startArc _endArc
                                Arc.CopyTags(start, _endArc, Direction.Left);
                                end = _endArc;
                            }
                            else
                            {
                                // No tags, just fold the start and end state
                                if (_endArc.IsPropertylessTransition && start.IsPropertylessTransition)
                                {
                                    // Move the end arc
                                    start.End     = null;
                                    _endArc.Start = null;
                                    _backend.MoveInputTransitionsAndDeleteState(from, to);
                                }
                                else
                                {
                                    // Discard the endstate and replace it with the startArc
                                    Arc.CopyTags(start, _endArc, Direction.Left);
                                    start.End   = null;
                                    _endArc.End = to;
                                }
                            }
                        }
                    }
                }

                if (!done)
                {
                    // If the last arc is an epsilon value then there is no need to create a new state
                    if (_endArc.IsEpsilonTransition && Graph.CanTagsBeMoved(_endArc, start))
                    {
                        // Copy the tags from "endArc" to the "start"
                        Arc.CopyTags(_endArc, start, Direction.Right);

                        if (_endArc.Start != null)
                        {
                            // Discard the endstate and replace it with the startArc
                            state         = _endArc.Start;
                            _endArc.Start = null;

                            // Connexion between the state end the start is done below
                            //state.OutArcs.Add (start);
                            //start.Start = state;
                        }
                        if (_endArc == _startArc)
                        {
                            _startArc = start;
                        }
                    }
                    else
                    {
                        // If the first arc is an epsilon value then there is no need to create a new state
                        if (start.IsEpsilonTransition && Graph.CanTagsBeMoved(start, _endArc))
                        {
                            // Copy the tags from "endArc" to the "start"
                            Arc.CopyTags(start, _endArc, Direction.Left);

                            if (start.End != null)
                            {
                                // Discard the endstate and replace it with the startArc
                                state       = start.End;
                                start.End   = null;
                                _endArc.End = state;
                                state       = null;
                            }
                            if (start == end)
                            {
                                end = _endArc;
                            }
                        }
                        else
                        {
                            // Create a new state
                            state = _backend.CreateNewState(_rule);

                            // Connect the new state with the end arc
                            _endArc.End = state;
                        }
                    }
                    // connect the arcs
                    if (state != null)
                    {
                        start.Start = state;
                    }
                }
                _endArc = end;
            }
        }
Beispiel #2
0
        internal virtual void AddArc(Arc start, Arc end)
        {
            State state = null;

            if (_startArc == null)
            {
                _startArc = start;
                _endArc   = end;
                return;
            }
            bool flag = false;

            if (_endArc.IsEpsilonTransition && start.IsEpsilonTransition)
            {
                start = TrimStart(start, _backend);
                if (start.IsEpsilonTransition)
                {
                    _endArc = TrimEnd(_endArc, _backend);
                    if (_endArc.IsEpsilonTransition)
                    {
                        State start2 = _endArc.Start;
                        State end2   = start.End;
                        flag = true;
                        if (start2 == null)
                        {
                            Arc.CopyTags(_endArc, start, Direction.Right);
                            _startArc = start;
                        }
                        else if (end2 == null)
                        {
                            Arc.CopyTags(start, _endArc, Direction.Left);
                            end = _endArc;
                        }
                        else if (_endArc.IsPropertylessTransition && start.IsPropertylessTransition)
                        {
                            start.End     = null;
                            _endArc.Start = null;
                            _backend.MoveInputTransitionsAndDeleteState(start2, end2);
                        }
                        else
                        {
                            Arc.CopyTags(start, _endArc, Direction.Left);
                            start.End   = null;
                            _endArc.End = end2;
                        }
                    }
                }
            }
            if (!flag)
            {
                if (_endArc.IsEpsilonTransition && Graph.CanTagsBeMoved(_endArc, start))
                {
                    Arc.CopyTags(_endArc, start, Direction.Right);
                    if (_endArc.Start != null)
                    {
                        state         = _endArc.Start;
                        _endArc.Start = null;
                    }
                    if (_endArc == _startArc)
                    {
                        _startArc = start;
                    }
                }
                else if (start.IsEpsilonTransition && Graph.CanTagsBeMoved(start, _endArc))
                {
                    Arc.CopyTags(start, _endArc, Direction.Left);
                    if (start.End != null)
                    {
                        state       = start.End;
                        start.End   = null;
                        _endArc.End = state;
                        state       = null;
                    }
                    if (start == end)
                    {
                        end = _endArc;
                    }
                }
                else
                {
                    state       = _backend.CreateNewState(_rule);
                    _endArc.End = state;
                }
                if (state != null)
                {
                    start.Start = state;
                }
            }
            _endArc = end;
        }