/// <summary> /// Prepares an <see cref="TerminalReader"/> to read from the specified <see cref="String"/>. /// </summary> /// <param name="text">A <see cref="String"/> containing the input text to be processed by the <see cref="TerminalReader"/>.</param> public void Open(string text) { _text = text; _match = null; _queuedTerminal = null; _stopTerminalRead = false; }
/// <summary> /// Returns the specified <see cref="Terminal"/> to the input stream. /// </summary> /// <param name="terminal">A <see cref="Terminal"/> to be returned to the input stream.</param> public void PushTerminal(Terminal terminal) { if (_queuedTerminal != null) { throw new InvalidOperationException("Queued terminal already exists."); } _queuedTerminal = terminal; }
/// <summary> /// Returns the next <see cref="Terminal"/> in the input text without advancing the current position of the <see cref="TerminalReader"/>. /// </summary> /// <returns>The next <see cref="Terminal"/> in the input text. If no <see cref="TerminalType"/> recognizes the input text, <value>null</value> is returned.</returns> public Terminal PeekTerminal() { if (m_queuedTerminal == null) { m_queuedTerminal = GetNextTerminal(); } return m_queuedTerminal; }
/// <summary> /// Reads the next <see cref="Terminal"/>. /// </summary> /// <returns>The next <see cref="Terminal"/> in the input text. If no <see cref="TerminalType"/> recognizes the input text, <value>null</value> is returned.</returns> public Terminal ReadTerminal() { Terminal result; if (_queuedTerminal != null) { result = _queuedTerminal; _queuedTerminal = null; } else { result = GetNextTerminal(); } LinguaTrace.TraceEvent(TraceEventType.Information, LinguaTraceId.ID_PARSE_READTOKEN, "{0}", result); return result; }
/// <summary> /// Returns the next <see cref="Terminal"/> in the input text without advancing the current position of the <see cref="TerminalReader"/>. /// </summary> /// <returns>The next <see cref="Terminal"/> in the input text. If no <see cref="TerminalType"/> recognizes the input text, <value>null</value> is returned.</returns> public Terminal PeekTerminal() { return _queuedTerminal ?? (_queuedTerminal = GetNextTerminal()); }
/// <summary> /// Performs syntax analysis against a sequence of terminals according to the <see cref="Grammar"/> used to create the <see cref="Parser"/>. /// </summary> /// <param name="terminalReader">Retrieves a sequence of <see cref="Terminal"/> objects.</param> /// <returns>If syntax analysis succeeds, returns the <see cref="Nonterminal"/> associated with <see cref="Grammar.StartNonterminal"/>. Otherwise, <value>null</value> is returned.</returns> public Nonterminal Parse(ITerminalReader terminalReader) { ParserStack stack = new ParserStack(); stack.Push(null, InitialState); Terminal terminal = terminalReader.ReadTerminal(); while (terminal != null) { if (terminal.ElementType.Ignore) { terminal = terminalReader.ReadTerminal(); } else { ParserAction action = stack.Peek().State.GetAction(terminal.ElementType); LinguaTrace.TraceEvent(TraceEventType.Information, LinguaTraceId.ID_PARSE_ACTION, "{0}", action); if (action == null) { return(null); } switch (action.ActionType) { case ParserActionTypes.Accept: { ParserActionAccept reduce = (ParserActionAccept)action; RuleType rule = reduce.Rule; Nonterminal lhs = Reduce(stack, rule); return(lhs); } case ParserActionTypes.Shift: { ParserActionShift shift = (ParserActionShift)action; stack.Push(terminal, shift.State); terminal = terminalReader.ReadTerminal(); } break; case ParserActionTypes.Reduce: { ParserActionReduce reduce = (ParserActionReduce)action; RuleType rule = reduce.Rule; Nonterminal lhs = Reduce(stack, rule); // Push the LHS nonterminal on the stack. // stack.Push(lhs, stack.Peek().State.GetGoto(lhs.ElementType)); } break; default: throw new InvalidOperationException(string.Format("Unrecognized action type {0}.", action.ActionType)); } } } ; return(null); }