/// <summary> /// Executes the given LR reduction /// </summary> /// <param name="production">A LR reduction</param> private void Reduce(LRProduction production) { Symbol variable = symVariables[production.Head]; builder.ReductionPrepare(production.Head, production.ReductionLength, production.HeadAction); for (int i = 0; i != production.BytecodeLength; i++) { LROpCode op = production[i]; switch (op.Base) { case LROpCodeBase.SemanticAction: { SemanticAction action = symActions[production[i + 1].DataValue]; i++; action.Invoke(variable, builder); break; } case LROpCodeBase.AddVirtual: { int index = production[i + 1].DataValue; builder.ReductionAddVirtual(index, op.TreeAction); i++; break; } default: builder.ReductionPop(op.TreeAction); break; } } builder.Reduce(); }
/// <summary> /// Gets the dependencies on nullable variables /// </summary> /// <param name="production">The production of a nullable variable</param> /// <returns>The list of the nullable variables' indices that this production depends on</returns> private static List <int> GetNullableDependencies(LRProduction production) { List <int> result = new List <int>(); for (int i = 0; i != production.BytecodeLength; i++) { LROpCode op = production[i]; switch (op.Base) { case LROpCodeBase.SemanticAction: { i++; break; } case LROpCodeBase.AddVirtual: { i++; break; } case LROpCodeBase.AddNullVariable: { result.Add(production[i + 1].DataValue); i++; break; } default: break; } } return(result); }
/// <summary> /// Loads a new instance of the LRProduction class from a binary representation /// </summary> /// <param name="reader">The binary reader to read from</param> public LRProduction(BinaryReader reader) { head = reader.ReadUInt16(); headAction = (TreeAction)reader.ReadByte(); reducLength = reader.ReadByte(); bytecode = new LROpCode[reader.ReadByte()]; for (int i = 0; i != bytecode.Length; i++) { bytecode[i] = new LROpCode(reader); } }
/// <summary> /// Builds the SPPF /// </summary> /// <param name="generation">The current GSS generation</param> /// <param name="production">The LR production</param> /// <param name="first">The first label of the path</param> /// <param name="path">The reduction path</param> /// <returns>The identifier of the corresponding SPPF node</returns> private int BuildSPPF(int generation, LRProduction production, int first, GSSPath path) { Symbol variable = symVariables[production.Head]; sppf.ReductionPrepare(first, path, production.ReductionLength); for (int i = 0; i != production.BytecodeLength; i++) { LROpCode op = production[i]; switch (op.Base) { case LROpCodeBase.SemanticAction: { SemanticAction action = symActions[production[i + 1].DataValue]; i++; action.Invoke(variable, sppf); break; } case LROpCodeBase.AddVirtual: { int index = production[i + 1].DataValue; sppf.ReductionAddVirtual(index, op.TreeAction); i++; break; } case LROpCodeBase.AddNullVariable: { int index = production[i + 1].DataValue; sppf.ReductionAddNullable(nullables[index], op.TreeAction); i++; break; } default: sppf.ReductionPop(op.TreeAction); break; } } return(sppf.Reduce(generation, production.Head, production.HeadAction)); }