Merge pull request #2073 from ewanmellor/swift-RecognitionException-remove-generic

Tidy up the exception handling around RecognitionException.
This commit is contained in:
Terence Parr 2017-10-27 08:26:47 -07:00 committed by GitHub
commit 20baa32b5a
12 changed files with 59 additions and 75 deletions

View File

@ -63,7 +63,7 @@ public protocol ANTLRErrorStrategy {
/// - throws: _RecognitionException_ if the error strategy could not recover from /// - throws: _RecognitionException_ if the error strategy could not recover from
/// the recognition exception /// the recognition exception
/// ///
func recover(_ recognizer: Parser, _ e: AnyObject) throws func recover(_ recognizer: Parser, _ e: RecognitionException) throws
/// ///
/// This method provides the error handler with an opportunity to handle /// This method provides the error handler with an opportunity to handle
@ -115,5 +115,5 @@ public protocol ANTLRErrorStrategy {
/// - parameter recognizer: the parser instance /// - parameter recognizer: the parser instance
/// - parameter e: the recognition exception to report /// - parameter e: the recognition exception to report
/// ///
func reportError(_ recognizer: Parser, _ e: AnyObject) func reportError(_ recognizer: Parser, _ e: RecognitionException)
} }

View File

@ -40,7 +40,7 @@ public class BailErrorStrategy: DefaultErrorStrategy {
/// rule function catches. Use _Exception#getCause()_ to get the /// rule function catches. Use _Exception#getCause()_ to get the
/// original _org.antlr.v4.runtime.RecognitionException_. /// original _org.antlr.v4.runtime.RecognitionException_.
/// ///
override public func recover(_ recognizer: Parser, _ e: AnyObject) throws { override public func recover(_ recognizer: Parser, _ e: RecognitionException) throws {
var context = recognizer.getContext() var context = recognizer.getContext()
while let contextWrap = context { while let contextWrap = context {
contextWrap.exception = e contextWrap.exception = e
@ -56,7 +56,7 @@ public class BailErrorStrategy: DefaultErrorStrategy {
/// ///
override override
public func recoverInline(_ recognizer: Parser) throws -> Token { public func recoverInline(_ recognizer: Parser) throws -> Token {
let e = try InputMismatchException(recognizer) let e = InputMismatchException(recognizer)
var context = recognizer.getContext() var context = recognizer.getContext()
while let contextWrap = context { while let contextWrap = context {
contextWrap.exception = e contextWrap.exception = e

View File

@ -90,7 +90,7 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
/// the exception /// the exception
/// ///
public func reportError(_ recognizer: Parser, public func reportError(_ recognizer: Parser,
_ e: AnyObject) { _ e: RecognitionException) {
// if we've already reported an error and have not matched a token // if we've already reported an error and have not matched a token
// yet successfully, don't report any errors. // yet successfully, don't report any errors.
if inErrorRecoveryMode(recognizer) { if inErrorRecoveryMode(recognizer) {
@ -109,8 +109,7 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
} }
else { else {
errPrint("unknown recognition error type: " + String(describing: type(of: e))) errPrint("unknown recognition error type: " + String(describing: type(of: e)))
let re = (e as! RecognitionException<ParserATNSimulator>) recognizer.notifyErrorListeners(e.getOffendingToken(), e.message ?? "", e)
recognizer.notifyErrorListeners(re.getOffendingToken(), re.message ?? "", e)
} }
} }
@ -119,7 +118,7 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
/// until we find one in the resynchronization set--loosely the set of tokens /// until we find one in the resynchronization set--loosely the set of tokens
/// that can follow the current rule. /// that can follow the current rule.
/// ///
public func recover(_ recognizer: Parser, _ e: AnyObject) throws { public func recover(_ recognizer: Parser, _ e: RecognitionException) throws {
// print("recover in "+recognizer.getRuleInvocationStack()+ // print("recover in "+recognizer.getRuleInvocationStack()+
// " index="+getTokenStream(recognizer).index()+ // " index="+getTokenStream(recognizer).index()+
// ", lastErrorIndex="+ // ", lastErrorIndex="+
@ -219,7 +218,7 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
if try singleTokenDeletion(recognizer) != nil { if try singleTokenDeletion(recognizer) != nil {
return return
} }
throw try ANTLRException.recognition(e: InputMismatchException(recognizer)) throw ANTLRException.recognition(e: InputMismatchException(recognizer))
case ATNState.PLUS_LOOP_BACK: fallthrough case ATNState.PLUS_LOOP_BACK: fallthrough
case ATNState.STAR_LOOP_BACK: case ATNState.STAR_LOOP_BACK:
@ -418,11 +417,8 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
if try singleTokenInsertion(recognizer) { if try singleTokenInsertion(recognizer) {
return try getMissingSymbol(recognizer) return try getMissingSymbol(recognizer)
} }
throw try ANTLRException.recognition(e: InputMismatchException(recognizer))
// throw try ANTLRException.InputMismatch(e: InputMismatchException(recognizer) )
//RuntimeException("InputMismatchException")
// even that didn't work; must throw the exception // even that didn't work; must throw the exception
//throwException() /* throw InputMismatchException(recognizer); */ throw ANTLRException.recognition(e: InputMismatchException(recognizer))
} }
/// ///

View File

@ -11,23 +11,12 @@
/// Disambiguating predicate evaluation occurs when we test a predicate during /// Disambiguating predicate evaluation occurs when we test a predicate during
/// prediction. /// prediction.
/// ///
public class FailedPredicateException: RecognitionException<ParserATNSimulator> { public class FailedPredicateException: RecognitionException {
private final var ruleIndex: Int private final var ruleIndex: Int
private final var predicateIndex: Int private final var predicateIndex: Int
private final var predicate: String? private final var predicate: String?
public convenience init(_ recognizer: Parser) throws { public init(_ recognizer: Parser, _ predicate: String? = nil, _ message: String? = nil) {
try self.init(recognizer, nil)
}
public convenience init(_ recognizer: Parser, _ predicate: String?)throws {
try self.init(recognizer, predicate, nil)
}
public init(_ recognizer: Parser,
_ predicate: String?,
_ message: String?) throws
{
let s = recognizer.getInterpreter().atn.states[recognizer.getState()]! let s = recognizer.getInterpreter().atn.states[recognizer.getState()]!
let trans = s.transition(0) as! AbstractPredicateTransition let trans = s.transition(0) as! AbstractPredicateTransition
@ -42,9 +31,10 @@ public class FailedPredicateException: RecognitionException<ParserATNSimulator>
self.predicate = predicate self.predicate = predicate
super.init(FailedPredicateException.formatMessage(predicate!, message), recognizer , recognizer.getInputStream()!, recognizer._ctx) super.init(recognizer, recognizer.getInputStream()!, recognizer._ctx, FailedPredicateException.formatMessage(predicate, message))
if let token = try? recognizer.getCurrentToken() {
try self.setOffendingToken(recognizer.getCurrentToken()) setOffendingToken(token)
}
} }
public func getRuleIndex() -> Int { public func getRuleIndex() -> Int {
@ -60,11 +50,12 @@ public class FailedPredicateException: RecognitionException<ParserATNSimulator>
} }
private static func formatMessage(_ predicate: String, _ message: String?) -> String { private static func formatMessage(_ predicate: String?, _ message: String?) -> String {
if message != nil { if message != nil {
return message! return message!
} }
return "failed predicate: {predicate}?" //String.format(Locale.getDefault(), "failed predicate: {%s}?", predicate); let predstr = predicate ?? "<unknown>"
return "failed predicate: {\(predstr)}?"
} }
} }

View File

@ -10,9 +10,11 @@
/// when the current input does not match the expected token. /// when the current input does not match the expected token.
/// ///
public class InputMismatchException: RecognitionException<ParserATNSimulator> { public class InputMismatchException: RecognitionException {
public init(_ recognizer: Parser) throws { public init(_ recognizer: Parser) {
super.init(recognizer, recognizer.getInputStream()!, recognizer._ctx) super.init(recognizer, recognizer.getInputStream()!, recognizer._ctx)
self.setOffendingToken(try recognizer.getCurrentToken()) if let token = try? recognizer.getCurrentToken() {
setOffendingToken(token)
}
} }
} }

View File

@ -5,7 +5,7 @@
/// ///
public class LexerNoViableAltException: RecognitionException<LexerATNSimulator>, CustomStringConvertible { public class LexerNoViableAltException: RecognitionException, CustomStringConvertible {
/// ///
/// Matching attempted at what input index? /// Matching attempted at what input index?
/// ///

View File

@ -10,7 +10,7 @@
/// in the various paths when the error. Reported by reportNoViableAlternative() /// in the various paths when the error. Reported by reportNoViableAlternative()
/// ///
public class NoViableAltException: RecognitionException<ParserATNSimulator> { public class NoViableAltException: RecognitionException {
/// Which configurations did we try at input.index() that couldn't match input.LT(1)? /// Which configurations did we try at input.index() that couldn't match input.LT(1)?
private final var deadEndConfigs: ATNConfigSet? private final var deadEndConfigs: ATNConfigSet?
@ -22,14 +22,15 @@ public class NoViableAltException: RecognitionException<ParserATNSimulator> {
/// ///
private final var startToken: Token private final var startToken: Token
public convenience init(_ recognizer: Parser?) throws { public convenience init(_ recognizer: Parser) {
// LL(1) error // LL(1) error
let token = try! recognizer.getCurrentToken()
self.init(recognizer, self.init(recognizer,
recognizer!.getInputStream()!, recognizer.getInputStream()!,
try recognizer!.getCurrentToken(), token,
try recognizer!.getCurrentToken(), token,
nil, nil,
recognizer!._ctx) recognizer._ctx)
} }
public init(_ recognizer: Parser?, public init(_ recognizer: Parser?,
@ -42,7 +43,6 @@ public class NoViableAltException: RecognitionException<ParserATNSimulator> {
self.deadEndConfigs = deadEndConfigs self.deadEndConfigs = deadEndConfigs
self.startToken = startToken self.startToken = startToken
// as? Recognizer<AnyObject, ATNSimulator>
super.init(recognizer, input, ctx) super.init(recognizer, input, ctx)
self.setOffendingToken(offendingToken) self.setOffendingToken(offendingToken)
} }

View File

@ -237,11 +237,8 @@ public class ParserInterpreter: Parser {
case Transition.PREDICATE: case Transition.PREDICATE:
let predicateTransition = transition as! PredicateTransition let predicateTransition = transition as! PredicateTransition
if try !sempred(_ctx!, predicateTransition.ruleIndex, predicateTransition.predIndex) { if try !sempred(_ctx!, predicateTransition.ruleIndex, predicateTransition.predIndex) {
throw ANTLRException.recognition(e: FailedPredicateException(self))
throw try ANTLRException.recognition(e: FailedPredicateException(self))
} }
break break
case Transition.ACTION: case Transition.ACTION:
@ -251,9 +248,7 @@ public class ParserInterpreter: Parser {
case Transition.PRECEDENCE: case Transition.PRECEDENCE:
if !precpred(_ctx!, (transition as! PrecedencePredicateTransition).precedence) { if !precpred(_ctx!, (transition as! PrecedencePredicateTransition).precedence) {
throw ANTLRException.recognition(e: FailedPredicateException(self, "precpred(_ctx,\((transition as! PrecedencePredicateTransition).precedence))"))
throw try ANTLRException.recognition(e: FailedPredicateException(self, "precpred(_ctx,\((transition as! PrecedencePredicateTransition).precedence))"))
} }
break break

View File

@ -11,12 +11,11 @@
/// and what kind of problem occurred. /// and what kind of problem occurred.
/// ///
public class RecognitionException<T:ATNSimulator> { public class RecognitionException {
/// ///
/// The _org.antlr.v4.runtime.Recognizer_ where this exception originated. /// The _org.antlr.v4.runtime.Recognizer_ where this exception originated.
/// ///
private final var recognizer: Recognizer<T>? private final var recognizer: RecognizerProtocol?
//Recognizer<AnyObject,ATNSimulator>? ;
private final let ctx: RuleContext? private final let ctx: RuleContext?
@ -32,25 +31,15 @@ public class RecognitionException<T:ATNSimulator> {
private var offendingState = -1 private var offendingState = -1
public var message: String? public var message: String?
public init(_ recognizer: Recognizer<T>?,
_ input: IntStream,
_ ctx: ParserRuleContext?) {
self.recognizer = recognizer
self.input = input
self.ctx = ctx
if let recognizer = recognizer {
self.offendingState = recognizer.getState()
}
}
public init(_ message: String, public init(_ recognizer: RecognizerProtocol?,
_ recognizer: Recognizer<T>?,
_ input: IntStream, _ input: IntStream,
_ ctx: ParserRuleContext?) { _ ctx: ParserRuleContext? = nil,
self.message = message _ message: String? = nil) {
self.recognizer = recognizer self.recognizer = recognizer
self.input = input self.input = input
self.ctx = ctx self.ctx = ctx
self.message = message
if let recognizer = recognizer { if let recognizer = recognizer {
self.offendingState = recognizer.getState() self.offendingState = recognizer.getState()
} }
@ -87,7 +76,6 @@ public class RecognitionException<T:ATNSimulator> {
if let recognizer = recognizer { if let recognizer = recognizer {
return try? recognizer.getATN().getExpectedTokens(offendingState, ctx!) return try? recognizer.getATN().getExpectedTokens(offendingState, ctx!)
} }
return nil return nil
} }
@ -134,7 +122,7 @@ public class RecognitionException<T:ATNSimulator> {
/// - Returns: The recognizer where this exception occurred, or `null` if /// - Returns: The recognizer where this exception occurred, or `null` if
/// the recognizer is not available. /// the recognizer is not available.
/// ///
public func getRecognizer() -> Recognizer<T>? { public func getRecognizer() -> RecognizerProtocol? {
return recognizer return recognizer
} }
} }

View File

@ -5,13 +5,25 @@
import Foundation import Foundation
open class Recognizer<ATNInterpreter:ATNSimulator> {
public protocol RecognizerProtocol {
func getATN() -> ATN
func getGrammarFileName() -> String
func getParseInfo() -> ParseInfo?
func getRuleNames() -> [String]
func getSerializedATN() -> String
func getState() -> Int
func getTokenType(_ tokenName: String) -> Int
func getVocabulary() -> Vocabulary
}
open class Recognizer<ATNInterpreter: ATNSimulator>: RecognizerProtocol {
//TODO: WeakKeyDictionary NSMapTable Dictionary MapTable<Vocabulary,HashMap<String, Int>> //TODO: WeakKeyDictionary NSMapTable Dictionary MapTable<Vocabulary,HashMap<String, Int>>
private let tokenTypeMapCache = HashMap<Vocabulary, [String : Int]>() private let tokenTypeMapCache = HashMap<Vocabulary, [String : Int]>()
private let ruleIndexMapCache = HashMap<ArrayWrapper<String>, [String : Int]>() private let ruleIndexMapCache = HashMap<ArrayWrapper<String>, [String : Int]>()
private var _listeners: [ANTLRErrorListener] = [ConsoleErrorListener.INSTANCE] private var _listeners: [ANTLRErrorListener] = [ConsoleErrorListener.INSTANCE]
public var _interp: ATNInterpreter! public var _interp: ATNInterpreter!
@ -151,8 +163,8 @@ open class Recognizer<ATNInterpreter:ATNSimulator> {
/// ///
/// What is the error header, normally line/character position information? /// What is the error header, normally line/character position information?
/// ///
open func getErrorHeader(_ e: AnyObject) -> String { open func getErrorHeader(_ e: RecognitionException) -> String {
let offending = (e as! RecognitionException).getOffendingToken() let offending = e.getOffendingToken()
let line = offending.getLine() let line = offending.getLine()
let charPositionInLine = offending.getCharPositionInLine() let charPositionInLine = offending.getCharPositionInLine()
return "line \(line):\(charPositionInLine)" return "line \(line):\(charPositionInLine)"

View File

@ -16,5 +16,5 @@ import Foundation
public enum ANTLRException: Error { public enum ANTLRException: Error {
case cannotInvokeStartRule case cannotInvokeStartRule
case recognition(e:AnyObject) case recognition(e: RecognitionException)
} }

View File

@ -589,7 +589,7 @@ case <i><if(!choice.ast.greedy)>+1<endif>:
Sync(s) ::= "sync(<s.expecting.name>);" Sync(s) ::= "sync(<s.expecting.name>);"
ThrowNoViableAlt(t) ::= "throw try ANTLRException.recognition(e: NoViableAltException(self))" ThrowNoViableAlt(t) ::= "throw ANTLRException.recognition(e: NoViableAltException(self))"
TestSetInline(s) ::= << TestSetInline(s) ::= <<
<!<s.bitsets:{bits | <if(rest(rest(bits.ttypes)))><bitsetBitfieldComparison(s, bits)><else><bitsetInlineComparison(s, bits)><endif>}; separator=" || ">!> <!<s.bitsets:{bits | <if(rest(rest(bits.ttypes)))><bitsetBitfieldComparison(s, bits)><else><bitsetInlineComparison(s, bits)><endif>}; separator=" || ">!>
@ -694,7 +694,7 @@ ArgAction(a, chunks) ::= "<chunks>"
SemPred(p, chunks, failChunks) ::= << SemPred(p, chunks, failChunks) ::= <<
setState(<p.stateNumber>) setState(<p.stateNumber>)
if (!(<chunks>)) { if (!(<chunks>)) {
throw try ANTLRException.recognition(e:FailedPredicateException(self, <p.predicate><if(failChunks)>, <failChunks><elseif(p.msg)>, <p.msg><endif>)) throw ANTLRException.recognition(e:FailedPredicateException(self, <p.predicate><if(failChunks)>, <failChunks><elseif(p.msg)>, <p.msg><endif>))
} }
>> >>