static TableFragment ExtractTransitionTable(ConfigTable table, CharSet[] charSets, int[] charClassMap, Dictionary <Graph.State, int> stateMap, Statistics statistics) { var fragments = new List <TableFragment>(); foreach (var fromState in table.Graph.States) { int[] transitionsList = null; for (var i = 0; i < charSets.Length; i++) { var toState = NextState(fromState, charSets[charClassMap[i]]); if (toState != null) { if (transitionsList == null) { transitionsList = new int[charSets.Length]; } transitionsList[i] = stateMap[toState] + 1; } } if (transitionsList != null) { fragments.Add(new TableFragment(transitionsList, stateMap[fromState])); } else { statistics.StatesTerminal++; } } return(TableFragment.Combine(fragments)); }
public void Skip_NoExcess() { var fragment1 = new TableFragment(new int[] { 1, 1, 2, 2 }, 0); var fragment2 = new TableFragment(new int[] { 2 }, 1, 2); var combined = TableFragment.Combine(new TableFragment[] { fragment1, fragment2, }); Assert.That(combined.Skip, Is.EqualTo(0)); Assert.That(combined, Is.EquivalentTo(new int[] { 1, 1, 2, 2 })); Assert.That(combined.GetOffset(0), Is.EqualTo(0)); Assert.That(combined.GetOffset(1), Is.EqualTo(1)); }
public void Skip_WithExcess() { var fragment1 = new TableFragment(new int[] { 1, 1, 2, 2 }, 0); var fragment2 = new TableFragment(new int[] { 2, 2, 3 }, 1, 0); var fragment3 = new TableFragment(new int[] { 3 }, 2, 5); var combined = TableFragment.Combine(new TableFragment[] { fragment1, fragment2, fragment3, }); Assert.That(combined.Skip, Is.EqualTo(1)); Assert.That(combined, Is.EquivalentTo(new int[] { 1, 1, 2, 2, 3 })); Assert.That(combined.GetOffset(0), Is.EqualTo(0)); Assert.That(combined.GetOffset(1), Is.EqualTo(2)); Assert.That(combined.GetOffset(2), Is.EqualTo(-1)); }
public void Combine() { var fragment1 = new TableFragment(new int[] { 1, 2, 3, -1 }, 0); var fragment2 = new TableFragment(new int[] { 1, 2, 3, -1 }, 1); var fragment3 = new TableFragment(new int[] { -1, -1, 2, -1 }, 2); var fragment4 = new TableFragment(new int[] { -1, 1, -1, -1 }, 3); var combined = TableFragment.Combine(new TableFragment[] { fragment1, fragment2, fragment3, fragment4, }); Assert.That(combined.Skip, Is.EqualTo(0)); Assert.That(combined, Is.EquivalentTo(new int[] { 1, 2, 3, -1, 1, -1, -1, 2, -1 })); Assert.That(combined.GetOffset(0), Is.EqualTo(0)); Assert.That(combined.GetOffset(1), Is.EqualTo(0)); Assert.That(combined.GetOffset(2), Is.EqualTo(5)); Assert.That(combined.GetOffset(3), Is.EqualTo(3)); Assert.That(combined.GetOffset(4), Is.EqualTo(null)); }
static CompressedBlob ExtractTransitionTableBlob(Config config, Statistics statistics, TableData data) { var graph = config.Graph.Graph; var actionsList = new int[data.StateMap.Count]; var lastGotoStateIndex = data.StateMap.Count; var fragments = new List <TableFragment>(); foreach (var state in graph.States) { var index = data.StateMap[state]; var transitionRow = ExtractTransitionRow(data, state); var gotoRow = ExtractGotoRow(data, state); if (transitionRow.Fragment == null) { actionsList[index] = transitionRow.ShortCircuitReduction; statistics.StatesShortCircuited++; if (gotoRow != null) { statistics.StatesWithGotos++; } } else { fragments.Add(transitionRow.Fragment); if (transitionRow.HasReduction && transitionRow.HasShift) { statistics.StatesWithSRConflicts++; } if (gotoRow != null) { statistics.StatesWithGotos++; } else if (!transitionRow.HasReduction || !transitionRow.HasShift) { statistics.StatesOther++; } } if (gotoRow != null) { fragments.Add(gotoRow); statistics.NonTerminalColumns = Math.Max(statistics.NonTerminalColumns, gotoRow.Count); lastGotoStateIndex = data.StateMap[state] + 1; } } var combined = TableFragment.Combine(fragments); var offsetSectionLen = graph.States.Count + lastGotoStateIndex; Array.Resize(ref actionsList, offsetSectionLen + combined.Count); for (var i = 0; i < graph.States.Count << 1; i++) { var offset = combined.GetOffset(i); if (offset.HasValue) { actionsList[i] = offset.Value + offsetSectionLen; } } combined.CopyTo(actionsList, offsetSectionLen); var actionsBlob = CompressedBlob.Compress(config.Manager.TableCompression, ElementSizeStrategy.Get(config.Manager.ElementSize), actionsList); statistics.ActionsRunTime = actionsList.Length; statistics.ActionsAssemblyBytes = actionsBlob.Bytes; statistics.GotoOffsetsLen = lastGotoStateIndex; return(actionsBlob); }
void CheckIntegrity(int[][] table, int expectedLen) { var fragments = new List <TableFragment>(); for (var s = 0; s < table.Length; s++) { var row = table[s]; if (row == null) { continue; } fragments.Add(new TableFragment(row, s)); } var compound = TableFragment.Combine(fragments); var builder = new StringBuilder(); for (var s = 0; s < table.Length; s++) { var offset = compound.GetOffset(s); var row = table[s]; if (row == null) { if (offset >= 0) { builder.Append("row["); builder.Append(s); builder.Append("] should be null but was "); builder.Append(offset); builder.AppendLine(); } } else if (!offset.HasValue) { builder.Append("row["); builder.Append(s); builder.Append("] should be non-null but was null"); builder.AppendLine(); } else { for (var c = 0; c < row.Length; c++) { var expected = row[c]; var actual = compound[offset.Value + c]; if (expected != actual) { builder.Append("row["); builder.Append(s); builder.Append("]["); builder.Append(c); builder.Append("] should be "); builder.Append(expected); builder.Append(" but was "); builder.Append(actual); builder.AppendLine(); } } } } Assert.That(builder.ToString(), Is.EqualTo(string.Empty)); Assert.That(compound.Count, Is.EqualTo(expectedLen)); }