/// <summary> /// During a redution, pops the top symbol from the stack and gives it a tree action /// </summary> /// <param name="action">The tree action to apply to the symbol</param> public void ReductionPop(TreeAction action) { SubTree sub = stack[stackNext + popCount]; ReductionAddSub(sub, action); sub.Free(); popCount++; }
/// <summary> /// Finalizes the parse tree and returns it /// </summary> /// <returns>The final parse tree</returns> public AST GetTree() { // Get the axiom's sub tree SubTree sub = stack[stackNext - 2]; // Commit the remaining sub-tree sub.Commit(result); return(result); }
/// <summary> /// Clones this sub-tree /// </summary> /// <returns>The clone</returns> public SubTree Clone() { SubTree result = pool != null?pool.Acquire() : new SubTree(null, nodes.Length); int size = GetSize(); Array.Copy(nodes, result.nodes, size); Array.Copy(actions, result.actions, size); return(result); }
/// <summary> /// Push a token onto the stack /// </summary> /// <param name="index">The token's index in the parsed text</param> public void StackPushToken(int index) { SubTree single = poolSingle.Acquire(); single.SetupRoot(new TableElemRef(TableType.Token, index), TreeAction.None); if (stackNext == stack.Length) { Array.Resize(ref stack, stack.Length + LRkParser.INIT_STACK_SIZE); } stack[stackNext++] = single; }
/// <summary> /// Copy the root's children of this sub-tree to the given sub-tree's buffer beginning at the given index /// </summary> /// <param name="destination">The sub-tree to copy to</param> /// <param name="index">The starting index in the destination's buffer</param> /// <remarks> /// This methods only applies in the case of a depth 1 sub-tree (only a root and its children). /// The results of this method in the case of a depth 2 sub-tree is undetermined. /// </remarks> public void CopyChildrenTo(SubTree destination, int index) { if (nodes[0].count == 0) { return; } int size = GetSize() - 1; Array.Copy(nodes, 1, destination.nodes, index, size); Array.Copy(actions, 1, destination.actions, index, size); }
/// <summary> /// Copy the content of this sub-tree to the given sub-tree's buffer beginning at the given index /// </summary> /// <param name="destination">The sub-tree to copy to</param> /// <param name="index">The starting index in the destination's buffer</param> /// <remarks> /// This methods only applies in the case of a depth 1 sub-tree (only a root and its children). /// The results of this method in the case of a depth 2 sub-tree is undetermined. /// </remarks> public void CopyTo(SubTree destination, int index) { if (nodes[0].count == 0) { destination.nodes[index] = nodes[0]; destination.actions[index] = actions[0]; } else { int size = nodes[0].count + 1; Array.Copy(nodes, 0, destination.nodes, index, size); Array.Copy(actions, 0, destination.actions, index, size); } }
/// <summary> /// Prepares for the forthcoming reduction operations /// </summary> /// <param name="varIndex">The reduced variable index</param> /// <param name="length">The length of the reduction</param> /// <param name="action">The tree action applied onto the symbol</param> public void ReductionPrepare(int varIndex, int length, TreeAction action) { stackNext -= length; int estimation = ESTIMATION_BIAS; for (int i = 0; i != length; i++) { estimation += stack[stackNext + i].GetSize(); } cache = GetSubTree(estimation); cache.SetupRoot(new TableElemRef(TableType.Variable, varIndex), action); cacheNext = 1; handleNext = 0; popCount = 0; }
/// <summary> /// During a reduction, insert the given sub-tree /// </summary> /// <param name="sub">The sub-tree</param> /// <param name="action">The tree action applied onto the symbol</param> private void ReductionAddSub(SubTree sub, TreeAction action) { if (sub.GetActionAt(0) == TreeAction.ReplaceByChildren) { int directChildrenCount = sub.GetChildrenCountAt(0); while (handleNext + directChildrenCount >= handle.Length) { Array.Resize(ref handle, handle.Length + INIT_HANDLE_SIZE); } // copy the children to the cache sub.CopyChildrenTo(cache, cacheNext); // setup the handle int index = 1; for (int i = 0; i != directChildrenCount; i++) { int size = sub.GetChildrenCountAt(index) + 1; handle[handleNext++] = cacheNext; cacheNext += size; index += size; } } else if (action == TreeAction.Drop) { } else { if (action != TreeAction.None) { sub.SetActionAt(0, action); } // copy the complete sub-tree to the cache if (handleNext == handle.Length) { Array.Resize(ref handle, handle.Length + INIT_HANDLE_SIZE); } sub.CopyTo(cache, cacheNext); handle[handleNext++] = cacheNext; cacheNext += sub.GetChildrenCountAt(0) + 1; } }