forked from jasder/antlr
[Swift] Report InputMismatchException with original context information
Port 0803c74
from the Java runtime to Swift. This was issue #1922.
Enable the corresponding tests for Swift.
This commit is contained in:
parent
11d601348e
commit
842d3d7597
|
@ -639,7 +639,7 @@ public class ParserErrorsDescriptors {
|
|||
|
||||
@Override
|
||||
public boolean ignore(String targetName) {
|
||||
return !"Java".equals(targetName);
|
||||
return !"Java".equals(targetName) && !"Swift".equals(targetName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -291,7 +291,7 @@ public class SemPredEvalParserDescriptors {
|
|||
|
||||
@Override
|
||||
public boolean ignore(String targetName) {
|
||||
return !"Java".equals(targetName);
|
||||
return !"Java".equals(targetName) && !"Swift".equals(targetName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,22 @@ open class DefaultErrorStrategy: ANTLRErrorStrategy {
|
|||
|
||||
open var lastErrorStates: IntervalSet?
|
||||
|
||||
/**
|
||||
* This field is used to propagate information about the lookahead following
|
||||
* the previous match. Since prediction prefers completing the current rule
|
||||
* to error recovery efforts, error reporting may occur later than the
|
||||
* original point where it was discoverable. The original context is used to
|
||||
* compute the true expected sets as though the reporting occurred as early
|
||||
* as possible.
|
||||
*/
|
||||
open var nextTokensContext: ParserRuleContext?
|
||||
|
||||
/**
|
||||
* @see #nextTokensContext
|
||||
*/
|
||||
open var nextTokensState = ATNState.INVALID_STATE_NUMBER
|
||||
|
||||
|
||||
public init() {
|
||||
}
|
||||
|
||||
|
@ -207,7 +223,20 @@ open class DefaultErrorStrategy: ANTLRErrorStrategy {
|
|||
|
||||
// try cheaper subset first; might get lucky. seems to shave a wee bit off
|
||||
let nextToks = recognizer.getATN().nextTokens(s)
|
||||
if nextToks.contains(CommonToken.EPSILON) || nextToks.contains(la) {
|
||||
if nextToks.contains(la) {
|
||||
// We are sure the token matches
|
||||
nextTokensContext = nil
|
||||
nextTokensState = ATNState.INVALID_STATE_NUMBER
|
||||
return
|
||||
}
|
||||
|
||||
if nextToks.contains(CommonToken.EPSILON) {
|
||||
if nextTokensContext == nil {
|
||||
// It's possible the next token won't match; information tracked
|
||||
// by sync is restricted for performance.
|
||||
nextTokensContext = recognizer.getContext()
|
||||
nextTokensState = recognizer.getState()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -274,8 +303,9 @@ open class DefaultErrorStrategy: ANTLRErrorStrategy {
|
|||
/// - parameter e: the recognition exception
|
||||
///
|
||||
open func reportInputMismatch(_ recognizer: Parser, _ e: InputMismatchException) {
|
||||
let msg = "mismatched input " + getTokenErrorDisplay(e.getOffendingToken()) +
|
||||
" expecting " + e.getExpectedTokens()!.toString(recognizer.getVocabulary())
|
||||
let tok = getTokenErrorDisplay(e.getOffendingToken())
|
||||
let expected = e.getExpectedTokens()?.toString(recognizer.getVocabulary()) ?? "<missing>"
|
||||
let msg = "mismatched input \(tok) expecting \(expected)"
|
||||
recognizer.notifyErrorListeners(e.getOffendingToken(), msg, e)
|
||||
}
|
||||
|
||||
|
@ -423,7 +453,8 @@ open class DefaultErrorStrategy: ANTLRErrorStrategy {
|
|||
return try getMissingSymbol(recognizer)
|
||||
}
|
||||
// even that didn't work; must throw the exception
|
||||
throw ANTLRException.recognition(e: InputMismatchException(recognizer))
|
||||
let exn = InputMismatchException(recognizer, state: nextTokensState, ctx: nextTokensContext)
|
||||
throw ANTLRException.recognition(e: exn)
|
||||
}
|
||||
|
||||
///
|
||||
|
|
|
@ -11,10 +11,16 @@
|
|||
///
|
||||
|
||||
public class InputMismatchException: RecognitionException {
|
||||
public init(_ recognizer: Parser) {
|
||||
super.init(recognizer, recognizer.getInputStream()!, recognizer._ctx)
|
||||
public init(_ recognizer: Parser, state: Int = ATNState.INVALID_STATE_NUMBER, ctx: ParserRuleContext? = nil) {
|
||||
let bestCtx = ctx ?? recognizer._ctx
|
||||
|
||||
super.init(recognizer, recognizer.getInputStream()!, bestCtx)
|
||||
|
||||
if let token = try? recognizer.getCurrentToken() {
|
||||
setOffendingToken(token)
|
||||
}
|
||||
if (state != ATNState.INVALID_STATE_NUMBER) {
|
||||
setOffendingState(state)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue