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); }
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); }
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); }
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); }
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); }