internal int Add(Token item) { return this.m_Array.Add(item); }
private ParseResult ParseLALR(ref Token nextToken) { // This function analyzes a token and either: // 1. Makes a SINGLE reduction and pushes a complete Reduction object on the m_Stack // 2. Accepts the token and shifts // 3. Errors and places the expected symbol indexes in the Tokens list // The Token is assumed to be valid and WILL be checked // If an action is performed that requires controlt to be returned to the user, the function returns true. // The Message parameter is then set to the type of action. var result = default(ParseResult); var parseAction = this.m_LRStates[this.m_CurrentLALR][nextToken.Parent]; // Work - shift or reduce if (parseAction != null) { this.m_HaveReduction = false; // Will be set true if a reduction is made // 'Debug.WriteLine("Action: " & ParseAction.Text) switch (parseAction.Type) { case LRActionType.Accept: this.m_HaveReduction = true; result = ParseResult.Accept; break; case LRActionType.Shift: this.m_CurrentLALR = parseAction.Value; nextToken.State = (short)this.m_CurrentLALR; this.m_Stack.Push(ref nextToken); result = ParseResult.Shift; break; case LRActionType.Reduce: // Produce a reduction - remove as many tokens as members in the rule & push a nonterminal token var prod = this.m_ProductionTable[parseAction.Value]; // ======== Create Reduction Token head; short n; if (this.m_TrimReductions && prod.ContainsOneNonTerminal()) { // The current rule only consists of a single nonterminal and can be trimmed from the // parse tree. Usually we create a new Reduction, assign it to the Data property // of Head and push it on the m_Stack. However, in this case, the Data property of the // Head will be assigned the Data property of the reduced token (i.e. the only one // on the m_Stack). // In this case, to save code, the value popped of the m_Stack is changed into the head. head = this.m_Stack.Pop(); head.Parent = prod.Head(); result = ParseResult.ReduceEliminated; // Build a Reduction } else { this.m_HaveReduction = true; var newReduction = new Reduction(prod.Handle().Count()); var with2 = newReduction; with2.Parent = prod; for (n = (short)(prod.Handle().Count() - 1); n >= 0; n += -1) { with2[n] = this.m_Stack.Pop(); } head = new Token(prod.Head(), newReduction); result = ParseResult.ReduceNormal; } // ========== Goto var index = this.m_Stack.Top().State; // ========= If n is -1 here, then we have an Internal Table Error!!!! n = this.m_LRStates[index].IndexOf(prod.Head()); if (n != -1) { this.m_CurrentLALR = this.m_LRStates[index][n].Value; head.State = (short)this.m_CurrentLALR; this.m_Stack.Push(ref head); } else { result = ParseResult.InternalError; } break; } } else { // === Syntax Error! Fill Expected Tokens this.m_ExpectedSymbols.Clear(); // .Count - 1 foreach (LRAction action in this.m_LRStates[this.m_CurrentLALR]) { switch (action.Symbol.Type) { case SymbolType.Content: case SymbolType.End: case SymbolType.GroupStart: case SymbolType.GroupEnd: this.m_ExpectedSymbols.Add(action.Symbol); break; } } result = ParseResult.SyntaxError; } return result; // Very important }
private Token LookaheadDFA() { // This function implements the DFA for th parser's lexer. // It generates a token which is used by the LALR state // machine. var target = 0; var result = new Token(); // =================================================== // Match DFA token // =================================================== var done = false; int currentDFA = this.m_DFA.InitialState; var currentPosition = 1; // Next byte in the input Stream var lastAcceptState = -1; // We have not yet accepted a character string var lastAcceptPosition = -1; var ch = this.Lookahead(1); // NO MORE DATA // ReSharper disable once PossibleNullReferenceException if (!(string.IsNullOrEmpty(ch) | ch[0] == 65535)) { while (!done) { // This code searches all the branches of the current DFA state // for the next character in the input Stream. If found the // target state is returned. ch = this.Lookahead(currentPosition); // End reached, do not match bool found; if (string.IsNullOrEmpty(ch)) { found = false; } else { var n = 0; found = false; while (n < this.m_DFA[currentDFA].Edges.Count & !found) { var edge = this.m_DFA[currentDFA].Edges[n]; // ==== Look for character in the Character Set Table if (edge.Characters.Contains(ch[0])) { found = true; target = edge.Target; // .TableIndex } n += 1; } } // This block-if statement checks whether an edge was found from the current state. If so, the state and current // position advance. Otherwise it is time to exit the main loop and report the token found (if there was one). // If the LastAcceptState is -1, then we never found a match and the Error Token is created. Otherwise, a new // token is created using the Symbol in the Accept State and all the characters that comprise it. if (found) { // This code checks whether the target state accepts a token. // If so, it sets the appropiate variables so when the // algorithm in done, it can return the proper token and // number of characters. // NOT is very important! if (this.m_DFA[target].Accept != null) { lastAcceptState = target; lastAcceptPosition = currentPosition; } currentDFA = target; currentPosition += 1; // No edge found } else { done = true; // Lexer cannot recognize symbol if (lastAcceptState == -1) { result.Parent = this.m_SymbolTable.GetFirstOfType(SymbolType.Error); result.Data = this.LookaheadBuffer(1); // Create Token, read characters } else { result.Parent = this.m_DFA[lastAcceptState].Accept; result.Data = this.LookaheadBuffer(lastAcceptPosition); // Data contains the total number of accept characters } } // DoEvents } } else { // End of file reached, create End Token result.Data = string.Empty; result.Parent = this.m_SymbolTable.GetFirstOfType(SymbolType.End); } // =================================================== // Set the new token's position information // =================================================== // Notice, this is a copy, not a linking of an instance. We don't want the user // to be able to alter the main value indirectly. result.Position().Copy(this.m_SysPosition); return result; }
public void PushInput(ref Token theToken) { this.m_InputTokens.Push(theToken); }
public bool Open(TextReader reader) { var start = new Token(); this.Restart(); this.m_Source = reader; // === Create stack top item. Only needs state start.State = this.m_LRStates.InitialState; this.m_Stack.Push(ref start); return true; }
public void EnqueueInput(ref Token theToken) { this.m_InputTokens.Enqueue(ref theToken); }