public RecognitionException(string message, Exception inner, IIntStream input) : base(message, inner) { this.input = input; this.index = input.Index(); if (input is ITokenStream) { this.token = ((ITokenStream)input).LT(1); this.line = token.Line; this.charPositionInLine = token.CharPositionInLine; } if (input is ITreeNodeStream) { ExtractInformationFromTreeNodeStream(input); } else if (input is ICharStream) { this.c = input.LA(1); this.line = ((ICharStream)input).Line; this.charPositionInLine = ((ICharStream)input).CharPositionInLine; } else { this.c = input.LA(1); } }
/// <summary> /// Recover from an error found on the input stream. This is /// for NoViableAlt and mismatched symbol exceptions. If you enable /// single token insertion and deletion, this will usually not /// handle mismatched symbol exceptions but there could be a mismatched /// token that the Match() routine could not recover from. /// </summary> public virtual void Recover(IIntStream input, RecognitionException re) { if (state.lastErrorIndex == input.Index()) { // uh oh, another error at same token index; must be a case // where LT(1) is in the recovery token set so nothing is // consumed; consume a single token so at least to prevent // an infinite loop; this is a failsafe. input.Consume(); } state.lastErrorIndex = input.Index(); BitSet followSet = ComputeErrorRecoverySet(); BeginResync(); ConsumeUntil(input, followSet); EndResync(); }
/// <summary> /// Record whether or not this rule parsed the input at this position /// successfully. Use a standard hashtable for now. /// </summary> public virtual void Memoize(IIntStream input, int ruleIndex, int ruleStartIndex) { int stopTokenIndex = state.failed ? MEMO_RULE_FAILED : input.Index() - 1; if (state.ruleMemo[ruleIndex] != null) { state.ruleMemo[ruleIndex][(int)ruleStartIndex] = (int)stopTokenIndex; } }
/// <summary> /// Has this rule already parsed input at the current index in the /// input stream? Return the stop token index or MEMO_RULE_UNKNOWN. /// If we attempted but failed to parse properly before, return /// MEMO_RULE_FAILED. /// /// This method has a side-effect: if we have seen this input for /// this rule and successfully parsed before, then seek ahead to /// 1 past the stop token matched for this rule last time. /// </summary> public virtual bool AlreadyParsedRule(IIntStream input, int ruleIndex) { int stopIndex = GetRuleMemoization(ruleIndex, input.Index()); if (stopIndex == MEMO_RULE_UNKNOWN) { return(false); } if (stopIndex == MEMO_RULE_FAILED) { state.failed = true; } else { input.Seek(stopIndex + 1); // jump to one past stop token } return(true); }
public RecognitionException(string message, Exception inner, IIntStream input) : base(message, inner) { this.input = input; this.index = input.Index(); if (input is ITokenStream) { this.token = ((ITokenStream)input).LT(1); this.line = token.Line; this.charPositionInLine = token.CharPositionInLine; } //if (input is ITreeNodeStream) //{ // ExtractInformationFromTreeNodeStream(input); //} //else if (input is ICharStream) { this.c = input.LA(1); this.line = ((ICharStream)input).Line; this.charPositionInLine = ((ICharStream)input).CharPositionInLine; } else { this.c = input.LA(1); } }
/// <summary> /// From the input stream, predict what alternative will succeed using this /// DFA (representing the covering regular approximation to the underlying CFL). /// </summary> /// <param name="input">Input stream</param> /// <returns>Return an alternative number 1..n. Throw an exception upon error.</returns> public int Predict(IIntStream input) { if (debug) { Console.Error.WriteLine("Enter DFA.predict for decision " + decisionNumber); } int mark = input.Mark(); // remember where decision started in input int s = 0; // we always start at s0 try { while (true) { if (debug) { Console.Error.WriteLine("DFA " + decisionNumber + " state " + s + " LA(1)=" + (char)input.LA(1) + "(" + input.LA(1) + "), index=" + input.Index()); } int specialState = special[s]; if (specialState >= 0) { if (debug) { Console.Error.WriteLine("DFA " + decisionNumber + " state " + s + " is special state " + specialState); } s = specialStateTransitionHandler(this, specialState, input); if (debug) { Console.Error.WriteLine("DFA " + decisionNumber + " returns from special state " + specialState + " to " + s); } if (s == -1) { NoViableAlt(s, input); return(0); } input.Consume(); continue; } if (accept[s] >= 1) { if (debug) { Console.Error.WriteLine("accept; predict " + accept[s] + " from state " + s); } return(accept[s]); } // look for a normal char transition char c = (char)input.LA(1); // -1 == \uFFFF, all tokens fit in 65000 space if ((c >= min[s]) && (c <= max[s])) { int snext = transition[s][c - min[s]]; // move to next state if (snext < 0) { // was in range but not a normal transition // must check EOT, which is like the else clause. // eot[s]>=0 indicates that an EOT edge goes to another // state. if (eot[s] >= 0) // EOT Transition to accept state? { if (debug) { Console.Error.WriteLine("EOT transition"); } s = eot[s]; input.Consume(); // TODO: I had this as return accept[eot[s]] // which assumed here that the EOT edge always // went to an accept...faster to do this, but // what about predicated edges coming from EOT // target? continue; } NoViableAlt(s, input); return(0); } s = snext; input.Consume(); continue; } if (eot[s] >= 0) { // EOT Transition? if (debug) { Console.Error.WriteLine("EOT transition"); } s = eot[s]; input.Consume(); continue; } if ((c == (char)Token.EOF) && (eof[s] >= 0)) { // EOF Transition to accept state? if (debug) { Console.Error.WriteLine("accept via EOF; predict " + accept[eof[s]] + " from " + eof[s]); } return(accept[eof[s]]); } // not in range and not EOF/EOT, must be invalid symbol if (debug) { Console.Error.WriteLine("min[" + s + "]=" + min[s]); Console.Error.WriteLine("max[" + s + "]=" + max[s]); Console.Error.WriteLine("eot[" + s + "]=" + eot[s]); Console.Error.WriteLine("eof[" + s + "]=" + eof[s]); for (int p = 0; p < transition[s].Length; p++) { Console.Error.Write(transition[s][p] + " "); } Console.Error.WriteLine(); } NoViableAlt(s, input); return(0); } } finally { input.Rewind(mark); } }
/// <summary> /// Has this rule already parsed input at the current index in the /// input stream? Return the stop token index or MEMO_RULE_UNKNOWN. /// If we attempted but failed to parse properly before, return /// MEMO_RULE_FAILED. /// /// This method has a side-effect: if we have seen this input for /// this rule and successfully parsed before, then seek ahead to /// 1 past the stop token matched for this rule last time. /// </summary> public virtual bool AlreadyParsedRule(IIntStream input, int ruleIndex) { int stopIndex = GetRuleMemoization(ruleIndex, input.Index()); if (stopIndex == MEMO_RULE_UNKNOWN) { return false; } if (stopIndex == MEMO_RULE_FAILED) { state.failed = true; } else { input.Seek(stopIndex + 1); // jump to one past stop token } return true; }
/// <summary> /// From the input stream, predict what alternative will succeed using this /// DFA (representing the covering regular approximation to the underlying CFL). /// </summary> /// <param name="input">Input stream</param> /// <returns>Return an alternative number 1..n. Throw an exception upon error.</returns> public int Predict(IIntStream input) { if (debug) { Console.Error.WriteLine("Enter DFA.predict for decision " + decisionNumber); } int mark = input.Mark(); // remember where decision started in input int s = 0; // we always start at s0 try { while (true) { if (debug) Console.Error.WriteLine("DFA " + decisionNumber + " state " + s + " LA(1)=" + (char)input.LA(1) + "(" + input.LA(1) + "), index=" + input.Index()); int specialState = special[s]; if (specialState >= 0) { if (debug) Console.Error.WriteLine("DFA " + decisionNumber + " state " + s + " is special state " + specialState); s = specialStateTransitionHandler(this, specialState, input); if (debug) { Console.Error.WriteLine("DFA " + decisionNumber + " returns from special state " + specialState + " to " + s); } if (s == -1) { NoViableAlt(s, input); return 0; } input.Consume(); continue; } if (accept[s] >= 1) { if (debug) Console.Error.WriteLine("accept; predict " + accept[s] + " from state " + s); return accept[s]; } // look for a normal char transition char c = (char)input.LA(1); // -1 == \uFFFF, all tokens fit in 65000 space if ((c >= min[s]) && (c <= max[s])) { int snext = transition[s][c - min[s]]; // move to next state if (snext < 0) { // was in range but not a normal transition // must check EOT, which is like the else clause. // eot[s]>=0 indicates that an EOT edge goes to another // state. if (eot[s] >= 0) // EOT Transition to accept state? { if (debug) Console.Error.WriteLine("EOT transition"); s = eot[s]; input.Consume(); // which assumed here that the EOT edge always // went to an accept...faster to do this, but // what about predicated edges coming from EOT // target? continue; } NoViableAlt(s, input); return 0; } s = snext; input.Consume(); continue; } if (eot[s] >= 0) { // EOT Transition? if (debug) Console.Error.WriteLine("EOT transition"); s = eot[s]; input.Consume(); continue; } if ((c == (char)Token.EOF) && (eof[s] >= 0)) { // EOF Transition to accept state? if (debug) Console.Error.WriteLine("accept via EOF; predict " + accept[eof[s]] + " from " + eof[s]); return accept[eof[s]]; } // not in range and not EOF/EOT, must be invalid symbol if (debug) { Console.Error.WriteLine("min[" + s + "]=" + min[s]); Console.Error.WriteLine("max[" + s + "]=" + max[s]); Console.Error.WriteLine("eot[" + s + "]=" + eot[s]); Console.Error.WriteLine("eof[" + s + "]=" + eof[s]); for (int p = 0; p < transition[s].Length; p++) { Console.Error.Write(transition[s][p] + " "); } Console.Error.WriteLine(); } NoViableAlt(s, input); return 0; } } finally { input.Rewind(mark); } }