Beispiel #1
0
        private NodeBunch BuildCustomItem(Element item)
        {
            var links = item.GetItemLinks();

            var headNode = _nodeFactory.CreateNode(item.AsPseudoList());

            if (headNode == null)
            {
                throw new BuildingException("Node factory returned null.");
            }

            var tree = headNode.FetchTree();

            if (tree.Count == 1)
            {
                var nodeBox = new NodeBox(headNode, links);
                return(new NodeBunch(nodeBox, nodeBox));
            }
            else
            {
                var headNodeBox = new NodeBox(headNode);

                try
                {
                    var tailNode    = tree.Single(x => x.EstablishedLinks.Count == 0);
                    var tailNodeBox = new NodeBox(tailNode, links);

                    return(new NodeBunch(headNodeBox, tailNodeBox));
                }
                catch (Exception ex)
                {
                    throw new BuildingException("More than one tail node (the node which doesn't have links).", ex);
                }
            }
        }
Beispiel #2
0
        public void DemandLink(NodeBox to)
        {
            if (_linksRequested)
            {
                throw new InvalidOperationException("Cannot demand link - links already were requested.");
            }

            if (_links.Any())
            {
                throw new InvalidOperationException("Cannot demand link if own links are present.");
            }

            _node.EstablishLink(to._node);
        }
Beispiel #3
0
        private NodeBunch BuildItem(Element item)
        {
            var       car = item.GetCarSymbolName();
            NodeBunch buildResult;

            INode   node;
            NodeBox nodeBox;

            switch (car)
            {
            case "BLOCK":
                buildResult = this.BuildBlock(item);
                break;

            case "ALT":
                buildResult = this.BuildAlt(item);
                break;

            case "OPT":
                buildResult = this.BuildOpt(item);
                break;

            case "SEQ":
                buildResult = this.BuildSeq(item);
                break;

            case "IDLE":
                node = new IdleNode(
                    _nodeFactory.NodeFamily,
                    item.GetItemName());
                nodeBox     = new NodeBox(node, item.GetItemLinks());
                buildResult = new NodeBunch(nodeBox, nodeBox);
                break;

            case "END":
                node        = EndNode.Instance;
                nodeBox     = new NodeBox(node);
                buildResult = new NodeBunch(nodeBox, nodeBox);
                break;

            default:
                buildResult = this.BuildCustomItem(item);
                break;
            }

            return(buildResult);
        }
Beispiel #4
0
        private NodeBunch BuildBlock(Element item)
        {
            var blockName = item.GetSingleKeywordArgument <Symbol>(":ref").Name;
            var defblock  = _defblocks[blockName];
            var args      = defblock.GetFreeArguments();

            var blockEnter    = new NodeBox(new IdleNode(_nodeFactory.NodeFamily, blockName));
            var contentResult = this.BuildContent(args);
            var blockExit     = new NodeBox(new IdleNode(_nodeFactory.NodeFamily, $"<exit of block> {blockName}"), item.GetItemLinks());

            blockEnter.DemandLink(contentResult.Head);
            contentResult.Tail.RequestLink(blockExit);

            var result = new NodeBunch(blockEnter, blockExit);

            return(result);
        }
Beispiel #5
0
        private NodeBunch BuildOpt(Element item)
        {
            var optName = item.GetItemName() ?? this.GetNextOptName();

            var optEnter = new NodeBox(new IdleNode(_nodeFactory.NodeFamily, optName));
            var optExit  = new NodeBox(new IdleNode(_nodeFactory.NodeFamily, $"<exit of opt> {optName}"), item.GetItemLinks());

            // short circuit!
            optEnter.DemandLink(optExit);

            var args          = item.GetFreeArguments();
            var contentResult = this.BuildContent(args);

            optEnter.DemandLink(contentResult.Head);
            contentResult.Tail.RequestLink(optExit);

            var result = new NodeBunch(optEnter, optExit);

            return(result);
        }
Beispiel #6
0
        private NodeBunch BuildAlt(Element item)
        {
            var altName      = item.GetItemName() ?? this.GetNextAltName();
            var alternatives = item.GetFreeArguments();

            var altEnter = new NodeBox(new IdleNode(_nodeFactory.NodeFamily, altName));
            var altExit  = new NodeBox(new IdleNode(_nodeFactory.NodeFamily, $"<exit of alt> {altName}"), item.GetItemLinks());

            foreach (var alternative in alternatives)
            {
                var alternativeResult = this.BuildItem(alternative);

                altEnter.DemandLink(alternativeResult.Head);
                alternativeResult.Tail.RequestLink(altExit);
            }

            var result = new NodeBunch(altEnter, altExit);

            return(result);
        }
Beispiel #7
0
        public void RequestLink(NodeBox to)
        {
            if (_node is FallbackNode)
            {
                return; // won't add any links to fallback node.
            }

            if (to == null)
            {
                throw new ArgumentNullException(nameof(to));
            }

            if (_linksRequested)
            {
                throw new InvalidOperationException("Cannot request link - links already were requested.");
            }

            if (_links.Any())
            {
                foreach (var link in _links)
                {
                    if (link == "NEXT")
                    {
                        _node.EstablishLink(to._node);
                    }
                    else
                    {
                        _node.ClaimLink(link);
                    }
                }
            }
            else
            {
                _node.EstablishLink(to._node);
            }

            _linksRequested = true;
        }
Beispiel #8
0
        private NodeBunch BuildContent(PseudoList content)
        {
            NodeBox head = null;
            NodeBox tail = null;

            foreach (var item in content)
            {
                var result = this.BuildItem(item);

                if (head == null)
                {
                    // first entry
                    head = result.Head;
                    tail = result.Tail;
                }
                else
                {
                    tail.RequestLink(result.Head);
                    tail = result.Tail;
                }
            }

            if (tail == null)
            {
                throw new BuildingException("Content is empty.");
            }

            if (tail.Links.Any())
            {
                throw new BuildingException("Last item in a content must not have explicit links.");
            }

            var buildResult = new NodeBunch(head, tail);

            return(buildResult);
        }
Beispiel #9
0
 public NodeBunch(NodeBox head, NodeBox tail)
 {
     this.Head = head ?? throw new ArgumentNullException(nameof(head));
     this.Tail = tail ?? throw new ArgumentNullException(nameof(tail));
 }