private TransitionTable(int tokenCount, int stateCount, int productionCount, string[] tokenDescriptions) { TokenCount = tokenCount; StateCount = stateCount; ProductionCount = productionCount; m_gotoTable = new int[stateCount, productionCount]; m_shiftTable = new ActionListNode <int> [stateCount, tokenCount + 1]; m_reduceTable = new ActionListNode <int> [stateCount, tokenCount + 1]; m_tokenDescriptions = tokenDescriptions; }
public IEnumerator <T> GetEnumerator() { ActionListNode <T> currentNode = this; do { yield return(currentNode.Value); currentNode = currentNode.m_nextNode; } while (currentNode != null); }
internal static void AppendToLast(ref ActionListNode <T> list, T value) { if (list == null) { list = new ActionListNode <T>(value); } else { ActionListNode <T> head = list; while (head.m_nextNode != null) { head = head.m_nextNode; } head.Append(new ActionListNode <T>(value)); } }
public ActionListNode <T> Append(ActionListNode <T> next) { m_nextNode = next; return(m_nextNode); }
public static TransitionTable Create(LR0Model model, ScannerInfo scannerInfo) { CodeContract.RequiresArgumentNotNull(model, "model"); string[] tokenDescriptions = new string[scannerInfo.EndOfStreamTokenIndex + 1]; List <IProduction> nonterminals = new List <IProduction>(); foreach (var production in model.ProductionInfoManager.Productions) { if (!production.IsTerminal) { var info = model.ProductionInfoManager.GetInfo(production); info.NonTerminalIndex = nonterminals.Count; nonterminals.Add(production); } else { var terminal = (production as Terminal); string description; int index; if (terminal != null) { index = terminal.Token.Index; description = terminal.Token.Description; } else { index = scannerInfo.EndOfStreamTokenIndex; description = "$"; } tokenDescriptions[index] = description; } } //add one null reference to non-terminal list //for "accept" action in parsing nonterminals.Add(null); TransitionTable table = new TransitionTable(scannerInfo.EndOfStreamTokenIndex + 1, model.States.Count, nonterminals.Count, tokenDescriptions); table.m_nonTerminals = nonterminals.ToArray(); table.m_acceptProductionIndex = nonterminals.Count - 1; for (int i = 0; i < model.States.Count; i++) { var state = model.States[i]; foreach (var edge in state.Edges) { var edgeSymbol = model.ProductionInfoManager.Productions[edge.SymbolIndex]; var info = model.ProductionInfoManager.GetInfo(edgeSymbol); if (edgeSymbol.IsTerminal) { //shift Terminal t = edgeSymbol as Terminal; int tokenIndex = t == null ? scannerInfo.EndOfStreamTokenIndex : t.Token.Index; ActionListNode <int> .AppendToLast(ref table.m_shiftTable[i, tokenIndex], edge.TargetStateIndex); } else { //goto table.m_gotoTable[i, info.NonTerminalIndex] = edge.TargetStateIndex; } } //lexer states for shifting if (state.MaxShiftingLexer != null) { ActionListNode <int> .AppendToLast(ref table.m_shiftTable[i, table.TokenCount], state.MaxShiftingLexer.Value); } //reduces foreach (var reduce in state.Reduces) { Terminal t = reduce.ReduceTerminal as Terminal; int tokenIndex = t == null ? scannerInfo.EndOfStreamTokenIndex : t.Token.Index; var info = model.ProductionInfoManager.GetInfo(reduce.ReduceProduction); ActionListNode <int> .AppendToLast(ref table.m_reduceTable[i, tokenIndex], info.NonTerminalIndex); } //lexer states for reducing if (state.MaxReducingLexer != null) { ActionListNode <int> .AppendToLast(ref table.m_reduceTable[i, table.TokenCount], state.MaxReducingLexer.Value); } //accepts if (state.IsAcceptState) { ActionListNode <int> .AppendToLast(ref table.m_reduceTable[i, scannerInfo.EndOfStreamTokenIndex], table.m_acceptProductionIndex); } } return(table); }