示例#1
0
 public void BranchesAreAdded()
 {
     var parse = new Parse("tr", string.Empty, null, null);
     parse.Add(new Parse("td", "first", null, null));
     Assert.AreEqual("first", parse.Parts.Body);
     parse.Add(new Parse("td", "second", null, null));
     Assert.AreEqual("second", parse.Parts.More.Body);
     parse.Add(new Parse("td", "third", null, null));
     Assert.AreEqual("third", parse.Parts.Last.Body);
 }
示例#2
0
        [Test] public void BranchesAreAdded()
        {
            var parse = new Parse("tr", string.Empty, null, null);

            parse.Add(new Parse("td", "first", null, null));
            Assert.AreEqual("first", parse.Parts.Body);
            parse.Add(new Parse("td", "second", null, null));
            Assert.AreEqual("second", parse.Parts.More.Body);
            parse.Add(new Parse("td", "third", null, null));
            Assert.AreEqual("third", parse.Parts.Last.Body);
        }
示例#3
0
 public override Tree<Cell> MakeCell(string text, string tag, IEnumerable<Tree<Cell>> branches) {
     var result = new Parse(tag, text, null, null);
     foreach (var branch in branches) {
         result.Add(branch);
     }
     return result;
 }
示例#4
0
        public override Tree <Cell> MakeCell(string text, string tag, IEnumerable <Tree <Cell> > branches)
        {
            var result = new Parse(tag, text, null, null);

            foreach (var branch in branches)
            {
                result.Add(branch);
            }
            return(result);
        }
示例#5
0
 public override Tree<Cell> MakeCell(string text, string tag, IEnumerable<Tree<Cell>> branches)
 {
     var result = new Parse(new CellBase(text));
     if (!string.IsNullOrEmpty(tag)) result.Value.SetTag(tag);
     if (!string.IsNullOrEmpty(text)) result.Value.SetAttribute(CellAttribute.Body, text);
     foreach (var branch in branches) {
         result.Add(branch);
     }
     return result;
 }
示例#6
0
 public override void DoTable(Parse table)
 {
     if (!_trueOrFalse)
     {
         var branch = new Parse("td colspan='" + _colSpan + "'", _message, null, null);
         Wrong(branch);
         table.Add(branch);
     }
     else
     {
         Right(table.Parts.Leaf);
     }
 }
        public override Tree <Cell> MakeCell(string text, string tag, IEnumerable <Tree <Cell> > branches)
        {
            var result = new Parse(new CellBase(text));

            if (!string.IsNullOrEmpty(tag))
            {
                result.Value.SetTag(tag);
            }
            if (!string.IsNullOrEmpty(text))
            {
                result.Value.SetAttribute(CellAttribute.Body, text);
            }
            foreach (var branch in branches)
            {
                result.Add(branch);
            }
            return(result);
        }
示例#8
0
        /// <summary>
        /// Produces all events for the specified sentence chunks and adds them to the specified list.
        /// </summary>
        /// <param name="newEvents">A list of events to be added to.</param>
        /// <param name="chunks">Pre-chunked constituents of a sentence.</param>
        protected override void AddParseEvents(List<Event> newEvents, Parse[] chunks) {
            /** Frontier nodes built from node in a completed parse.  Specifically,
              * they have all their children regardless of the stage of parsing.*/

            var rightFrontier = new List<Parse>();
            var builtNodes = new List<Parse>();

            /** Nodes which characterize what the parse looks like to the parser as its being built.
             * Specifically, these nodes don't have all their children attached like the parents of
             * the chunk nodes do.*/
            var currentChunks = new Parse[chunks.Length];
            for (var ci = 0; ci < chunks.Length; ci++) {
                currentChunks[ci] = (Parse) chunks[ci].Clone();
                currentChunks[ci].PreviousPunctuationSet = chunks[ci].PreviousPunctuationSet;
                currentChunks[ci].NextPunctuationSet = chunks[ci].NextPunctuationSet;
                currentChunks[ci].Label = AbstractBottomUpParser.COMPLETE;
                chunks[ci].Label = AbstractBottomUpParser.COMPLETE;
            }
            for (var ci = 0; ci < chunks.Length; ci++) {
                //System.err.println("parserEventStream.addParseEvents: chunks="+Arrays.asList(chunks));
                var parent = chunks[ci].Parent;
                var prevParent = chunks[ci];
                
                //var off = 0;
                //build un-built parents
                if (!chunks[ci].IsPosTag) {
                    builtNodes.Add(chunks[ci]);
                    //builtNodes[off++] = chunks[ci];
                }

                //perform build stages
                while (parent.Type != AbstractBottomUpParser.TOP_NODE && parent.Label == null) {
                    if (parent.Label == null && prevParent.Type != parent.Type) {
                        //build level
                        // if (debug) System.err.println("Build: " + parent.Type + " for: " + currentChunks[ci]);
                        if (Type == ParserEventTypeEnum.Build) {
                            newEvents.Add(new Event(parent.Type, buildContextGenerator.GetContext(currentChunks, ci)));
                        }
                        builtNodes.Add(parent);
                        //builtNodes[off++] = parent;
                        var newParent = new Parse(currentChunks[ci].Text, currentChunks[ci].Span, parent.Type, 1, 0);
                        newParent.Add(currentChunks[ci], Rules);
                        newParent.PreviousPunctuationSet = currentChunks[ci].PreviousPunctuationSet;
                        newParent.NextPunctuationSet = currentChunks[ci].NextPunctuationSet;
                        currentChunks[ci].Parent = newParent;
                        currentChunks[ci] = newParent;
                        newParent.Label = Parser.BUILT;

                        //see if chunk is complete
                        if (LastChild(chunks[ci], parent)) {
                            if (Type == ParserEventTypeEnum.Check) {
                                newEvents.Add(new Event(AbstractBottomUpParser.COMPLETE,
                                    checkContextGenerator.GetContext(currentChunks[ci], currentChunks, ci, false)));
                            }
                            currentChunks[ci].Label = AbstractBottomUpParser.COMPLETE;
                            parent.Label = AbstractBottomUpParser.COMPLETE;
                        } else {
                            if (Type == ParserEventTypeEnum.Check) {
                                newEvents.Add(new Event(AbstractBottomUpParser.INCOMPLETE,
                                    checkContextGenerator.GetContext(currentChunks[ci], currentChunks, ci, false)));
                            }
                            currentChunks[ci].Label = AbstractBottomUpParser.INCOMPLETE;
                            parent.Label = AbstractBottomUpParser.COMPLETE;
                        }

                        chunks[ci] = parent;
                        //System.err.println("build: "+newParent+" for "+parent);
                    }
                    //TODO: Consider whether we need to set this label or train parses at all.

                    parent.Label = Parser.BUILT;
                    prevParent = parent;
                    parent = parent.Parent;
                }
                //decide to attach
                if (Type == ParserEventTypeEnum.Build) {
                    newEvents.Add(new Event(Parser.DONE, buildContextGenerator.GetContext(currentChunks, ci)));
                }
                //attach node
                string attachType = null;
                /** Node selected for attachment. */
                Parse attachNode = null;
                var attachNodeIndex = -1;
                if (ci == 0) {
                    var top = new Parse(currentChunks[ci].Text, new Span(0, currentChunks[ci].Text.Length),
                        AbstractBottomUpParser.TOP_NODE, 1, 0);
                    top.Insert(currentChunks[ci]);
                } else {
                    /** Right frontier consisting of partially-built nodes based on current state of the parse.*/
                    var currentRightFrontier = Parser.GetRightFrontier(currentChunks[0], Punctuation);
                    if (currentRightFrontier.Count != rightFrontier.Count) {
                        throw new InvalidOperationException("frontiers mis-aligned: " + currentRightFrontier.Count +
                                                            " != " + rightFrontier.Count + " " + currentRightFrontier +
                                                            " " + rightFrontier);
                        //System.exit(1);
                    }
                    var parents = GetNonAdjoinedParent(chunks[ci]);
                    //try daughters first.
                    for (var cfi = 0; cfi < currentRightFrontier.Count; cfi++) {
                        var frontierNode = rightFrontier[cfi];
                        var cfn = currentRightFrontier[cfi];
                        if (!Parser.checkComplete || cfn.Label != AbstractBottomUpParser.COMPLETE) {
                            
                            //if (debug) System.err.println("Looking at attachment site (" + cfi + "): " + cfn.Type + " ci=" + i + " cs=" + nonPunctChildCount(cfn) + ", " + cfn + " :for " + currentChunks[ci].Type + " " + currentChunks[ci] + " -> " + parents);
                            if (parents.ContainsKey(frontierNode) && attachNode == null && parents[frontierNode] == NonPunctChildCount(cfn)) {
                                attachType = Parser.ATTACH_DAUGHTER;
                                attachNodeIndex = cfi;
                                attachNode = cfn;
                                if (Type == ParserEventTypeEnum.Attach) {
                                    newEvents.Add(new Event(attachType,
                                        attachContextGenerator.GetContext(currentChunks, ci, currentRightFrontier,
                                            attachNodeIndex)));
                                }
                                //System.err.println("daughter attach "+attachNode+" at "+fi);
                            }
                        } /* else {
                            if (debug) System.err.println("Skipping (" + cfi + "): " + cfn.Type + "," + cfn.getPreviousPunctuationSet() + " " + cfn + " :for " + currentChunks[ci].Type + " " + currentChunks[ci] + " -> " + parents);
                        }
                        // Can't attach past first incomplete node.
                        if (Parser.checkComplete && cfn.getLabel().equals(Parser.INCOMPLETE)) {
                            if (debug) System.err.println("breaking on incomplete:" + cfn.Type + " " + cfn);
                            break;
                        }
                        */
                    }
                    //try sisters, and generate non-attach events.
                    for (var cfi = 0; cfi < currentRightFrontier.Count; cfi++) {
                        var frontierNode = rightFrontier[cfi];
                        var cfn = currentRightFrontier[cfi];
                        if (attachNode == null && parents.ContainsKey(frontierNode.Parent)
                            && frontierNode.Type.Equals(frontierNode.Parent.Type)
                            ) {
                            //&& frontierNode.Parent.getLabel() == null) {
                            attachType = Parser.ATTACH_SISTER;
                            attachNode = cfn;
                            attachNodeIndex = cfi;
                            if (Type == ParserEventTypeEnum.Attach) {
                                newEvents.Add(new Event(Parser.ATTACH_SISTER,
                                    attachContextGenerator.GetContext(currentChunks, ci, currentRightFrontier, cfi)));
                            }
                            chunks[ci].Parent.Label = Parser.BUILT;
                            //System.err.println("in search sister attach "+attachNode+" at "+cfi);
                        } else if (cfi == attachNodeIndex) {
                            //skip over previously attached daughter.
                        } else {
                            if (Type == ParserEventTypeEnum.Attach) {
                                newEvents.Add(new Event(Parser.NON_ATTACH,
                                    attachContextGenerator.GetContext(currentChunks, ci, currentRightFrontier, cfi)));
                            }
                        }
                        //Can't attach past first incomplete node.
                        if (Parser.checkComplete && cfn.Label.Equals(AbstractBottomUpParser.INCOMPLETE)) {
                            //if (debug) System.err.println("breaking on incomplete:" + cfn.Type + " " + cfn);
                            break;
                        }
                    }
                    //attach Node
                    if (attachNode != null) {
                        if (attachType == Parser.ATTACH_DAUGHTER) {
                            var daughter = currentChunks[ci];
                            //if (debug) System.err.println("daughter attach a=" + attachNode.Type + ":" + attachNode + " d=" + daughter + " com=" + lastChild(chunks[ci], rightFrontier.get(attachNodeIndex)));
                            attachNode.Add(daughter, Rules);
                            daughter.Parent = attachNode;
                            if (LastChild(chunks[ci], rightFrontier[attachNodeIndex])) {
                                if (Type == ParserEventTypeEnum.Check) {
                                    newEvents.Add(new Event(AbstractBottomUpParser.COMPLETE,
                                        checkContextGenerator.GetContext(attachNode, currentChunks, ci, true)));
                                }
                                attachNode.Label = AbstractBottomUpParser.COMPLETE;
                            } else {
                                if (Type == ParserEventTypeEnum.Check) {
                                    newEvents.Add(new Event(AbstractBottomUpParser.INCOMPLETE,
                                        checkContextGenerator.GetContext(attachNode, currentChunks, ci, true)));
                                }
                            }
                        } else if (attachType == Parser.ATTACH_SISTER) {
                            var frontierNode = rightFrontier[attachNodeIndex];
                            rightFrontier[attachNodeIndex] = frontierNode.Parent;
                            var sister = currentChunks[ci];
                            //if (debug) System.err.println("sister attach a=" + attachNode.Type + ":" + attachNode + " s=" + sister + " ap=" + attachNode.Parent + " com=" + lastChild(chunks[ci], rightFrontier.get(attachNodeIndex)));
                            var newParent = attachNode.Parent.AdJoin(sister, Rules);

                            newParent.Parent = attachNode.Parent;
                            attachNode.Parent = newParent;
                            sister.Parent = newParent;
                            if (Equals(attachNode, currentChunks[0])) {
                                currentChunks[0] = newParent;
                            }
                            if (LastChild(chunks[ci], rightFrontier[attachNodeIndex])) {
                                if (Type == ParserEventTypeEnum.Check) {
                                    newEvents.Add(new Event(AbstractBottomUpParser.COMPLETE,
                                        checkContextGenerator.GetContext(newParent, currentChunks, ci, true)));
                                }
                                newParent.Label = AbstractBottomUpParser.COMPLETE;
                            } else {
                                if (Type == ParserEventTypeEnum.Check) {
                                    newEvents.Add(new Event(AbstractBottomUpParser.INCOMPLETE,
                                        checkContextGenerator.GetContext(newParent, currentChunks, ci, true)));
                                }
                                newParent.Label = AbstractBottomUpParser.INCOMPLETE;
                            }
                        }
                        //update right frontier
                        for (var ni = 0; ni < attachNodeIndex; ni++) {
                            //System.err.println("removing: "+rightFrontier.get(0));
                            rightFrontier.RemoveAt(0);
                        }
                    } else {
                        //System.err.println("No attachment!");
                        throw new InvalidOperationException("No Attachment: " + chunks[ci]);
                    }
                }
                rightFrontier.InsertRange(0, builtNodes);
                builtNodes.Clear();
            }
        }
示例#9
0
        private ICompilationUnit Parse(IProjectContent projectContent, string fileName, int[] lineLength, BooCompiler compiler)
        {
            compiler.Parameters.OutputWriter = new StringWriter();
            compiler.Parameters.TraceLevel   = System.Diagnostics.TraceLevel.Off;

            // Compile pipeline as of Boo 0.9.4:
            // Boo.Lang.Compiler.Pipelines.Parse:
            //   Boo.Lang.Compiler.Steps.Parsing
            // Boo.Lang.Compiler.Pipelines.ExpandMacros:
            //   Boo.Lang.Compiler.Steps.PreErrorChecking
            //   Boo.Lang.Compiler.Steps.MergePartialClasses
            //   Boo.Lang.Compiler.Steps.InitializeNameResolutionService
            //   Boo.Lang.Compiler.Steps.IntroduceGlobalNamespaces
            //   Boo.Lang.Compiler.Steps.TransformCallableDefinitions
            //   Boo.Lang.Compiler.Steps.BindTypeDefinitions
            //   Boo.Lang.Compiler.Steps.BindGenericParameters
            //   Boo.Lang.Compiler.Steps.ResolveImports
            //   Boo.Lang.Compiler.Steps.BindBaseTypes
            //   Boo.Lang.Compiler.Steps.MacroAndAttributeExpansion
            // Boo.Lang.Compiler.Pipelines.ResolveExpressions:
            //   Boo.Lang.Compiler.Steps.ExpandAstLiterals
            //   Boo.Lang.Compiler.Steps.IntroduceModuleClasses
            //   Boo.Lang.Compiler.Steps.NormalizeStatementModifiers
            //   Boo.Lang.Compiler.Steps.NormalizeTypeAndMemberDefinitions
            //   Boo.Lang.Compiler.Steps.NormalizeExpressions
            //   Boo.Lang.Compiler.Steps.BindTypeDefinitions
            //   Boo.Lang.Compiler.Steps.BindGenericParameters
            //   Boo.Lang.Compiler.Steps.BindEnumMembers
            //   Boo.Lang.Compiler.Steps.BindBaseTypes
            //   Boo.Lang.Compiler.Steps.CheckMemberTypes
            //   Boo.Lang.Compiler.Steps.BindMethods
            //   Boo.Lang.Compiler.Steps.ResolveTypeReferences
            //   Boo.Lang.Compiler.Steps.BindTypeMembers
            //   Boo.Lang.Compiler.Steps.CheckGenericConstraints
            //   Boo.Lang.Compiler.Steps.ProcessInheritedAbstractMembers
            //   Boo.Lang.Compiler.Steps.CheckMemberNames
            //   Boo.Lang.Compiler.Steps.ProcessMethodBodiesWithDuckTyping
            //   Boo.Lang.Compiler.Steps.ReifyTypes
            //   Boo.Lang.Compiler.Steps.VerifyExtensionMethods
            //   Boo.Lang.Compiler.Steps.TypeInference
            // Boo.Lang.Compiler.Pipelines.Compile:
            //   Boo.Lang.Compiler.Steps.ConstantFolding
            //   Boo.Lang.Compiler.Steps.CheckLiteralValues
            //   Boo.Lang.Compiler.Steps.OptimizeIterationStatements
            //   Boo.Lang.Compiler.Steps.BranchChecking
            //   Boo.Lang.Compiler.Steps.CheckIdentifiers
            //   Boo.Lang.Compiler.Steps.StricterErrorChecking
            //   Boo.Lang.Compiler.Steps.CheckAttributesUsage
            //   Boo.Lang.Compiler.Steps.ExpandDuckTypedExpressions
            //   Boo.Lang.Compiler.Steps.ProcessAssignmentsToValueTypeMembers
            //   Boo.Lang.Compiler.Steps.ExpandPropertiesAndEvents
            //   Boo.Lang.Compiler.Steps.CheckMembersProtectionLevel
            //   Boo.Lang.Compiler.Steps.NormalizeIterationStatements
            //   Boo.Lang.Compiler.Steps.ProcessSharedLocals
            //   Boo.Lang.Compiler.Steps.ProcessClosures
            //   Boo.Lang.Compiler.Steps.ProcessGenerators
            //   Boo.Lang.Compiler.Steps.ExpandVarArgsMethodInvocations
            //   Boo.Lang.Compiler.Steps.InjectCallableConversions
            //   Boo.Lang.Compiler.Steps.ImplementICallableOnCallableDefinitions
            //   Boo.Lang.Compiler.Steps.RemoveDeadCode
            //   Boo.Lang.Compiler.Steps.CheckNeverUsedMembers
            // Boo.Lang.Compiler.Pipelines.CompileToMemory:
            //   Boo.Lang.Compiler.Steps.EmitAssembly
            // Boo.Lang.Compiler.Pipelines.CompileToFile:
            //   Boo.Lang.Compiler.Steps.SaveAssembly


            CompilerPipeline compilePipe = new Parse();

            compilePipe.Add(new PreErrorChecking());
            compilePipe.Add(new MergePartialClasses());
            compilePipe.Add(new InitializeNameResolutionService());
            compilePipe.Add(new IntroduceGlobalNamespaces());
            // TransformCallableDefinitions: not used for CC
            compilePipe.Add(new BindTypeDefinitions());
            compilePipe.Add(new BindGenericParameters());
            compilePipe.Add(new ResolveImports());
            compilePipe.Add(new BindBaseTypes());
            compilePipe.Add(new MacroAndAttributeExpansion());
            compilePipe.Add(new IntroduceModuleClasses());

            var parsingStep = compilePipe[0];
            //compiler.Parameters.Environment.Provide<ParserSettings>().TabSize = 1;

            ConvertVisitor visitor = new ConvertVisitor(lineLength, projectContent);

            visitor.Cu.FileName = fileName;
            compilePipe.Add(visitor);

            compilePipe.BreakOnErrors    = false;
            compiler.Parameters.Pipeline = compilePipe;
            compiler.Parameters.References.Add(typeof(Boo.Lang.Useful.Attributes.SingletonAttribute).Assembly);

            int errorCount = 0;

            compilePipe.AfterStep += delegate(object sender, CompilerStepEventArgs args) {
                if (args.Step == parsingStep)
                {
                    errorCount = args.Context.Errors.Count;
                }
            };
            try {
                compiler.Run();
                visitor.Cu.ErrorsDuringCompile = errorCount > 0;
            } catch (Exception ex) {
                MessageService.ShowException(ex);
            }
            return(visitor.Cu);
        }
示例#10
0
        /// <summary>
        /// Produces all events for the specified sentence chunks and adds them to the specified list.
        /// </summary>
        /// <param name="newEvents">A list of events to be added to.</param>
        /// <param name="chunks">Pre-chunked constituents of a sentence.</param>
        protected override void AddParseEvents(List <Event> newEvents, Parse[] chunks)
        {
            /* Frontier nodes built from node in a completed parse.  Specifically,
             * they have all their children regardless of the stage of parsing.*/

            var rightFrontier = new List <Parse>();
            var builtNodes    = new List <Parse>();

            /* Nodes which characterize what the parse looks like to the parser as its being built.
             * Specifically, these nodes don't have all their children attached like the parents of
             * the chunk nodes do.*/
            var currentChunks = new Parse[chunks.Length];

            for (var ci = 0; ci < chunks.Length; ci++)
            {
                currentChunks[ci] = (Parse)chunks[ci].Clone();
                currentChunks[ci].PreviousPunctuationSet = chunks[ci].PreviousPunctuationSet;
                currentChunks[ci].NextPunctuationSet     = chunks[ci].NextPunctuationSet;
                currentChunks[ci].Label = AbstractBottomUpParser.COMPLETE;
                chunks[ci].Label        = AbstractBottomUpParser.COMPLETE;
            }
            for (var ci = 0; ci < chunks.Length; ci++)
            {
                //System.err.println("parserEventStream.addParseEvents: chunks="+Arrays.asList(chunks));
                var parent     = chunks[ci].Parent;
                var prevParent = chunks[ci];

                //var off = 0;
                //build un-built parents
                if (!chunks[ci].IsPosTag)
                {
                    builtNodes.Add(chunks[ci]);
                    //builtNodes[off++] = chunks[ci];
                }

                //perform build stages
                while (parent.Type != AbstractBottomUpParser.TOP_NODE && parent.Label == null)
                {
                    if (parent.Label == null && prevParent.Type != parent.Type)
                    {
                        //build level
                        // if (debug) System.err.println("Build: " + parent.Type + " for: " + currentChunks[ci]);
                        if (Type == ParserEventTypeEnum.Build)
                        {
                            newEvents.Add(new Event(parent.Type, buildContextGenerator.GetContext(currentChunks, ci)));
                        }
                        builtNodes.Add(parent);
                        //builtNodes[off++] = parent;
                        var newParent = new Parse(currentChunks[ci].Text, currentChunks[ci].Span, parent.Type, 1, 0);
                        newParent.Add(currentChunks[ci], Rules);
                        newParent.PreviousPunctuationSet = currentChunks[ci].PreviousPunctuationSet;
                        newParent.NextPunctuationSet     = currentChunks[ci].NextPunctuationSet;
                        currentChunks[ci].Parent         = newParent;
                        currentChunks[ci] = newParent;
                        newParent.Label   = Parser.BUILT;

                        //see if chunk is complete
                        if (LastChild(chunks[ci], parent))
                        {
                            if (Type == ParserEventTypeEnum.Check)
                            {
                                newEvents.Add(new Event(AbstractBottomUpParser.COMPLETE,
                                                        checkContextGenerator.GetContext(currentChunks[ci], currentChunks, ci, false)));
                            }
                            currentChunks[ci].Label = AbstractBottomUpParser.COMPLETE;
                            parent.Label            = AbstractBottomUpParser.COMPLETE;
                        }
                        else
                        {
                            if (Type == ParserEventTypeEnum.Check)
                            {
                                newEvents.Add(new Event(AbstractBottomUpParser.INCOMPLETE,
                                                        checkContextGenerator.GetContext(currentChunks[ci], currentChunks, ci, false)));
                            }
                            currentChunks[ci].Label = AbstractBottomUpParser.INCOMPLETE;
                            parent.Label            = AbstractBottomUpParser.COMPLETE;
                        }

                        chunks[ci] = parent;
                        //System.err.println("build: "+newParent+" for "+parent);
                    }
                    //TODO: Consider whether we need to set this label or train parses at all.

                    parent.Label = Parser.BUILT;
                    prevParent   = parent;
                    parent       = parent.Parent;
                }
                //decide to attach
                if (Type == ParserEventTypeEnum.Build)
                {
                    newEvents.Add(new Event(Parser.DONE, buildContextGenerator.GetContext(currentChunks, ci)));
                }
                //attach node
                string attachType = null;
                /* Node selected for attachment. */
                Parse attachNode      = null;
                var   attachNodeIndex = -1;
                if (ci == 0)
                {
                    var top = new Parse(currentChunks[ci].Text, new Span(0, currentChunks[ci].Text.Length),
                                        AbstractBottomUpParser.TOP_NODE, 1, 0);
                    top.Insert(currentChunks[ci]);
                }
                else
                {
                    /* Right frontier consisting of partially-built nodes based on current state of the parse.*/
                    var currentRightFrontier = Parser.GetRightFrontier(currentChunks[0], Punctuation);
                    if (currentRightFrontier.Count != rightFrontier.Count)
                    {
                        throw new InvalidOperationException("frontiers mis-aligned: " + currentRightFrontier.Count +
                                                            " != " + rightFrontier.Count + " " + currentRightFrontier +
                                                            " " + rightFrontier);
                        //System.exit(1);
                    }
                    var parents = GetNonAdjoinedParent(chunks[ci]);
                    //try daughters first.
                    for (var cfi = 0; cfi < currentRightFrontier.Count; cfi++)
                    {
                        var frontierNode = rightFrontier[cfi];
                        var cfn          = currentRightFrontier[cfi];
                        if (!Parser.checkComplete || cfn.Label != AbstractBottomUpParser.COMPLETE)
                        {
                            //if (debug) System.err.println("Looking at attachment site (" + cfi + "): " + cfn.Type + " ci=" + i + " cs=" + nonPunctChildCount(cfn) + ", " + cfn + " :for " + currentChunks[ci].Type + " " + currentChunks[ci] + " -> " + parents);
                            if (parents.ContainsKey(frontierNode) && attachNode == null && parents[frontierNode] == NonPunctChildCount(cfn))
                            {
                                attachType      = Parser.ATTACH_DAUGHTER;
                                attachNodeIndex = cfi;
                                attachNode      = cfn;
                                if (Type == ParserEventTypeEnum.Attach)
                                {
                                    newEvents.Add(new Event(attachType,
                                                            attachContextGenerator.GetContext(currentChunks, ci, currentRightFrontier,
                                                                                              attachNodeIndex)));
                                }
                                //System.err.println("daughter attach "+attachNode+" at "+fi);
                            }
                        } /* else {
                           * if (debug) System.err.println("Skipping (" + cfi + "): " + cfn.Type + "," + cfn.getPreviousPunctuationSet() + " " + cfn + " :for " + currentChunks[ci].Type + " " + currentChunks[ci] + " -> " + parents);
                           * }
                           * // Can't attach past first incomplete node.
                           * if (Parser.checkComplete && cfn.getLabel().equals(Parser.INCOMPLETE)) {
                           * if (debug) System.err.println("breaking on incomplete:" + cfn.Type + " " + cfn);
                           * break;
                           * }
                           */
                    }
                    //try sisters, and generate non-attach events.
                    for (var cfi = 0; cfi < currentRightFrontier.Count; cfi++)
                    {
                        var frontierNode = rightFrontier[cfi];
                        var cfn          = currentRightFrontier[cfi];
                        if (attachNode == null && parents.ContainsKey(frontierNode.Parent) &&
                            frontierNode.Type.Equals(frontierNode.Parent.Type)
                            )
                        {
                            //&& frontierNode.Parent.getLabel() == null) {
                            attachType      = Parser.ATTACH_SISTER;
                            attachNode      = cfn;
                            attachNodeIndex = cfi;
                            if (Type == ParserEventTypeEnum.Attach)
                            {
                                newEvents.Add(new Event(Parser.ATTACH_SISTER,
                                                        attachContextGenerator.GetContext(currentChunks, ci, currentRightFrontier, cfi)));
                            }
                            chunks[ci].Parent.Label = Parser.BUILT;
                            //System.err.println("in search sister attach "+attachNode+" at "+cfi);
                        }
                        else if (cfi == attachNodeIndex)
                        {
                            //skip over previously attached daughter.
                        }
                        else
                        {
                            if (Type == ParserEventTypeEnum.Attach)
                            {
                                newEvents.Add(new Event(Parser.NON_ATTACH,
                                                        attachContextGenerator.GetContext(currentChunks, ci, currentRightFrontier, cfi)));
                            }
                        }
                        //Can't attach past first incomplete node.
                        if (Parser.checkComplete && cfn.Label.Equals(AbstractBottomUpParser.INCOMPLETE))
                        {
                            //if (debug) System.err.println("breaking on incomplete:" + cfn.Type + " " + cfn);
                            break;
                        }
                    }
                    //attach Node
                    if (attachNode != null)
                    {
                        if (attachType == Parser.ATTACH_DAUGHTER)
                        {
                            var daughter = currentChunks[ci];
                            //if (debug) System.err.println("daughter attach a=" + attachNode.Type + ":" + attachNode + " d=" + daughter + " com=" + lastChild(chunks[ci], rightFrontier.get(attachNodeIndex)));
                            attachNode.Add(daughter, Rules);
                            daughter.Parent = attachNode;
                            if (LastChild(chunks[ci], rightFrontier[attachNodeIndex]))
                            {
                                if (Type == ParserEventTypeEnum.Check)
                                {
                                    newEvents.Add(new Event(AbstractBottomUpParser.COMPLETE,
                                                            checkContextGenerator.GetContext(attachNode, currentChunks, ci, true)));
                                }
                                attachNode.Label = AbstractBottomUpParser.COMPLETE;
                            }
                            else
                            {
                                if (Type == ParserEventTypeEnum.Check)
                                {
                                    newEvents.Add(new Event(AbstractBottomUpParser.INCOMPLETE,
                                                            checkContextGenerator.GetContext(attachNode, currentChunks, ci, true)));
                                }
                            }
                        }
                        else if (attachType == Parser.ATTACH_SISTER)
                        {
                            var frontierNode = rightFrontier[attachNodeIndex];
                            rightFrontier[attachNodeIndex] = frontierNode.Parent;
                            var sister = currentChunks[ci];
                            //if (debug) System.err.println("sister attach a=" + attachNode.Type + ":" + attachNode + " s=" + sister + " ap=" + attachNode.Parent + " com=" + lastChild(chunks[ci], rightFrontier.get(attachNodeIndex)));
                            var newParent = attachNode.Parent.AdJoin(sister, Rules);

                            newParent.Parent  = attachNode.Parent;
                            attachNode.Parent = newParent;
                            sister.Parent     = newParent;
                            if (Equals(attachNode, currentChunks[0]))
                            {
                                currentChunks[0] = newParent;
                            }
                            if (LastChild(chunks[ci], rightFrontier[attachNodeIndex]))
                            {
                                if (Type == ParserEventTypeEnum.Check)
                                {
                                    newEvents.Add(new Event(AbstractBottomUpParser.COMPLETE,
                                                            checkContextGenerator.GetContext(newParent, currentChunks, ci, true)));
                                }
                                newParent.Label = AbstractBottomUpParser.COMPLETE;
                            }
                            else
                            {
                                if (Type == ParserEventTypeEnum.Check)
                                {
                                    newEvents.Add(new Event(AbstractBottomUpParser.INCOMPLETE,
                                                            checkContextGenerator.GetContext(newParent, currentChunks, ci, true)));
                                }
                                newParent.Label = AbstractBottomUpParser.INCOMPLETE;
                            }
                        }
                        //update right frontier
                        for (var ni = 0; ni < attachNodeIndex; ni++)
                        {
                            //System.err.println("removing: "+rightFrontier.get(0));
                            rightFrontier.RemoveAt(0);
                        }
                    }
                    else
                    {
                        //System.err.println("No attachment!");
                        throw new InvalidOperationException("No Attachment: " + chunks[ci]);
                    }
                }
                rightFrontier.InsertRange(0, builtNodes);
                builtNodes.Clear();
            }
        }