/// <summary> /// Initializes this node /// </summary> /// <param name="identifier">The identifier of this node</param> /// <param name="original">The original symbol of this node</param> /// <param name="label">The label on the first version of this node</param> /// <param name="childrenBuffer">A buffer for the children</param> /// <param name="childrenCount">The number of children</param> public SPPFNodeNormal(int identifier, TableElemRef original, TableElemRef label, SPPFNodeRef[] childrenBuffer, int childrenCount) : base(identifier) { this.original = original; this.versions = new SPPFNodeVersion[VERSION_COUNT]; this.versions[0] = new SPPFNodeVersion(label, childrenBuffer, childrenCount); this.versionsCount = 1; }
/// <summary> /// Initializes this node /// </summary> /// <param name="identifier">The identifier of this node</param> /// <param name="label">The label of this node</param> public SPPFNodeNormal(int identifier, TableElemRef label) : base(identifier) { this.original = label; this.versions = new SPPFNodeVersion[VERSION_COUNT]; this.versions[0] = new SPPFNodeVersion(label); this.versionsCount = 1; }
/// <summary> /// Executes the reduction as a normal reduction /// </summary> /// <param name="varIndex">The reduced variable index</param> /// <param name="headAction">The tree action applied in the rule's head</param> /// <returns>The identifier of the produced SPPF node</returns> private int ReduceNormal(int varIndex, TreeAction headAction) { TableElemRef promotedSymbol = new TableElemRef(); SPPFNodeRef promotedReference = new SPPFNodeRef(SPPF.EPSILON, 0); int insertion = 0; for (int i = 0; i != handleNext; i++) { switch (handleActions[i]) { case TreeAction.Promote: if (promotedReference.NodeId != SPPF.EPSILON) { // not the first promotion // create a new version for the promoted node SPPFNodeNormal oldPromotedNode = sppf.GetNode(promotedReference.NodeId) as SPPFNodeNormal; SPPFNodeRef oldPromotedRef = oldPromotedNode.NewVersion(promotedSymbol, cacheChildren, insertion); // register the previously promoted reference into the cache cacheChildren[0] = oldPromotedRef; insertion = 1; } // save the new promoted node promotedReference = cacheChildren[handleIndices[i]]; SPPFNodeNormal promotedNode = sppf.GetNode(promotedReference.NodeId) as SPPFNodeNormal; SPPFNodeVersion promotedVersion = promotedNode.GetVersion(promotedReference.Version); promotedSymbol = promotedVersion.Label; // repack the children on the left if any Array.Copy(cacheChildren, handleIndices[i] + 1, cacheChildren, insertion, promotedVersion.ChildrenCount); insertion += promotedVersion.ChildrenCount; break; default: // Repack the sub-root on the left if (insertion != handleIndices[i]) { cacheChildren[insertion] = cacheChildren[handleIndices[i]]; } insertion++; break; } } TableElemRef originalLabel = new TableElemRef(TableType.Variable, varIndex); TableElemRef currentLabel = originalLabel; if (promotedReference.NodeId != SPPF.EPSILON) { // a promotion occurred currentLabel = promotedSymbol; } else if (headAction == TreeAction.ReplaceByEpsilon) { // this variable must be replaced in the final AST currentLabel = new TableElemRef(TableType.None, 0); } return(sppf.NewNode(originalLabel, currentLabel, cacheChildren, insertion)); }
/// <summary> /// Gets the symbol at the i-th index /// </summary> /// <param name="index">Index of the symbol</param> /// <returns>The symbol at the given index</returns> public SemanticElement this[int index] { get { SPPFNodeRef reference = cacheChildren[handleIndices[index]]; SPPFNode sppfNode = sppf.GetNode(reference.NodeId); TableElemRef label = (sppfNode as SPPFNodeNormal).GetVersion(reference.Version).Label; return(result.GetSemanticElementForLabel(label)); } }
/// <summary> /// Adds a new version to this node /// </summary> /// <param name="label">The label for this version of the node</param> /// <param name="children">A buffer of children for this version of the node</param> /// <param name="childrenCount">The number of children</param> /// <returns>The reference to this new version</returns> public SPPFNodeRef NewVersion(TableElemRef label, SPPFNodeRef[] children, int childrenCount) { if (versionsCount == versions.Length) { Array.Resize(ref versions, versions.Length + VERSION_COUNT); } versions[versionsCount] = new SPPFNodeVersion(label, children, childrenCount); SPPFNodeRef result = new SPPFNodeRef(identifier, versionsCount); versionsCount++; return(result); }
/// <summary> /// Initializes this node version /// </summary> /// <param name="label">The label for this version of the node</param> /// <param name="children">A buffer of children for this version of the node</param> /// <param name="childrenCount">The number of children</param> public SPPFNodeVersion(TableElemRef label, SPPFNodeRef[] children, int childrenCount) { this.label = label; if (children == null || childrenCount == 0) { this.children = null; } else { this.children = new SPPFNodeRef[childrenCount]; Array.Copy(children, this.children, childrenCount); } }
/// <summary> /// Initializes this node /// </summary> /// <param name="identifier">The identifier of this node</param> /// <param name="label">The label of this node</param> /// <param name="childrenBuffer">A buffer for the children</param> /// <param name="actionsBuffer">A buffer for the actions on the children</param> /// <param name="childrenCount">The number of children</param> public SPPFNodeReplaceable(int identifier, TableElemRef label, SPPFNodeRef[] childrenBuffer, TreeAction[] actionsBuffer, int childrenCount) : base(identifier) { this.label = label; if (childrenCount > 0) { this.children = new SPPFNodeRef[childrenCount]; this.actions = new TreeAction[childrenCount]; Array.Copy(childrenBuffer, children, childrenCount); Array.Copy(actionsBuffer, actions, childrenCount); } else { this.children = null; this.actions = null; } }
/// <summary> /// Executes the reduction as the reduction of a replaceable variable /// </summary> /// <param name="varIndex">The reduced variable index</param> /// <returns>The identifier of the produced SPPF node</returns> private int ReduceReplaceable(int varIndex) { int insertion = 0; for (int i = 0; i != handleNext; i++) { if (insertion != handleIndices[i]) { cacheChildren[insertion] = cacheChildren[handleIndices[i]]; } insertion++; } TableElemRef originalLabel = new TableElemRef(TableType.Variable, varIndex); return(sppf.NewReplaceableNode(originalLabel, cacheChildren, handleActions, handleNext)); }
/// <summary> /// Gets the GSS label already in history for the given GSS generation and symbol /// </summary> /// <param name="generation">The index of a GSS generation</param> /// <param name="symbol">A symbol to look for</param> /// <returns>The existing GSS label, or the epsilon label</returns> public int GetLabelFor(int generation, TableElemRef symbol) { HistoryPart hp = GetHistoryPart(generation); if (hp == null) { return(SPPF.EPSILON); } for (int i = 0; i != hp.next; i++) { if (sppf.GetNode(hp.data[i]).OriginalSymbol == symbol) { return(hp.data[i]); } } return(SPPF.EPSILON); }
/// <summary> /// Executes the shift operations for the given token /// </summary> /// <param name="oldtoken">A token</param> /// <returns>The next generation</returns> private int Shifter(Lexer.TokenKernel oldtoken) { // Create next generation int gen = gss.CreateGeneration(); // Create the GSS label to be used for the transitions TableElemRef sym = new TableElemRef(TableType.Token, oldtoken.Index); int label = sppf.GetSingleNode(sym); // Execute all shifts in the queue at this point int count = shifts.Count; for (int i = 0; i != count; i++) { ExecuteShift(gen, label, shifts.Dequeue()); } return(gen); }
/// <summary> /// Initializes this node version without children /// </summary> /// <param name="label">The label for this version of the node</param> public SPPFNodeVersion(TableElemRef label) { this.label = label; this.children = null; }
/// <summary> /// Initializes the root of this sub-tree /// </summary> /// <param name="symbol">The root's symbol</param> /// <param name="action">The tree action applied on the root</param> public void SetupRoot(TableElemRef symbol, TreeAction action) { nodes[0] = new AST.Node(symbol); actions[0] = action; }
/// <summary> /// Creates a new single node in the SPPF /// </summary> /// <param name="label">The original label for this node</param> /// <returns>The identifier of the new node</returns> public int NewNode(TableElemRef label) { return(nodes.Add(new SPPFNodeNormal(nodes.Size, label))); }
/// <summary> /// Creates a new single node in the SPPF /// </summary> /// <param name="original">The original symbol of this node</param> /// <param name="label">The label on the first version of this node</param> /// <param name="childrenBuffer">A buffer for the children</param> /// <param name="childrenCount">The number of children</param> /// <returns>The identifier of the new node</returns> public int NewNode(TableElemRef original, TableElemRef label, SPPFNodeRef[] childrenBuffer, int childrenCount) { return(nodes.Add(new SPPFNodeNormal(nodes.Size, original, label, childrenBuffer, childrenCount))); }
/// <summary> /// Creates a single node in the result SPPF an returns it /// </summary> /// <param name="symbol">The symbol as the node's label</param> /// <returns>The created node's index in the SPPF</returns> public int GetSingleNode(TableElemRef symbol) { return(sppf.NewNode(symbol)); }
/// <summary> /// Creates a new replaceable node in the SPPF /// </summary> /// <param name="label">The label of this node</param> /// <param name="childrenBuffer">A buffer for the children</param> /// <param name="actionsBuffer">A buffer for the actions on the children</param> /// <param name="childrenCount">The number of children</param> /// <returns>The identifier of the new node</returns> public int NewReplaceableNode(TableElemRef label, SPPFNodeRef[] childrenBuffer, TreeAction[] actionsBuffer, int childrenCount) { return(nodes.Add(new SPPFNodeReplaceable(nodes.Size, label, childrenBuffer, actionsBuffer, childrenCount))); }
/// <summary> /// Sets the content of the i-th item /// </summary> /// <param name="index">The index of the item to set</param> /// <param name="symbol">The symbol</param> /// <param name="action">The tree action</param> public void SetAt(int index, TableElemRef symbol, TreeAction action) { nodes[index] = new AST.Node(symbol); actions[index] = action; }