Tidy up the exception behavior around IntervalSet and ATNConfigSet.
These classes throw exceptions if the instance is read-only, and only in that case. This means that there is no need for us to propagate exception declarations in the cases where we have guaranteed by construction that the instance is writable. In particular, this means that IntervalSet and ATNConfigSet's constructors won't throw exceptions(!) The set options that return a new set (e.g. complement) no longer throw either. To help with this, this cset adds BitSet.firstSetBit(). This is equivalent to BitSet.nextSetBit(0), but is guaranteed not to throw an exception. As a consequence, ANTLRErrorListener / DiagnosticErrorListener no longer throw exceptions through any of their functions (syntaxError and report*), and DefaultErrorStrategy can no longer throw exceptions as part of its internal operations (though of course it can still throw exceptions if recovery fails and a real parsing error needs to be reported). Also, LL1Analyzer no longer throws exceptions at all, and so ATN.nextTokens doesn't throw either.
This commit is contained in:
parent
7e03b0857a
commit
7dd4017f41
|
@ -93,7 +93,7 @@ public protocol ANTLRErrorListener: class {
|
|||
_ stopIndex: Int,
|
||||
_ exact: Bool,
|
||||
_ ambigAlts: BitSet,
|
||||
_ configs: ATNConfigSet) throws
|
||||
_ configs: ATNConfigSet)
|
||||
|
||||
///
|
||||
/// This method is called when an SLL conflict occurs and the parser is about
|
||||
|
@ -123,7 +123,7 @@ public protocol ANTLRErrorListener: class {
|
|||
_ startIndex: Int,
|
||||
_ stopIndex: Int,
|
||||
_ conflictingAlts: BitSet?,
|
||||
_ configs: ATNConfigSet) throws
|
||||
_ configs: ATNConfigSet)
|
||||
|
||||
///
|
||||
/// This method is called by the parser when a full-context prediction has a
|
||||
|
@ -168,5 +168,5 @@ public protocol ANTLRErrorListener: class {
|
|||
_ startIndex: Int,
|
||||
_ stopIndex: Int,
|
||||
_ prediction: Int,
|
||||
_ configs: ATNConfigSet) throws
|
||||
_ configs: ATNConfigSet)
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ open class BaseErrorListener: ANTLRErrorListener {
|
|||
_ stopIndex: Int,
|
||||
_ exact: Bool,
|
||||
_ ambigAlts: BitSet,
|
||||
_ configs: ATNConfigSet) throws {
|
||||
_ configs: ATNConfigSet) {
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,7 +42,7 @@ open class BaseErrorListener: ANTLRErrorListener {
|
|||
_ startIndex: Int,
|
||||
_ stopIndex: Int,
|
||||
_ conflictingAlts: BitSet?,
|
||||
_ configs: ATNConfigSet) throws {
|
||||
_ configs: ATNConfigSet) {
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,6 +51,6 @@ open class BaseErrorListener: ANTLRErrorListener {
|
|||
_ startIndex: Int,
|
||||
_ stopIndex: Int,
|
||||
_ prediction: Int,
|
||||
_ configs: ATNConfigSet) throws {
|
||||
_ configs: ATNConfigSet) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
|
|||
}
|
||||
beginErrorCondition(recognizer)
|
||||
if let nvae = e as? NoViableAltException {
|
||||
try! reportNoViableAlternative(recognizer, nvae)
|
||||
reportNoViableAlternative(recognizer, nvae)
|
||||
}
|
||||
else if let ime = e as? InputMismatchException {
|
||||
reportInputMismatch(recognizer, ime)
|
||||
|
@ -139,10 +139,10 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
|
|||
}
|
||||
lastErrorIndex = getTokenStream(recognizer).index()
|
||||
if lastErrorStates == nil {
|
||||
lastErrorStates = try IntervalSet()
|
||||
lastErrorStates = IntervalSet()
|
||||
}
|
||||
try lastErrorStates!.add(recognizer.getState())
|
||||
let followSet = try getErrorRecoverySet(recognizer)
|
||||
let followSet = getErrorRecoverySet(recognizer)
|
||||
try consumeUntil(recognizer, followSet)
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
|
|||
let la = try tokens.LA(1)
|
||||
|
||||
// try cheaper subset first; might get lucky. seems to shave a wee bit off
|
||||
let nextToks = try recognizer.getATN().nextTokens(s)
|
||||
let nextToks = recognizer.getATN().nextTokens(s)
|
||||
if nextToks.contains(CommonToken.EPSILON) || nextToks.contains(la) {
|
||||
return
|
||||
}
|
||||
|
@ -224,9 +224,9 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
|
|||
case ATNState.PLUS_LOOP_BACK: fallthrough
|
||||
case ATNState.STAR_LOOP_BACK:
|
||||
// errPrint("at loop back: "+s.getClass().getSimpleName());
|
||||
try reportUnwantedToken(recognizer)
|
||||
reportUnwantedToken(recognizer)
|
||||
let expecting = try recognizer.getExpectedTokens()
|
||||
let whatFollowsLoopIterationOrRule = try expecting.or(try getErrorRecoverySet(recognizer)) as! IntervalSet
|
||||
let whatFollowsLoopIterationOrRule = expecting.or(getErrorRecoverySet(recognizer)) as! IntervalSet
|
||||
try consumeUntil(recognizer, whatFollowsLoopIterationOrRule)
|
||||
break
|
||||
|
||||
|
@ -246,13 +246,19 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
|
|||
/// - parameter e: the recognition exception
|
||||
///
|
||||
internal func reportNoViableAlternative(_ recognizer: Parser,
|
||||
_ e: NoViableAltException) throws {
|
||||
_ e: NoViableAltException) {
|
||||
let tokens = getTokenStream(recognizer)
|
||||
var input: String
|
||||
if e.getStartToken().getType() == CommonToken.EOF {
|
||||
input = "<EOF>"
|
||||
} else {
|
||||
input = try tokens.getText(e.getStartToken(), e.getOffendingToken())
|
||||
}
|
||||
else {
|
||||
do {
|
||||
input = try tokens.getText(e.getStartToken(), e.getOffendingToken())
|
||||
}
|
||||
catch {
|
||||
input = "<unknown>"
|
||||
}
|
||||
}
|
||||
let msg = "no viable alternative at input " + escapeWSAndQuote(input)
|
||||
recognizer.notifyErrorListeners(e.getOffendingToken(), msg, e)
|
||||
|
@ -308,16 +314,16 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
|
|||
///
|
||||
/// - parameter recognizer: the parser instance
|
||||
///
|
||||
internal func reportUnwantedToken(_ recognizer: Parser) throws {
|
||||
internal func reportUnwantedToken(_ recognizer: Parser) {
|
||||
if inErrorRecoveryMode(recognizer) {
|
||||
return
|
||||
}
|
||||
|
||||
beginErrorCondition(recognizer)
|
||||
|
||||
let t = try recognizer.getCurrentToken()
|
||||
let t = try? recognizer.getCurrentToken()
|
||||
let tokenName = getTokenErrorDisplay(t)
|
||||
let expecting = try getExpectedTokens(recognizer)
|
||||
let expecting = (try? getExpectedTokens(recognizer)) ?? IntervalSet.EMPTY_SET
|
||||
let msg = "extraneous input \(tokenName) expecting \(expecting.toString(recognizer.getVocabulary()))"
|
||||
recognizer.notifyErrorListeners(t, msg, nil)
|
||||
}
|
||||
|
@ -339,15 +345,15 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
|
|||
///
|
||||
/// - parameter recognizer: the parser instance
|
||||
///
|
||||
internal func reportMissingToken(_ recognizer: Parser) throws {
|
||||
internal func reportMissingToken(_ recognizer: Parser) {
|
||||
if inErrorRecoveryMode(recognizer) {
|
||||
return
|
||||
}
|
||||
|
||||
beginErrorCondition(recognizer)
|
||||
|
||||
let t = try recognizer.getCurrentToken()
|
||||
let expecting = try getExpectedTokens(recognizer)
|
||||
let t = try? recognizer.getCurrentToken()
|
||||
let expecting = (try? getExpectedTokens(recognizer)) ?? IntervalSet.EMPTY_SET
|
||||
let msg = "missing \(expecting.toString(recognizer.getVocabulary())) at \(getTokenErrorDisplay(t))"
|
||||
|
||||
recognizer.notifyErrorListeners(t, msg, nil)
|
||||
|
@ -450,10 +456,10 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
|
|||
let currentState = recognizer.getInterpreter().atn.states[recognizer.getState()]!
|
||||
let next = currentState.transition(0).target
|
||||
let atn = recognizer.getInterpreter().atn
|
||||
let expectingAtLL2 = try atn.nextTokens(next, recognizer._ctx)
|
||||
let expectingAtLL2 = atn.nextTokens(next, recognizer._ctx)
|
||||
// print("LT(2) set="+expectingAtLL2.toString(recognizer.getTokenNames()));
|
||||
if expectingAtLL2.contains(currentSymbolType) {
|
||||
try reportMissingToken(recognizer)
|
||||
reportMissingToken(recognizer)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
@ -482,7 +488,7 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
|
|||
let nextTokenType = try getTokenStream(recognizer).LA(2)
|
||||
let expecting = try getExpectedTokens(recognizer)
|
||||
if expecting.contains(nextTokenType) {
|
||||
try reportUnwantedToken(recognizer)
|
||||
reportUnwantedToken(recognizer)
|
||||
///
|
||||
/// errPrint("recoverFromMismatchedToken deleting "+
|
||||
/// ((TokenStream)getTokenStream(recognizer)).LT(1)+
|
||||
|
@ -685,19 +691,19 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
|
|||
/// Like Grosch I implement context-sensitive FOLLOW sets that are combined
|
||||
/// at run-time upon error to avoid overhead during parsing.
|
||||
///
|
||||
internal func getErrorRecoverySet(_ recognizer: Parser) throws -> IntervalSet {
|
||||
internal func getErrorRecoverySet(_ recognizer: Parser) -> IntervalSet {
|
||||
let atn = recognizer.getInterpreter().atn
|
||||
var ctx: RuleContext? = recognizer._ctx
|
||||
let recoverSet = try IntervalSet()
|
||||
let recoverSet = IntervalSet()
|
||||
while let ctxWrap = ctx, ctxWrap.invokingState >= 0 {
|
||||
// compute what follows who invoked us
|
||||
let invokingState = atn.states[ctxWrap.invokingState]!
|
||||
let rt = invokingState.transition(0) as! RuleTransition
|
||||
let follow = try atn.nextTokens(rt.followState)
|
||||
try recoverSet.addAll(follow)
|
||||
let follow = atn.nextTokens(rt.followState)
|
||||
try! recoverSet.addAll(follow)
|
||||
ctx = ctxWrap.parent
|
||||
}
|
||||
try recoverSet.remove(CommonToken.EPSILON)
|
||||
try! recoverSet.remove(CommonToken.EPSILON)
|
||||
// print("recover set "+recoverSet.toString(recognizer.getTokenNames()));
|
||||
return recoverSet
|
||||
}
|
||||
|
|
|
@ -59,16 +59,16 @@ public class DiagnosticErrorListener: BaseErrorListener {
|
|||
_ stopIndex: Int,
|
||||
_ exact: Bool,
|
||||
_ ambigAlts: BitSet,
|
||||
_ configs: ATNConfigSet) throws {
|
||||
_ configs: ATNConfigSet) {
|
||||
if exactOnly && !exact {
|
||||
return
|
||||
}
|
||||
|
||||
let decision = getDecisionDescription(recognizer, dfa)
|
||||
let conflictingAlts = try getConflictingAlts(ambigAlts, configs)
|
||||
let text = try recognizer.getTokenStream()!.getText(Interval.of(startIndex, stopIndex))
|
||||
let conflictingAlts = getConflictingAlts(ambigAlts, configs)
|
||||
let text = getTextInInterval(recognizer, startIndex, stopIndex)
|
||||
let message = "reportAmbiguity d=\(decision): ambigAlts=\(conflictingAlts), input='\(text)'"
|
||||
try recognizer.notifyErrorListeners(message)
|
||||
recognizer.notifyErrorListeners(message)
|
||||
}
|
||||
|
||||
override
|
||||
|
@ -77,11 +77,11 @@ public class DiagnosticErrorListener: BaseErrorListener {
|
|||
_ startIndex: Int,
|
||||
_ stopIndex: Int,
|
||||
_ conflictingAlts: BitSet?,
|
||||
_ configs: ATNConfigSet) throws {
|
||||
_ configs: ATNConfigSet) {
|
||||
let decision = getDecisionDescription(recognizer, dfa)
|
||||
let text = try recognizer.getTokenStream()!.getText(Interval.of(startIndex, stopIndex))
|
||||
let text = getTextInInterval(recognizer, startIndex, stopIndex)
|
||||
let message = "reportAttemptingFullContext d=\(decision), input='\(text)'"
|
||||
try recognizer.notifyErrorListeners(message)
|
||||
recognizer.notifyErrorListeners(message)
|
||||
}
|
||||
|
||||
override
|
||||
|
@ -90,11 +90,11 @@ public class DiagnosticErrorListener: BaseErrorListener {
|
|||
_ startIndex: Int,
|
||||
_ stopIndex: Int,
|
||||
_ prediction: Int,
|
||||
_ configs: ATNConfigSet) throws {
|
||||
_ configs: ATNConfigSet) {
|
||||
let decision = getDecisionDescription(recognizer, dfa)
|
||||
let text = try recognizer.getTokenStream()!.getText(Interval.of(startIndex, stopIndex))
|
||||
let text = getTextInInterval(recognizer, startIndex, stopIndex)
|
||||
let message = "reportContextSensitivity d=\(decision), input='\(text)'"
|
||||
try recognizer.notifyErrorListeners(message)
|
||||
recognizer.notifyErrorListeners(message)
|
||||
}
|
||||
|
||||
internal func getDecisionDescription(_ recognizer: Parser, _ dfa: DFA) -> String {
|
||||
|
@ -125,12 +125,17 @@ public class DiagnosticErrorListener: BaseErrorListener {
|
|||
/// - returns: Returns `reportedAlts` if it is not `null`, otherwise
|
||||
/// returns the set of alternatives represented in `configs`.
|
||||
///
|
||||
internal func getConflictingAlts(_ reportedAlts: BitSet?, _ configs: ATNConfigSet) throws -> BitSet {
|
||||
if reportedAlts != nil {
|
||||
return reportedAlts!
|
||||
}
|
||||
let result = try configs.getAltBitSet()
|
||||
return result
|
||||
internal func getConflictingAlts(_ reportedAlts: BitSet?, _ configs: ATNConfigSet) -> BitSet {
|
||||
return reportedAlts ?? configs.getAltBitSet()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fileprivate func getTextInInterval(_ recognizer: Parser, _ startIndex: Int, _ stopIndex: Int) -> String {
|
||||
do {
|
||||
return try recognizer.getTokenStream()?.getText(Interval.of(startIndex, stopIndex)) ?? "<unknown>"
|
||||
}
|
||||
catch {
|
||||
return "<unknown>"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public class NoViableAltException: RecognitionException<ParserATNSimulator> {
|
|||
public init(_ recognizer: Parser?,
|
||||
_ input: IntStream,
|
||||
_ startToken: Token,
|
||||
_ offendingToken: Token,
|
||||
_ offendingToken: Token?,
|
||||
_ deadEndConfigs: ATNConfigSet?,
|
||||
_ ctx: ParserRuleContext?) {
|
||||
|
||||
|
@ -44,7 +44,9 @@ public class NoViableAltException: RecognitionException<ParserATNSimulator> {
|
|||
|
||||
// as? Recognizer<AnyObject, ATNSimulator>
|
||||
super.init(recognizer, input, ctx)
|
||||
self.setOffendingToken(offendingToken)
|
||||
if let offendingToken = offendingToken {
|
||||
setOffendingToken(offendingToken)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -506,15 +506,20 @@ open class Parser: Recognizer<ParserATNSimulator> {
|
|||
return try _input.LT(1)!
|
||||
}
|
||||
|
||||
public final func notifyErrorListeners(_ msg: String) throws {
|
||||
try notifyErrorListeners(getCurrentToken(), msg, nil)
|
||||
public final func notifyErrorListeners(_ msg: String) {
|
||||
let token = try? getCurrentToken()
|
||||
notifyErrorListeners(token, msg, nil)
|
||||
}
|
||||
|
||||
public func notifyErrorListeners(_ offendingToken: Token, _ msg: String,
|
||||
_ e: AnyObject?) {
|
||||
public func notifyErrorListeners(_ offendingToken: Token?, _ msg: String, _ e: AnyObject?) {
|
||||
_syntaxErrors += 1
|
||||
let line = offendingToken.getLine()
|
||||
let charPositionInLine = offendingToken.getCharPositionInLine()
|
||||
var line = -1
|
||||
var charPositionInLine = -1
|
||||
if let offendingToken = offendingToken {
|
||||
line = offendingToken.getLine()
|
||||
charPositionInLine = offendingToken.getCharPositionInLine()
|
||||
}
|
||||
|
||||
let listener = getErrorListenerDispatch()
|
||||
listener.syntaxError(self, offendingToken, line, charPositionInLine, msg, e)
|
||||
}
|
||||
|
@ -832,7 +837,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
|
|||
// parser.getInterpreter()!.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);
|
||||
//
|
||||
// // get ambig trees
|
||||
// var alt : Int = ambiguityInfo.ambigAlts.nextSetBit(0);
|
||||
// var alt : Int = ambiguityInfo.ambigAlts.firstSetBit();
|
||||
// while alt>=0 {
|
||||
// // re-parse entire input for all ambiguous alternatives
|
||||
// // (don't have to do first as it's been parsed, but do again for simplicity
|
||||
|
@ -870,11 +875,11 @@ open class Parser: Recognizer<ParserATNSimulator> {
|
|||
/// - Returns: `true` if `symbol` can follow the current state in
|
||||
/// the ATN, otherwise `false`.
|
||||
///
|
||||
public func isExpectedToken(_ symbol: Int) throws -> Bool {
|
||||
public func isExpectedToken(_ symbol: Int) -> Bool {
|
||||
let atn = getInterpreter().atn
|
||||
var ctx = _ctx
|
||||
var ctx: ParserRuleContext? = _ctx
|
||||
let s = atn.states[getState()]!
|
||||
var following = try atn.nextTokens(s)
|
||||
var following = atn.nextTokens(s)
|
||||
if following.contains(symbol) {
|
||||
return true
|
||||
}
|
||||
|
@ -886,7 +891,7 @@ open class Parser: Recognizer<ParserATNSimulator> {
|
|||
while let ctxWrap = ctx, ctxWrap.invokingState >= 0 && following.contains(CommonToken.EPSILON) {
|
||||
let invokingState = atn.states[ctxWrap.invokingState]!
|
||||
let rt = invokingState.transition(0) as! RuleTransition
|
||||
following = try atn.nextTokens(rt.followState)
|
||||
following = atn.nextTokens(rt.followState)
|
||||
if following.contains(symbol) {
|
||||
return true
|
||||
}
|
||||
|
@ -913,10 +918,10 @@ open class Parser: Recognizer<ParserATNSimulator> {
|
|||
}
|
||||
|
||||
|
||||
public func getExpectedTokensWithinCurrentRule() throws -> IntervalSet {
|
||||
public func getExpectedTokensWithinCurrentRule() -> IntervalSet {
|
||||
let atn = getInterpreter().atn
|
||||
let s = atn.states[getState()]!
|
||||
return try atn.nextTokens(s)
|
||||
return atn.nextTokens(s)
|
||||
}
|
||||
|
||||
/// Get a rule's index (i.e., `RULE_ruleName` field) or -1 if not found.
|
||||
|
|
|
@ -38,9 +38,9 @@ public class ProxyErrorListener: ANTLRErrorListener {
|
|||
_ stopIndex: Int,
|
||||
_ exact: Bool,
|
||||
_ ambigAlts: BitSet,
|
||||
_ configs: ATNConfigSet) throws {
|
||||
for listener: ANTLRErrorListener in delegates {
|
||||
try listener.reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs)
|
||||
_ configs: ATNConfigSet) {
|
||||
for listener in delegates {
|
||||
listener.reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,9 +50,9 @@ public class ProxyErrorListener: ANTLRErrorListener {
|
|||
_ startIndex: Int,
|
||||
_ stopIndex: Int,
|
||||
_ conflictingAlts: BitSet?,
|
||||
_ configs: ATNConfigSet) throws {
|
||||
for listener: ANTLRErrorListener in delegates {
|
||||
try listener.reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs)
|
||||
_ configs: ATNConfigSet) {
|
||||
for listener in delegates {
|
||||
listener.reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,9 +62,9 @@ public class ProxyErrorListener: ANTLRErrorListener {
|
|||
_ startIndex: Int,
|
||||
_ stopIndex: Int,
|
||||
_ prediction: Int,
|
||||
_ configs: ATNConfigSet) throws {
|
||||
for listener: ANTLRErrorListener in delegates {
|
||||
try listener.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs)
|
||||
_ configs: ATNConfigSet) {
|
||||
for listener in delegates {
|
||||
listener.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,7 +186,7 @@ open class Recognizer<ATNInterpreter:ATNSimulator> {
|
|||
return true
|
||||
}
|
||||
|
||||
open func precpred(_ localctx: RuleContext?, _ precedence: Int) throws -> Bool {
|
||||
open func precpred(_ localctx: RuleContext?, _ precedence: Int) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -73,9 +73,9 @@ public class ATN {
|
|||
/// the rule surrounding `s`. In other words, the set will be
|
||||
/// restricted to tokens reachable staying within `s`'s rule.
|
||||
///
|
||||
public func nextTokens(_ s: ATNState, _ ctx: RuleContext?)throws -> IntervalSet {
|
||||
let anal: LL1Analyzer = LL1Analyzer(self)
|
||||
let next: IntervalSet = try anal.LOOK(s, ctx)
|
||||
public func nextTokens(_ s: ATNState, _ ctx: RuleContext?) -> IntervalSet {
|
||||
let anal = LL1Analyzer(self)
|
||||
let next = anal.LOOK(s, ctx)
|
||||
return next
|
||||
}
|
||||
|
||||
|
@ -84,14 +84,14 @@ public class ATN {
|
|||
/// staying in same rule. _org.antlr.v4.runtime.Token#EPSILON_ is in set if we reach end of
|
||||
/// rule.
|
||||
///
|
||||
public func nextTokens(_ s: ATNState) throws -> IntervalSet {
|
||||
public func nextTokens(_ s: ATNState) -> IntervalSet {
|
||||
if let nextTokenWithinRule = s.nextTokenWithinRule
|
||||
{
|
||||
return nextTokenWithinRule
|
||||
}
|
||||
let intervalSet = try nextTokens(s, nil)
|
||||
let intervalSet = nextTokens(s, nil)
|
||||
s.nextTokenWithinRule = intervalSet
|
||||
try intervalSet.setReadonly(true)
|
||||
try! intervalSet.setReadonly(true)
|
||||
return intervalSet
|
||||
}
|
||||
|
||||
|
@ -151,27 +151,27 @@ public class ATN {
|
|||
}
|
||||
|
||||
var ctx: RuleContext? = context
|
||||
let s: ATNState = states[stateNumber]!
|
||||
var following: IntervalSet = try nextTokens(s)
|
||||
let s = states[stateNumber]!
|
||||
var following = nextTokens(s)
|
||||
if !following.contains(CommonToken.EPSILON) {
|
||||
return following
|
||||
}
|
||||
|
||||
let expected: IntervalSet = try IntervalSet()
|
||||
try expected.addAll(following)
|
||||
try expected.remove(CommonToken.EPSILON)
|
||||
let expected = IntervalSet()
|
||||
try! expected.addAll(following)
|
||||
try! expected.remove(CommonToken.EPSILON)
|
||||
|
||||
while let ctxWrap = ctx , ctxWrap.invokingState >= 0 && following.contains(CommonToken.EPSILON) {
|
||||
let invokingState: ATNState = states[ctxWrap.invokingState]!
|
||||
let rt: RuleTransition = invokingState.transition(0) as! RuleTransition
|
||||
following = try nextTokens(rt.followState)
|
||||
try expected.addAll(following)
|
||||
try expected.remove(CommonToken.EPSILON)
|
||||
while let ctxWrap = ctx, ctxWrap.invokingState >= 0 && following.contains(CommonToken.EPSILON) {
|
||||
let invokingState = states[ctxWrap.invokingState]!
|
||||
let rt = invokingState.transition(0) as! RuleTransition
|
||||
following = nextTokens(rt.followState)
|
||||
try! expected.addAll(following)
|
||||
try! expected.remove(CommonToken.EPSILON)
|
||||
ctx = ctxWrap.parent
|
||||
}
|
||||
|
||||
if following.contains(CommonToken.EPSILON) {
|
||||
try expected.add(CommonToken.EOF)
|
||||
try! expected.add(CommonToken.EOF)
|
||||
}
|
||||
|
||||
return expected
|
||||
|
|
|
@ -76,9 +76,9 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
|
|||
self.init(true)
|
||||
}
|
||||
|
||||
public convenience init(_ old: ATNConfigSet) throws {
|
||||
public convenience init(_ old: ATNConfigSet) {
|
||||
self.init(old.fullCtx)
|
||||
try addAll(old)
|
||||
try! addAll(old)
|
||||
self.uniqueAlt = old.uniqueAlt
|
||||
self.conflictingAlts = old.conflictingAlts
|
||||
self.hasSemanticContext = old.hasSemanticContext
|
||||
|
@ -108,7 +108,6 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
|
|||
_ mergeCache: inout DoubleKeyMap<PredictionContext, PredictionContext, PredictionContext>?) throws -> Bool {
|
||||
if readonly {
|
||||
throw ANTLRError.illegalState(msg: "This set is readonly")
|
||||
|
||||
}
|
||||
|
||||
if config.semanticContext != SemanticContext.NONE {
|
||||
|
@ -158,11 +157,9 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
|
|||
}
|
||||
|
||||
public final func getStates() -> Set<ATNState> {
|
||||
|
||||
let length = configs.count
|
||||
var states = Set<ATNState>(minimumCapacity: length)
|
||||
for i in 0..<length {
|
||||
states.insert(configs[i].state)
|
||||
var states = Set<ATNState>(minimumCapacity: configs.count)
|
||||
for config in configs {
|
||||
states.insert(config.state)
|
||||
}
|
||||
return states
|
||||
}
|
||||
|
@ -175,21 +172,19 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
|
|||
///
|
||||
/// - since: 4.3
|
||||
///
|
||||
public final func getAlts() throws -> BitSet {
|
||||
public final func getAlts() -> BitSet {
|
||||
let alts = BitSet()
|
||||
let length = configs.count
|
||||
for i in 0..<length {
|
||||
try alts.set(configs[i].alt)
|
||||
for config in configs {
|
||||
try! alts.set(config.alt)
|
||||
}
|
||||
return alts
|
||||
}
|
||||
|
||||
public final func getPredicates() -> [SemanticContext] {
|
||||
var preds = [SemanticContext]()
|
||||
let length = configs.count
|
||||
for i in 0..<length {
|
||||
if configs[i].semanticContext != SemanticContext.NONE {
|
||||
preds.append(configs[i].semanticContext)
|
||||
for config in configs {
|
||||
if config.semanticContext != SemanticContext.NONE {
|
||||
preds.append(config.semanticContext)
|
||||
}
|
||||
}
|
||||
return preds
|
||||
|
@ -202,14 +197,12 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
|
|||
public final func optimizeConfigs(_ interpreter: ATNSimulator) throws {
|
||||
if readonly {
|
||||
throw ANTLRError.illegalState(msg: "This set is readonly")
|
||||
|
||||
}
|
||||
if configLookup.isEmpty {
|
||||
return
|
||||
}
|
||||
let length = configs.count
|
||||
for i in 0..<length {
|
||||
configs[i].context = interpreter.getCachedContext(configs[i].context!)
|
||||
for config in configs {
|
||||
config.context = interpreter.getCachedContext(config.context!)
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -265,7 +258,6 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
|
|||
public final func clear() throws {
|
||||
if readonly {
|
||||
throw ANTLRError.illegalState(msg: "This set is readonly")
|
||||
|
||||
}
|
||||
configs.removeAll()
|
||||
cachedHashCode = -1
|
||||
|
@ -318,7 +310,7 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
|
|||
return MurmurHash.finish(hashCode, 2)
|
||||
}
|
||||
|
||||
public final func getConflictingAltSubsets() throws -> Array<BitSet> {
|
||||
public final func getConflictingAltSubsets() -> [BitSet] {
|
||||
let length = configs.count
|
||||
let configToAlts = HashMap<Int, BitSet>(count: length)
|
||||
|
||||
|
@ -332,15 +324,15 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
|
|||
configToAlts[hash] = alts
|
||||
}
|
||||
|
||||
try alts.set(configs[i].alt)
|
||||
try! alts.set(configs[i].alt)
|
||||
}
|
||||
|
||||
|
||||
return configToAlts.values
|
||||
}
|
||||
public final func getStateToAltMap() throws -> HashMap<ATNState, BitSet> {
|
||||
|
||||
public final func getStateToAltMap() -> HashMap<ATNState, BitSet> {
|
||||
let length = configs.count
|
||||
let m: HashMap<ATNState, BitSet> = HashMap<ATNState, BitSet>(count: length) //minimumCapacity: length)
|
||||
let m = HashMap<ATNState, BitSet>(count: length)
|
||||
|
||||
for i in 0..<length {
|
||||
var alts: BitSet
|
||||
|
@ -351,42 +343,37 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
|
|||
m[configs[i].state] = alts
|
||||
}
|
||||
|
||||
try alts.set(configs[i].alt)
|
||||
try! alts.set(configs[i].alt)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
//for DFAState
|
||||
public final func getAltSet() -> Set<Int>? {
|
||||
var alts: Set<Int> = Set<Int>()
|
||||
let length = configs.count
|
||||
for i in 0..<length {
|
||||
alts.insert(configs[i].alt)
|
||||
}
|
||||
|
||||
if alts.isEmpty {
|
||||
if configs.isEmpty {
|
||||
return nil
|
||||
}
|
||||
var alts = Set<Int>()
|
||||
for config in configs {
|
||||
alts.insert(config.alt)
|
||||
}
|
||||
return alts
|
||||
}
|
||||
|
||||
//for DiagnosticErrorListener
|
||||
public final func getAltBitSet() throws -> BitSet {
|
||||
let result: BitSet = BitSet()
|
||||
let length = configs.count
|
||||
for i in 0..<length {
|
||||
try result.set(configs[i].alt)
|
||||
public final func getAltBitSet() -> BitSet {
|
||||
let result = BitSet()
|
||||
for config in configs {
|
||||
try! result.set(config.alt)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
//LexerATNSimulator
|
||||
public final var firstConfigWithRuleStopState: ATNConfig? {
|
||||
let length = configs.count
|
||||
for i in 0..<length {
|
||||
if configs[i].state is RuleStopState {
|
||||
return configs[i]
|
||||
public final var firstConfigWithRuleStopState: ATNConfig? {
|
||||
for config in configs {
|
||||
if config.state is RuleStopState {
|
||||
return config
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -395,135 +382,124 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
|
|||
|
||||
//ParserATNSimulator
|
||||
|
||||
public final func getUniqueAlt() -> Int {
|
||||
var alt: Int = ATN.INVALID_ALT_NUMBER
|
||||
let length = configs.count
|
||||
for i in 0..<length {
|
||||
public final func getUniqueAlt() -> Int {
|
||||
var alt = ATN.INVALID_ALT_NUMBER
|
||||
for config in configs {
|
||||
if alt == ATN.INVALID_ALT_NUMBER {
|
||||
alt = configs[i].alt // found first alt
|
||||
} else {
|
||||
if configs[i].alt != alt {
|
||||
return ATN.INVALID_ALT_NUMBER
|
||||
}
|
||||
alt = config.alt // found first alt
|
||||
} else if config.alt != alt {
|
||||
return ATN.INVALID_ALT_NUMBER
|
||||
}
|
||||
}
|
||||
return alt
|
||||
}
|
||||
public final func removeAllConfigsNotInRuleStopState(_ mergeCache: inout DoubleKeyMap<PredictionContext, PredictionContext, PredictionContext>?,_ lookToEndOfRule: Bool,_ atn: ATN) throws -> ATNConfigSet {
|
||||
|
||||
public final func removeAllConfigsNotInRuleStopState(_ mergeCache: inout DoubleKeyMap<PredictionContext, PredictionContext, PredictionContext>?,_ lookToEndOfRule: Bool,_ atn: ATN) -> ATNConfigSet {
|
||||
if PredictionMode.allConfigsInRuleStopStates(self) {
|
||||
return self
|
||||
}
|
||||
|
||||
let result: ATNConfigSet = ATNConfigSet(fullCtx)
|
||||
let length = configs.count
|
||||
for i in 0..<length {
|
||||
if configs[i].state is RuleStopState {
|
||||
try result.add(configs[i],&mergeCache)
|
||||
let result = ATNConfigSet(fullCtx)
|
||||
for config in configs {
|
||||
if config.state is RuleStopState {
|
||||
try! result.add(config, &mergeCache)
|
||||
continue
|
||||
}
|
||||
|
||||
if lookToEndOfRule && configs[i].state.onlyHasEpsilonTransitions() {
|
||||
let nextTokens: IntervalSet = try atn.nextTokens(configs[i].state)
|
||||
if lookToEndOfRule && config.state.onlyHasEpsilonTransitions() {
|
||||
let nextTokens = atn.nextTokens(config.state)
|
||||
if nextTokens.contains(CommonToken.EPSILON) {
|
||||
let endOfRuleState: ATNState = atn.ruleToStopState[configs[i].state.ruleIndex!]
|
||||
try result.add(ATNConfig(configs[i], endOfRuleState), &mergeCache)
|
||||
let endOfRuleState = atn.ruleToStopState[config.state.ruleIndex!]
|
||||
try! result.add(ATNConfig(config, endOfRuleState), &mergeCache)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
public final func applyPrecedenceFilter(_ mergeCache: inout DoubleKeyMap<PredictionContext, PredictionContext, PredictionContext>?,_ parser: Parser,_ _outerContext: ParserRuleContext!) throws -> ATNConfigSet {
|
||||
|
||||
let configSet: ATNConfigSet = ATNConfigSet(fullCtx)
|
||||
let length = configs.count
|
||||
let statesFromAlt1: HashMap<Int, PredictionContext> = HashMap<Int, PredictionContext>(count: length)
|
||||
for i in 0..<length {
|
||||
let configSet = ATNConfigSet(fullCtx)
|
||||
let statesFromAlt1 = HashMap<Int, PredictionContext>(count: configs.count)
|
||||
for config in configs {
|
||||
// handle alt 1 first
|
||||
if configs[i].alt != 1 {
|
||||
if config.alt != 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
let updatedContext: SemanticContext? = try configs[i].semanticContext.evalPrecedence(parser, _outerContext)
|
||||
let updatedContext = try config.semanticContext.evalPrecedence(parser, _outerContext)
|
||||
if updatedContext == nil {
|
||||
// the configuration was eliminated
|
||||
continue
|
||||
}
|
||||
|
||||
statesFromAlt1[configs[i].state.stateNumber] = configs[i].context
|
||||
if updatedContext != configs[i].semanticContext {
|
||||
try configSet.add(ATNConfig(configs[i], updatedContext!), &mergeCache)
|
||||
statesFromAlt1[config.state.stateNumber] = config.context
|
||||
if updatedContext != config.semanticContext {
|
||||
try! configSet.add(ATNConfig(config, updatedContext!), &mergeCache)
|
||||
} else {
|
||||
try configSet.add(configs[i],&mergeCache)
|
||||
try! configSet.add(config, &mergeCache)
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0..<length {
|
||||
if configs[i].alt == 1 {
|
||||
for config in configs {
|
||||
if config.alt == 1 {
|
||||
// already handled
|
||||
continue
|
||||
}
|
||||
|
||||
if !configs[i].isPrecedenceFilterSuppressed() {
|
||||
if !config.isPrecedenceFilterSuppressed() {
|
||||
///
|
||||
/// In the future, this elimination step could be updated to also
|
||||
/// filter the prediction context for alternatives predicting alt>1
|
||||
/// (basically a graph subtraction algorithm).
|
||||
///
|
||||
let context: PredictionContext? = statesFromAlt1[configs[i].state.stateNumber]
|
||||
if context != nil && context == configs[i].context {
|
||||
let context = statesFromAlt1[config.state.stateNumber]
|
||||
if context != nil && context == config.context {
|
||||
// eliminated
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
try configSet.add(configs[i], &mergeCache)
|
||||
try! configSet.add(config, &mergeCache)
|
||||
}
|
||||
|
||||
return configSet
|
||||
}
|
||||
internal func getPredsForAmbigAlts(_ ambigAlts: BitSet,
|
||||
_ nalts: Int) throws -> [SemanticContext?]? {
|
||||
|
||||
var altToPred: [SemanticContext?]? = [SemanticContext?](repeating: nil, count: nalts + 1) //new SemanticContext[nalts + 1];
|
||||
let length = configs.count
|
||||
for i in 0..<length {
|
||||
if try ambigAlts.get(configs[i].alt) {
|
||||
altToPred![configs[i].alt] = SemanticContext.or(altToPred![configs[i].alt], configs[i].semanticContext)
|
||||
}
|
||||
internal func getPredsForAmbigAlts(_ ambigAlts: BitSet, _ nalts: Int) -> [SemanticContext?]? {
|
||||
var altToPred = [SemanticContext?](repeating: nil, count: nalts + 1)
|
||||
for config in configs {
|
||||
if try! ambigAlts.get(config.alt) {
|
||||
altToPred[config.alt] = SemanticContext.or(altToPred[config.alt], config.semanticContext)
|
||||
}
|
||||
var nPredAlts: Int = 0
|
||||
for i in 1...nalts {
|
||||
if altToPred![i] == nil {
|
||||
altToPred![i] = SemanticContext.NONE
|
||||
} else {
|
||||
if altToPred![i] != SemanticContext.NONE {
|
||||
nPredAlts += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
var nPredAlts = 0
|
||||
for i in 1...nalts {
|
||||
if altToPred[i] == nil {
|
||||
altToPred[i] = SemanticContext.NONE
|
||||
}
|
||||
|
||||
// // Optimize away p||p and p&&p TODO: optimize() was a no-op
|
||||
// for (int i = 0; i < altToPred.length; i++) {
|
||||
// altToPred[i] = altToPred[i].optimize();
|
||||
// }
|
||||
|
||||
// nonambig alts are null in altToPred
|
||||
if nPredAlts == 0 {
|
||||
altToPred = nil
|
||||
else if altToPred[i] != SemanticContext.NONE {
|
||||
nPredAlts += 1
|
||||
}
|
||||
}
|
||||
|
||||
return altToPred
|
||||
// // Optimize away p||p and p&&p TODO: optimize() was a no-op
|
||||
// for (int i = 0; i < altToPred.length; i++) {
|
||||
// altToPred[i] = altToPred[i].optimize();
|
||||
// }
|
||||
|
||||
// nonambig alts are null in altToPred
|
||||
return (nPredAlts == 0 ? nil : altToPred)
|
||||
}
|
||||
public final func getAltThatFinishedDecisionEntryRule() throws -> Int {
|
||||
let alts: IntervalSet = try IntervalSet()
|
||||
let length = configs.count
|
||||
for i in 0..<length {
|
||||
if configs[i].getOuterContextDepth() > 0 ||
|
||||
(configs[i].state is RuleStopState &&
|
||||
configs[i].context!.hasEmptyPath()) {
|
||||
try alts.add(configs[i].alt)
|
||||
|
||||
public final func getAltThatFinishedDecisionEntryRule() -> Int {
|
||||
let alts = IntervalSet()
|
||||
for config in configs {
|
||||
if config.getOuterContextDepth() > 0 ||
|
||||
(config.state is RuleStopState &&
|
||||
config.context!.hasEmptyPath()) {
|
||||
try! alts.add(config.alt)
|
||||
}
|
||||
}
|
||||
if alts.size() == 0 {
|
||||
|
@ -544,39 +520,36 @@ public class ATNConfigSet: Hashable, CustomStringConvertible {
|
|||
///
|
||||
public final func splitAccordingToSemanticValidity(
|
||||
_ outerContext: ParserRuleContext,
|
||||
_ evalSemanticContext:( SemanticContext,ParserRuleContext,Int,Bool) throws -> Bool) throws -> (ATNConfigSet, ATNConfigSet) {
|
||||
let succeeded: ATNConfigSet = ATNConfigSet(fullCtx)
|
||||
let failed: ATNConfigSet = ATNConfigSet(fullCtx)
|
||||
let length = configs.count
|
||||
for i in 0..<length {
|
||||
if configs[i].semanticContext != SemanticContext.NONE {
|
||||
let predicateEvaluationResult: Bool = try evalSemanticContext(configs[i].semanticContext, outerContext, configs[i].alt,fullCtx)
|
||||
if predicateEvaluationResult {
|
||||
try succeeded.add(configs[i])
|
||||
} else {
|
||||
try failed.add(configs[i])
|
||||
}
|
||||
_ evalSemanticContext: (SemanticContext, ParserRuleContext, Int, Bool) throws -> Bool) rethrows -> (ATNConfigSet, ATNConfigSet) {
|
||||
let succeeded = ATNConfigSet(fullCtx)
|
||||
let failed = ATNConfigSet(fullCtx)
|
||||
for config in configs {
|
||||
if config.semanticContext != SemanticContext.NONE {
|
||||
let predicateEvaluationResult = try evalSemanticContext(config.semanticContext, outerContext, config.alt,fullCtx)
|
||||
if predicateEvaluationResult {
|
||||
try! succeeded.add(config)
|
||||
} else {
|
||||
try succeeded.add(configs[i])
|
||||
try! failed.add(config)
|
||||
}
|
||||
} else {
|
||||
try! succeeded.add(config)
|
||||
}
|
||||
return (succeeded, failed)
|
||||
}
|
||||
return (succeeded, failed)
|
||||
}
|
||||
|
||||
//public enum PredictionMode
|
||||
public final func dupConfigsWithoutSemanticPredicates() throws -> ATNConfigSet {
|
||||
let dup: ATNConfigSet = ATNConfigSet()
|
||||
let length = configs.count
|
||||
for i in 0..<length {
|
||||
let c = ATNConfig(configs[i], SemanticContext.NONE)
|
||||
try dup.add(c)
|
||||
public final func dupConfigsWithoutSemanticPredicates() -> ATNConfigSet {
|
||||
let dup = ATNConfigSet()
|
||||
for config in configs {
|
||||
let c = ATNConfig(config, SemanticContext.NONE)
|
||||
try! dup.add(c)
|
||||
}
|
||||
return dup
|
||||
}
|
||||
|
||||
public final var hasConfigInRuleStopState: Bool {
|
||||
let length = configs.count
|
||||
for i in 0..<length {
|
||||
if configs[i].state is RuleStopState {
|
||||
for config in configs {
|
||||
if config.state is RuleStopState {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -268,12 +268,12 @@ public class ATNDeserializer {
|
|||
var sets: Array<IntervalSet> = Array<IntervalSet>()
|
||||
|
||||
// First, deserialize sets with 16-bit arguments <= U+FFFF.
|
||||
try readSets(data, &p, &sets, readUnicodeInt)
|
||||
readSets(data, &p, &sets, readUnicodeInt)
|
||||
|
||||
// Next, if the ATN was serialized with the Unicode SMP feature,
|
||||
// deserialize sets with 32-bit arguments <= U+10FFFF.
|
||||
if isFeatureSupported(ATNDeserializer.ADDED_UNICODE_SMP, uuid) {
|
||||
try readSets(data, &p, &sets, readUnicodeInt32)
|
||||
readSets(data, &p, &sets, readUnicodeInt32)
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -544,23 +544,23 @@ public class ATNDeserializer {
|
|||
return result
|
||||
}
|
||||
|
||||
private func readSets(_ data: [Character], _ p: inout Int, _ sets: inout Array<IntervalSet>, _ readUnicode: ([Character], inout Int) -> Int) throws {
|
||||
private func readSets(_ data: [Character], _ p: inout Int, _ sets: inout Array<IntervalSet>, _ readUnicode: ([Character], inout Int) -> Int) {
|
||||
let nsets = toInt(data[p])
|
||||
p += 1
|
||||
for _ in 0..<nsets {
|
||||
let nintervals = toInt(data[p])
|
||||
p += 1
|
||||
let set = try IntervalSet()
|
||||
let set = IntervalSet()
|
||||
sets.append(set)
|
||||
|
||||
let containsEof = (toInt(data[p]) != 0)
|
||||
p += 1
|
||||
if containsEof {
|
||||
try set.add(-1)
|
||||
try! set.add(-1)
|
||||
}
|
||||
|
||||
for _ in 0..<nintervals {
|
||||
try set.add(readUnicode(data, &p), readUnicode(data, &p))
|
||||
try! set.add(readUnicode(data, &p), readUnicode(data, &p))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -728,19 +728,19 @@ public class ATNDeserializer {
|
|||
let setBuilder = intervalSet[i]
|
||||
let nintervals = setBuilder["size"] as! Int
|
||||
|
||||
let set = try IntervalSet()
|
||||
let set = IntervalSet()
|
||||
sets.append(set)
|
||||
|
||||
let containsEof = (setBuilder["containsEof"] as! Int) != 0
|
||||
if containsEof {
|
||||
try set.add(-1)
|
||||
try! set.add(-1)
|
||||
}
|
||||
let intervalsBuilder = setBuilder["Intervals"] as! [[String : Any]]
|
||||
|
||||
|
||||
for j in 0..<nintervals {
|
||||
let vals = intervalsBuilder[j]
|
||||
try set.add((vals["a"] as! Int), (vals["b"] as! Int))
|
||||
try! set.add((vals["a"] as! Int), (vals["b"] as! Int))
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,8 @@ public final class AtomTransition: Transition, CustomStringConvertible {
|
|||
}
|
||||
|
||||
override
|
||||
public func labelIntervalSet() throws -> IntervalSet? {
|
||||
return try IntervalSet.of(label)
|
||||
public func labelIntervalSet() -> IntervalSet? {
|
||||
return IntervalSet(label)
|
||||
}
|
||||
|
||||
override
|
||||
|
|
|
@ -28,7 +28,7 @@ public class LL1Analyzer {
|
|||
/// - parameter s: the ATN state
|
||||
/// - returns: the expected symbols for each outgoing transition of `s`.
|
||||
///
|
||||
public func getDecisionLookahead(_ s: ATNState?) throws -> [IntervalSet?]? {
|
||||
public func getDecisionLookahead(_ s: ATNState?) -> [IntervalSet?]? {
|
||||
|
||||
guard let s = s else {
|
||||
return nil
|
||||
|
@ -36,10 +36,10 @@ public class LL1Analyzer {
|
|||
let length = s.getNumberOfTransitions()
|
||||
var look = [IntervalSet?](repeating: nil, count: length)
|
||||
for alt in 0..<length {
|
||||
look[alt] = try IntervalSet()
|
||||
look[alt] = IntervalSet()
|
||||
var lookBusy = Set<ATNConfig>()
|
||||
let seeThruPreds = false // fail to get lookahead upon pred
|
||||
try _LOOK(s.transition(alt).target, nil, PredictionContext.EMPTY,
|
||||
_LOOK(s.transition(alt).target, nil, PredictionContext.EMPTY,
|
||||
look[alt]!, &lookBusy, BitSet(), seeThruPreds, false)
|
||||
// Wipe out lookahead for this alternative if we found nothing
|
||||
// or we had a predicate when we !seeThruPreds
|
||||
|
@ -66,8 +66,8 @@ public class LL1Analyzer {
|
|||
/// - returns: The set of tokens that can follow `s` in the ATN in the
|
||||
/// specified `ctx`.
|
||||
///
|
||||
public func LOOK(_ s: ATNState, _ ctx: RuleContext?) throws -> IntervalSet {
|
||||
return try LOOK(s, nil, ctx)
|
||||
public func LOOK(_ s: ATNState, _ ctx: RuleContext?) -> IntervalSet {
|
||||
return LOOK(s, nil, ctx)
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -89,13 +89,12 @@ public class LL1Analyzer {
|
|||
/// specified `ctx`.
|
||||
///
|
||||
|
||||
public func LOOK(_ s: ATNState, _ stopState: ATNState?, _ ctx: RuleContext?) throws -> IntervalSet {
|
||||
let r = try IntervalSet()
|
||||
public func LOOK(_ s: ATNState, _ stopState: ATNState?, _ ctx: RuleContext?) -> IntervalSet {
|
||||
let r = IntervalSet()
|
||||
let seeThruPreds = true // ignore preds; get all lookahead
|
||||
let lookContext = ctx != nil ? PredictionContext.fromRuleContext(s.atn!, ctx) : nil
|
||||
var config = Set<ATNConfig>()
|
||||
try _LOOK(s, stopState, lookContext,
|
||||
r, &config, BitSet(), seeThruPreds, true)
|
||||
_LOOK(s, stopState, lookContext, r, &config, BitSet(), seeThruPreds, true)
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -135,12 +134,10 @@ public class LL1Analyzer {
|
|||
_ look: IntervalSet,
|
||||
_ lookBusy: inout Set<ATNConfig>,
|
||||
_ calledRuleStack: BitSet,
|
||||
_ seeThruPreds: Bool, _ addEOF: Bool) throws {
|
||||
_ seeThruPreds: Bool,
|
||||
_ addEOF: Bool) {
|
||||
// print ("_LOOK(\(s.stateNumber), ctx=\(ctx)");
|
||||
if s.description == "273" {
|
||||
var s = 0
|
||||
}
|
||||
var c = ATNConfig(s, 0, ctx)
|
||||
let c = ATNConfig(s, 0, ctx)
|
||||
if lookBusy.contains(c) {
|
||||
return
|
||||
} else {
|
||||
|
@ -149,12 +146,12 @@ public class LL1Analyzer {
|
|||
|
||||
if s == stopState {
|
||||
guard let ctx = ctx else {
|
||||
try look.add(CommonToken.EPSILON)
|
||||
try! look.add(CommonToken.EPSILON)
|
||||
return
|
||||
}
|
||||
|
||||
if ctx.isEmpty() && addEOF {
|
||||
try look.add(CommonToken.EOF)
|
||||
try! look.add(CommonToken.EOF)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -162,73 +159,64 @@ public class LL1Analyzer {
|
|||
|
||||
if s is RuleStopState {
|
||||
guard let ctx = ctx else {
|
||||
try look.add(CommonToken.EPSILON)
|
||||
try! look.add(CommonToken.EPSILON)
|
||||
return
|
||||
}
|
||||
|
||||
if ctx.isEmpty() && addEOF {
|
||||
try look.add(CommonToken.EOF)
|
||||
try! look.add(CommonToken.EOF)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if ctx != PredictionContext.EMPTY {
|
||||
// run thru all possible stack tops in ctx
|
||||
let length = ctx.size()
|
||||
for i in 0..<length {
|
||||
var returnState = atn.states[(ctx.getReturnState(i))]!
|
||||
|
||||
var removed = try calledRuleStack.get(returnState.ruleIndex!)
|
||||
try calledRuleStack.clear(returnState.ruleIndex!)
|
||||
try self._LOOK(returnState, stopState, ctx.getParent(i), look, &lookBusy, calledRuleStack, seeThruPreds, addEOF)
|
||||
defer {
|
||||
if removed {
|
||||
try! calledRuleStack.set(returnState.ruleIndex!)
|
||||
}
|
||||
let returnState = atn.states[(ctx.getReturnState(i))]!
|
||||
let removed = try! calledRuleStack.get(returnState.ruleIndex!)
|
||||
try! calledRuleStack.clear(returnState.ruleIndex!)
|
||||
_LOOK(returnState, stopState, ctx.getParent(i), look, &lookBusy, calledRuleStack, seeThruPreds, addEOF)
|
||||
if removed {
|
||||
try! calledRuleStack.set(returnState.ruleIndex!)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var n = s.getNumberOfTransitions()
|
||||
let n = s.getNumberOfTransitions()
|
||||
for i in 0..<n {
|
||||
var t = s.transition(i)
|
||||
let t = s.transition(i)
|
||||
if let rt = t as? RuleTransition {
|
||||
if try calledRuleStack.get(rt.target.ruleIndex!) {
|
||||
if try! calledRuleStack.get(rt.target.ruleIndex!) {
|
||||
continue
|
||||
}
|
||||
|
||||
var newContext = SingletonPredictionContext.create(ctx, rt.followState.stateNumber)
|
||||
try calledRuleStack.set(rt.target.ruleIndex!)
|
||||
try _LOOK(t.target, stopState, newContext, look, &lookBusy, calledRuleStack, seeThruPreds, addEOF)
|
||||
defer {
|
||||
try! calledRuleStack.clear(rt.target.ruleIndex!)
|
||||
}
|
||||
} else {
|
||||
if t is AbstractPredicateTransition {
|
||||
if seeThruPreds {
|
||||
try _LOOK(t.target, stopState, ctx, look, &lookBusy, calledRuleStack, seeThruPreds, addEOF)
|
||||
} else {
|
||||
try look.add(HIT_PRED)
|
||||
}
|
||||
let newContext = SingletonPredictionContext.create(ctx, rt.followState.stateNumber)
|
||||
try! calledRuleStack.set(rt.target.ruleIndex!)
|
||||
_LOOK(t.target, stopState, newContext, look, &lookBusy, calledRuleStack, seeThruPreds, addEOF)
|
||||
try! calledRuleStack.clear(rt.target.ruleIndex!)
|
||||
}
|
||||
else if t is AbstractPredicateTransition {
|
||||
if seeThruPreds {
|
||||
_LOOK(t.target, stopState, ctx, look, &lookBusy, calledRuleStack, seeThruPreds, addEOF)
|
||||
} else {
|
||||
if t.isEpsilon() {
|
||||
try _LOOK(t.target, stopState, ctx, look, &lookBusy, calledRuleStack, seeThruPreds, addEOF)
|
||||
} else {
|
||||
if t is WildcardTransition {
|
||||
try look.addAll(IntervalSet.of(CommonToken.MIN_USER_TOKEN_TYPE, atn.maxTokenType))
|
||||
} else {
|
||||
|
||||
var set = try t.labelIntervalSet()
|
||||
if set != nil {
|
||||
if t is NotSetTransition {
|
||||
set = try set!.complement(IntervalSet.of(CommonToken.MIN_USER_TOKEN_TYPE, atn.maxTokenType)) as? IntervalSet
|
||||
}
|
||||
try look.addAll(set)
|
||||
}
|
||||
}
|
||||
try! look.add(HIT_PRED)
|
||||
}
|
||||
}
|
||||
else if t.isEpsilon() {
|
||||
_LOOK(t.target, stopState, ctx, look, &lookBusy, calledRuleStack, seeThruPreds, addEOF)
|
||||
}
|
||||
else if t is WildcardTransition {
|
||||
try! look.addAll(IntervalSet.of(CommonToken.MIN_USER_TOKEN_TYPE, atn.maxTokenType))
|
||||
}
|
||||
else {
|
||||
var set = t.labelIntervalSet()
|
||||
if set != nil {
|
||||
if t is NotSetTransition {
|
||||
set = set!.complement(IntervalSet.of(CommonToken.MIN_USER_TOKEN_TYPE, atn.maxTokenType)) as? IntervalSet
|
||||
}
|
||||
try! look.addAll(set)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -377,10 +377,10 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
//added by janyou 20160224
|
||||
// dfa.s0!.configs = s0_closure // not used for prediction but useful to know start configs anyway
|
||||
s0_closure = try applyPrecedenceFilter(s0_closure)
|
||||
s0 = try addDFAState(dfa, DFAState(s0_closure))
|
||||
s0 = addDFAState(dfa, DFAState(s0_closure))
|
||||
try dfa.setPrecedenceStartState(parser.getPrecedence(), s0!)
|
||||
} else {
|
||||
s0 = try addDFAState(dfa, DFAState(s0_closure))
|
||||
s0 = addDFAState(dfa, DFAState(s0_closure))
|
||||
dfa.s0 = s0
|
||||
}
|
||||
}
|
||||
|
@ -463,9 +463,9 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
// ATN states in SLL implies LL will also get nowhere.
|
||||
// If conflict in states that dip out, choose min since we
|
||||
// will get error no matter what.
|
||||
let e: NoViableAltException = try noViableAlt(input, outerContext, previousD.configs, startIndex)
|
||||
let e = noViableAlt(input, outerContext, previousD.configs, startIndex)
|
||||
try input.seek(startIndex)
|
||||
let alt: Int = try getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(previousD.configs, outerContext)
|
||||
let alt = try getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(previousD.configs, outerContext)
|
||||
if alt != ATN.INVALID_ALT_NUMBER {
|
||||
return alt
|
||||
}
|
||||
|
@ -491,7 +491,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
if debug {
|
||||
print("Full LL avoided")
|
||||
}
|
||||
return try conflictingAlts.nextSetBit(0)
|
||||
return conflictingAlts.firstSetBit()
|
||||
}
|
||||
|
||||
if conflictIndex != startIndex {
|
||||
|
@ -506,7 +506,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
}
|
||||
let fullCtx = true
|
||||
let s0_closure = try computeStartState(dfa.atnStartState, outerContext, fullCtx)
|
||||
try reportAttemptingFullContext(dfa, conflictingAlts, D.configs, startIndex, input.index())
|
||||
reportAttemptingFullContext(dfa, conflictingAlts, D.configs, startIndex, input.index())
|
||||
let alt = try execATNWithFullContext(dfa, D, s0_closure,
|
||||
input, startIndex,
|
||||
outerContext)
|
||||
|
@ -518,22 +518,22 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
return D.prediction
|
||||
}
|
||||
|
||||
let stopIndex: Int = input.index()
|
||||
let stopIndex = input.index()
|
||||
try input.seek(startIndex)
|
||||
let alts: BitSet = try evalSemanticContext(D.predicates!, outerContext, true)
|
||||
let alts = try evalSemanticContext(D.predicates!, outerContext, true)
|
||||
switch alts.cardinality() {
|
||||
case 0:
|
||||
throw try ANTLRException.recognition(e: noViableAlt(input, outerContext, D.configs, startIndex))
|
||||
throw ANTLRException.recognition(e: noViableAlt(input, outerContext, D.configs, startIndex))
|
||||
|
||||
|
||||
case 1:
|
||||
return try alts.nextSetBit(0)
|
||||
return alts.firstSetBit()
|
||||
|
||||
default:
|
||||
// report ambiguity after predicate evaluation to make sure the correct
|
||||
// set of ambig alts is reported.
|
||||
try reportAmbiguity(dfa, D, startIndex, stopIndex, false, alts, D.configs)
|
||||
return try alts.nextSetBit(0)
|
||||
reportAmbiguity(dfa, D, startIndex, stopIndex, false, alts, D.configs)
|
||||
return alts.firstSetBit()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -582,7 +582,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
|
||||
let reach = try computeReachSet(previousD.configs, t, false)
|
||||
if reach == nil {
|
||||
try addDFAEdge(dfa, previousD, t, ATNSimulator.ERROR)
|
||||
addDFAEdge(dfa, previousD, t, ATNSimulator.ERROR)
|
||||
return ATNSimulator.ERROR
|
||||
}
|
||||
|
||||
|
@ -592,8 +592,8 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
let predictedAlt: Int = ParserATNSimulator.getUniqueAlt(reach!)
|
||||
|
||||
if debug {
|
||||
let altSubSets: Array<BitSet> = try PredictionMode.getConflictingAltSubsets(reach!)
|
||||
print("SLL altSubSets=\(altSubSets), configs=\(reach!), predict=\(predictedAlt), allSubsetsConflict=\(PredictionMode.allSubsetsConflict(altSubSets)), conflictingAlts=\(try! getConflictingAlts(reach!))")
|
||||
let altSubSets = PredictionMode.getConflictingAltSubsets(reach!)
|
||||
print("SLL altSubSets=\(altSubSets), configs=\(reach!), predict=\(predictedAlt), allSubsetsConflict=\(PredictionMode.allSubsetsConflict(altSubSets)), conflictingAlts=\(getConflictingAlts(reach!))")
|
||||
}
|
||||
|
||||
if predictedAlt != ATN.INVALID_ALT_NUMBER {
|
||||
|
@ -602,44 +602,43 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
D.configs.uniqueAlt = predictedAlt
|
||||
D.prediction = predictedAlt
|
||||
} else {
|
||||
if try PredictionMode.hasSLLConflictTerminatingPrediction(mode, reach!) {
|
||||
if PredictionMode.hasSLLConflictTerminatingPrediction(mode, reach!) {
|
||||
// MORE THAN ONE VIABLE ALTERNATIVE
|
||||
D.configs.conflictingAlts = try getConflictingAlts(reach!)
|
||||
D.configs.conflictingAlts = getConflictingAlts(reach!)
|
||||
D.requiresFullContext = true
|
||||
// in SLL-only mode, we will stop at this state and return the minimum alt
|
||||
D.isAcceptState = true
|
||||
D.prediction = try D.configs.conflictingAlts!.nextSetBit(0)
|
||||
D.prediction = D.configs.conflictingAlts!.firstSetBit()
|
||||
}
|
||||
}
|
||||
|
||||
if D.isAcceptState && D.configs.hasSemanticContext {
|
||||
try predicateDFAState(D, atn.getDecisionState(dfa.decision)!)
|
||||
predicateDFAState(D, atn.getDecisionState(dfa.decision)!)
|
||||
if D.predicates != nil {
|
||||
D.prediction = ATN.INVALID_ALT_NUMBER
|
||||
}
|
||||
}
|
||||
|
||||
// all adds to dfa are done after we've created full D state
|
||||
D = try addDFAEdge(dfa, previousD, t, D)!
|
||||
D = addDFAEdge(dfa, previousD, t, D)!
|
||||
return D
|
||||
}
|
||||
|
||||
final func predicateDFAState(_ dfaState: DFAState, _ decisionState: DecisionState) throws {
|
||||
final func predicateDFAState(_ dfaState: DFAState, _ decisionState: DecisionState) {
|
||||
// We need to test all predicates, even in DFA states that
|
||||
// uniquely predict alternative.
|
||||
let nalts: Int = decisionState.getNumberOfTransitions()
|
||||
let nalts = decisionState.getNumberOfTransitions()
|
||||
// Update DFA so reach becomes accept state with (predicate,alt)
|
||||
// pairs if preds found for conflicting alts
|
||||
let altsToCollectPredsFrom: BitSet = try getConflictingAltsOrUniqueAlt(dfaState.configs)
|
||||
let altToPred: [SemanticContext?]? = try getPredsForAmbigAlts(altsToCollectPredsFrom, dfaState.configs, nalts)
|
||||
if altToPred != nil {
|
||||
dfaState.predicates = try getPredicatePredictions(altsToCollectPredsFrom, altToPred!)
|
||||
let altsToCollectPredsFrom = getConflictingAltsOrUniqueAlt(dfaState.configs)
|
||||
if let altToPred = getPredsForAmbigAlts(altsToCollectPredsFrom, dfaState.configs, nalts) {
|
||||
dfaState.predicates = getPredicatePredictions(altsToCollectPredsFrom, altToPred)
|
||||
dfaState.prediction = ATN.INVALID_ALT_NUMBER // make sure we use preds
|
||||
} else {
|
||||
// There are preds in configs but they might go away
|
||||
// when OR'd together like {p}? || NONE == NONE. If neither
|
||||
// alt has preds, resolve to min alt
|
||||
dfaState.prediction = try altsToCollectPredsFrom.nextSetBit(0)
|
||||
dfaState.prediction = altsToCollectPredsFrom.firstSetBit()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -673,9 +672,9 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
// ATN states in SLL implies LL will also get nowhere.
|
||||
// If conflict in states that dip out, choose min since we
|
||||
// will get error no matter what.
|
||||
let e: NoViableAltException = try noViableAlt(input, outerContext, previous, startIndex)
|
||||
let e = noViableAlt(input, outerContext, previous, startIndex)
|
||||
try input.seek(startIndex)
|
||||
let alt: Int = try getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(previous, outerContext)
|
||||
let alt = try getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(previous, outerContext)
|
||||
if alt != ATN.INVALID_ALT_NUMBER {
|
||||
return alt
|
||||
}
|
||||
|
@ -683,9 +682,9 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
|
||||
}
|
||||
if let reach = reach {
|
||||
let altSubSets: Array<BitSet> = try PredictionMode.getConflictingAltSubsets(reach)
|
||||
let altSubSets = PredictionMode.getConflictingAltSubsets(reach)
|
||||
if debug {
|
||||
print("LL altSubSets=\(altSubSets), predict=\(try PredictionMode.getUniqueAlt(altSubSets)), resolvesToJustOneViableAlt=\(try PredictionMode.resolvesToJustOneViableAlt(altSubSets))")
|
||||
print("LL altSubSets=\(altSubSets), predict=\(PredictionMode.getUniqueAlt(altSubSets)), resolvesToJustOneViableAlt=\(PredictionMode.resolvesToJustOneViableAlt(altSubSets))")
|
||||
}
|
||||
|
||||
|
||||
|
@ -696,7 +695,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
break
|
||||
}
|
||||
if mode != PredictionMode.LL_EXACT_AMBIG_DETECTION {
|
||||
predictedAlt = try PredictionMode.resolvesToJustOneViableAlt(altSubSets)
|
||||
predictedAlt = PredictionMode.resolvesToJustOneViableAlt(altSubSets)
|
||||
if predictedAlt != ATN.INVALID_ALT_NUMBER {
|
||||
break
|
||||
}
|
||||
|
@ -706,7 +705,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
if PredictionMode.allSubsetsConflict(altSubSets) &&
|
||||
PredictionMode.allSubsetsEqual(altSubSets) {
|
||||
foundExactAmbig = true
|
||||
predictedAlt = try PredictionMode.getSingleViableAlt(altSubSets)
|
||||
predictedAlt = PredictionMode.getSingleViableAlt(altSubSets)
|
||||
break
|
||||
}
|
||||
// else there are multiple non-conflicting subsets or
|
||||
|
@ -726,7 +725,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
// without conflict, then we know that it's a full LL decision
|
||||
// not SLL.
|
||||
if reach.uniqueAlt != ATN.INVALID_ALT_NUMBER {
|
||||
try reportContextSensitivity(dfa, predictedAlt, reach, startIndex, input.index())
|
||||
reportContextSensitivity(dfa, predictedAlt, reach, startIndex, input.index())
|
||||
return predictedAlt
|
||||
}
|
||||
|
||||
|
@ -757,8 +756,8 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
/// the fact that we should predict alternative 1. We just can't say for
|
||||
/// sure that there is an ambiguity without looking further.
|
||||
///
|
||||
try reportAmbiguity(dfa, D, startIndex, input.index(), foundExactAmbig,
|
||||
reach.getAlts(), reach)
|
||||
reportAmbiguity(dfa, D, startIndex, input.index(), foundExactAmbig,
|
||||
reach.getAlts(), reach)
|
||||
}
|
||||
return predictedAlt
|
||||
}
|
||||
|
@ -813,7 +812,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
// for each transition
|
||||
let trans = config.state.transition(ti)
|
||||
if let target = getReachableTarget(trans, t) {
|
||||
try intermediate.add(ATNConfig(config, target), &mergeCache)
|
||||
try! intermediate.add(ATNConfig(config, target), &mergeCache)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -880,7 +879,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
/// already guaranteed to meet this condition whether or not it's
|
||||
/// required.
|
||||
///
|
||||
reach = try removeAllConfigsNotInRuleStopState(reach!, reach! === intermediate)
|
||||
reach = removeAllConfigsNotInRuleStopState(reach!, reach! === intermediate)
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -927,29 +926,22 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
/// rule stop state, otherwise return a new configuration set containing only
|
||||
/// the configurations from `configs` which are in a rule stop state
|
||||
///
|
||||
final func removeAllConfigsNotInRuleStopState(_ configs: ATNConfigSet, _ lookToEndOfRule: Bool) throws -> ATNConfigSet {
|
||||
|
||||
let result = try configs.removeAllConfigsNotInRuleStopState(&mergeCache,lookToEndOfRule,atn)
|
||||
return result
|
||||
final func removeAllConfigsNotInRuleStopState(_ configs: ATNConfigSet, _ lookToEndOfRule: Bool) -> ATNConfigSet {
|
||||
return configs.removeAllConfigsNotInRuleStopState(&mergeCache,lookToEndOfRule,atn)
|
||||
}
|
||||
|
||||
|
||||
final func computeStartState(_ p: ATNState,
|
||||
_ ctx: RuleContext,
|
||||
_ fullCtx: Bool) throws -> ATNConfigSet {
|
||||
|
||||
|
||||
let initialContext: PredictionContext = PredictionContext.fromRuleContext(atn, ctx)
|
||||
let configs: ATNConfigSet = ATNConfigSet(fullCtx)
|
||||
final func computeStartState(_ p: ATNState, _ ctx: RuleContext, _ fullCtx: Bool) throws -> ATNConfigSet {
|
||||
let initialContext = PredictionContext.fromRuleContext(atn, ctx)
|
||||
let configs = ATNConfigSet(fullCtx)
|
||||
let length = p.getNumberOfTransitions()
|
||||
for i in 0..<length {
|
||||
let target: ATNState = p.transition(i).target
|
||||
let c: ATNConfig = ATNConfig(target, i + 1, initialContext)
|
||||
var closureBusy: Set<ATNConfig> = Set<ATNConfig>()
|
||||
let target = p.transition(i).target
|
||||
let c = ATNConfig(target, i + 1, initialContext)
|
||||
var closureBusy = Set<ATNConfig>()
|
||||
try closure(c, configs, &closureBusy, true, fullCtx, false)
|
||||
}
|
||||
|
||||
|
||||
return configs
|
||||
}
|
||||
|
||||
|
@ -1126,7 +1118,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
|
||||
final internal func getPredsForAmbigAlts(_ ambigAlts: BitSet,
|
||||
_ configs: ATNConfigSet,
|
||||
_ nalts: Int) throws -> [SemanticContext?]? {
|
||||
_ nalts: Int) -> [SemanticContext?]? {
|
||||
// REACH=[1|1|[]|0:0, 1|2|[]|0:1]
|
||||
///
|
||||
/// altToPred starts as an array of all null contexts. The entry at index i
|
||||
|
@ -1140,8 +1132,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
///
|
||||
/// From this, it is clear that NONE||anything==NONE.
|
||||
///
|
||||
let altToPred: [SemanticContext?]? = try configs.getPredsForAmbigAlts(ambigAlts,nalts)
|
||||
|
||||
let altToPred = configs.getPredsForAmbigAlts(ambigAlts,nalts)
|
||||
if debug {
|
||||
print("getPredsForAmbigAlts result \(String(describing: altToPred))")
|
||||
}
|
||||
|
@ -1149,17 +1140,17 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
}
|
||||
|
||||
final internal func getPredicatePredictions(_ ambigAlts: BitSet?,
|
||||
_ altToPred: [SemanticContext?]) throws -> [DFAState.PredPrediction]? {
|
||||
var pairs: Array<DFAState.PredPrediction> = Array<DFAState.PredPrediction>()
|
||||
var containsPredicate: Bool = false
|
||||
_ altToPred: [SemanticContext?]) -> [DFAState.PredPrediction]? {
|
||||
var pairs = [DFAState.PredPrediction]()
|
||||
var containsPredicate = false
|
||||
let length = altToPred.count
|
||||
for i in 1..<length {
|
||||
let pred: SemanticContext? = altToPred[i]
|
||||
let pred = altToPred[i]
|
||||
|
||||
// unpredicated is indicated by SemanticContext.NONE
|
||||
assert(pred != nil, "Expected: pred!=null")
|
||||
|
||||
if try ambigAlts != nil && ambigAlts!.get(i) {
|
||||
if let ambigAlts = ambigAlts, try! ambigAlts.get(i) {
|
||||
pairs.append(DFAState.PredPrediction(pred!, i))
|
||||
}
|
||||
if pred != SemanticContext.NONE {
|
||||
|
@ -1216,18 +1207,15 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
///
|
||||
final internal func getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(_ configs: ATNConfigSet,
|
||||
_ outerContext: ParserRuleContext) throws -> Int {
|
||||
let sets: (ATNConfigSet, ATNConfigSet) = try
|
||||
splitAccordingToSemanticValidity(configs, outerContext)
|
||||
let semValidConfigs: ATNConfigSet = sets.0
|
||||
let semInvalidConfigs: ATNConfigSet = sets.1
|
||||
var alt: Int = try getAltThatFinishedDecisionEntryRule(semValidConfigs)
|
||||
let (semValidConfigs, semInvalidConfigs) = try splitAccordingToSemanticValidity(configs, outerContext)
|
||||
var alt = getAltThatFinishedDecisionEntryRule(semValidConfigs)
|
||||
if alt != ATN.INVALID_ALT_NUMBER {
|
||||
// semantically/syntactically viable path exists
|
||||
return alt
|
||||
}
|
||||
// Is there a syntactically valid path with a failed pred?
|
||||
if semInvalidConfigs.size() > 0 {
|
||||
alt = try getAltThatFinishedDecisionEntryRule(semInvalidConfigs)
|
||||
alt = getAltThatFinishedDecisionEntryRule(semInvalidConfigs)
|
||||
if alt != ATN.INVALID_ALT_NUMBER {
|
||||
// syntactically viable path exists
|
||||
return alt
|
||||
|
@ -1236,9 +1224,9 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
return ATN.INVALID_ALT_NUMBER
|
||||
}
|
||||
|
||||
final internal func getAltThatFinishedDecisionEntryRule(_ configs: ATNConfigSet) throws -> Int {
|
||||
final internal func getAltThatFinishedDecisionEntryRule(_ configs: ATNConfigSet) -> Int {
|
||||
|
||||
return try configs.getAltThatFinishedDecisionEntryRule()
|
||||
return configs.getAltThatFinishedDecisionEntryRule()
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -1255,7 +1243,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
_ configs: ATNConfigSet,
|
||||
_ outerContext: ParserRuleContext) throws -> (ATNConfigSet, ATNConfigSet) {
|
||||
|
||||
return try configs.splitAccordingToSemanticValidity(outerContext,evalSemanticContext)
|
||||
return try configs.splitAccordingToSemanticValidity(outerContext, evalSemanticContext)
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -1268,18 +1256,18 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
final internal func evalSemanticContext(_ predPredictions: [DFAState.PredPrediction],
|
||||
_ outerContext: ParserRuleContext,
|
||||
_ complete: Bool) throws -> BitSet {
|
||||
let predictions: BitSet = BitSet()
|
||||
for pair: DFAState.PredPrediction in predPredictions {
|
||||
let predictions = BitSet()
|
||||
for pair in predPredictions {
|
||||
if pair.pred == SemanticContext.NONE {
|
||||
try predictions.set(pair.alt)
|
||||
try! predictions.set(pair.alt)
|
||||
if !complete {
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
let fullCtx: Bool = false // in dfa
|
||||
let predicateEvaluationResult: Bool = try evalSemanticContext(pair.pred, outerContext, pair.alt, fullCtx)
|
||||
let fullCtx = false // in dfa
|
||||
let predicateEvaluationResult = try evalSemanticContext(pair.pred, outerContext, pair.alt, fullCtx)
|
||||
if debug || dfa_debug {
|
||||
print("eval pred \(pair)= \(predicateEvaluationResult)")
|
||||
}
|
||||
|
@ -1288,7 +1276,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
if debug || dfa_debug {
|
||||
print("PREDICT \(pair.alt)")
|
||||
}
|
||||
try predictions.set(pair.alt)
|
||||
try! predictions.set(pair.alt)
|
||||
if !complete {
|
||||
break
|
||||
}
|
||||
|
@ -1369,7 +1357,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
for i in 0..<length {
|
||||
if configContext.getReturnState(i) == PredictionContext.EMPTY_RETURN_STATE {
|
||||
if fullCtx {
|
||||
try configs.add(ATNConfig(config, config.state, PredictionContext.EMPTY), &mergeCache)
|
||||
try! configs.add(ATNConfig(config, config.state, PredictionContext.EMPTY), &mergeCache)
|
||||
continue
|
||||
} else {
|
||||
// we have no context info, just chase follow links (if greedy)
|
||||
|
@ -1400,10 +1388,9 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
return
|
||||
} else if fullCtx {
|
||||
// reached end of start rule
|
||||
try configs.add(config,&mergeCache)
|
||||
try! configs.add(config, &mergeCache)
|
||||
return
|
||||
} else {
|
||||
// print("FALLING off rule \(getRuleName(config.state.ruleIndex!))")
|
||||
// else if we have no context info, just chase follow links (if greedy)
|
||||
if debug {
|
||||
print("FALLING off rule \(getRuleName(config.state.ruleIndex!))")
|
||||
|
@ -1429,7 +1416,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
let p = config.state
|
||||
// optimization
|
||||
if !p.onlyHasEpsilonTransitions() {
|
||||
try configs.add(config, &mergeCache)
|
||||
try! configs.add(config, &mergeCache)
|
||||
// make sure to not return here, because EOF transitions can act as
|
||||
// both epsilon transitions and non-epsilon transitions.
|
||||
// if ( debug ) print("added config "+configs);
|
||||
|
@ -1730,87 +1717,87 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
|
||||
|
||||
final func precedenceTransition(_ config: ATNConfig,
|
||||
_ pt: PrecedencePredicateTransition,
|
||||
_ collectPredicates: Bool,
|
||||
_ inContext: Bool,
|
||||
_ fullCtx: Bool) throws -> ATNConfig {
|
||||
if debug {
|
||||
print("PRED (collectPredicates=\(collectPredicates)) \(pt.precedence)>=_p, ctx dependent=true")
|
||||
//if ( parser != nil ) {
|
||||
print("context surrounding pred is \(parser.getRuleInvocationStack())")
|
||||
// }
|
||||
}
|
||||
_ pt: PrecedencePredicateTransition,
|
||||
_ collectPredicates: Bool,
|
||||
_ inContext: Bool,
|
||||
_ fullCtx: Bool) throws -> ATNConfig {
|
||||
if debug {
|
||||
print("PRED (collectPredicates=\(collectPredicates)) \(pt.precedence)>=_p, ctx dependent=true")
|
||||
//if ( parser != nil ) {
|
||||
print("context surrounding pred is \(parser.getRuleInvocationStack())")
|
||||
// }
|
||||
}
|
||||
|
||||
var c: ATNConfig? = nil
|
||||
if collectPredicates && inContext {
|
||||
if fullCtx {
|
||||
// In full context mode, we can evaluate predicates on-the-fly
|
||||
// during closure, which dramatically reduces the size of
|
||||
// the config sets. It also obviates the need to test predicates
|
||||
// later during conflict resolution.
|
||||
let currentPosition: Int = _input.index()
|
||||
try _input.seek(_startIndex)
|
||||
let predSucceeds: Bool = try evalSemanticContext(pt.getPredicate(), _outerContext, config.alt, fullCtx)
|
||||
try _input.seek(currentPosition)
|
||||
if predSucceeds {
|
||||
c = ATNConfig(config, pt.target) // no pred context
|
||||
}
|
||||
} else {
|
||||
let newSemCtx: SemanticContext =
|
||||
SemanticContext.and(config.semanticContext, pt.getPredicate())
|
||||
c = ATNConfig(config, pt.target, newSemCtx)
|
||||
var c: ATNConfig? = nil
|
||||
if collectPredicates && inContext {
|
||||
if fullCtx {
|
||||
// In full context mode, we can evaluate predicates on-the-fly
|
||||
// during closure, which dramatically reduces the size of
|
||||
// the config sets. It also obviates the need to test predicates
|
||||
// later during conflict resolution.
|
||||
let currentPosition = _input.index()
|
||||
try _input.seek(_startIndex)
|
||||
let predSucceeds = try evalSemanticContext(pt.getPredicate(), _outerContext, config.alt, fullCtx)
|
||||
try _input.seek(currentPosition)
|
||||
if predSucceeds {
|
||||
c = ATNConfig(config, pt.target) // no pred context
|
||||
}
|
||||
} else {
|
||||
c = ATNConfig(config, pt.target)
|
||||
}
|
||||
else {
|
||||
let newSemCtx = SemanticContext.and(config.semanticContext, pt.getPredicate())
|
||||
c = ATNConfig(config, pt.target, newSemCtx)
|
||||
}
|
||||
}
|
||||
else {
|
||||
c = ATNConfig(config, pt.target)
|
||||
}
|
||||
|
||||
if debug {
|
||||
print("config from pred transition=\(String(describing: c))")
|
||||
}
|
||||
return c!
|
||||
if debug {
|
||||
print("config from pred transition=\(String(describing: c))")
|
||||
}
|
||||
return c!
|
||||
}
|
||||
|
||||
|
||||
final func predTransition(_ config: ATNConfig,
|
||||
_ pt: PredicateTransition,
|
||||
_ collectPredicates: Bool,
|
||||
_ inContext: Bool,
|
||||
_ fullCtx: Bool) throws -> ATNConfig? {
|
||||
if debug {
|
||||
print("PRED (collectPredicates=\(collectPredicates)) \(pt.ruleIndex):\(pt.predIndex), ctx dependent=\(pt.isCtxDependent)")
|
||||
//if ( parser != nil ) {
|
||||
print("context surrounding pred is \(parser.getRuleInvocationStack())")
|
||||
//}
|
||||
}
|
||||
_ pt: PredicateTransition,
|
||||
_ collectPredicates: Bool,
|
||||
_ inContext: Bool,
|
||||
_ fullCtx: Bool) throws -> ATNConfig? {
|
||||
if debug {
|
||||
print("PRED (collectPredicates=\(collectPredicates)) \(pt.ruleIndex):\(pt.predIndex), ctx dependent=\(pt.isCtxDependent)")
|
||||
//if ( parser != nil ) {
|
||||
print("context surrounding pred is \(parser.getRuleInvocationStack())")
|
||||
//}
|
||||
}
|
||||
|
||||
var c: ATNConfig? = nil
|
||||
if collectPredicates &&
|
||||
(!pt.isCtxDependent || (pt.isCtxDependent && inContext)) {
|
||||
if fullCtx {
|
||||
// In full context mode, we can evaluate predicates on-the-fly
|
||||
// during closure, which dramatically reduces the size of
|
||||
// the config sets. It also obviates the need to test predicates
|
||||
// later during conflict resolution.
|
||||
let currentPosition: Int = _input.index()
|
||||
try _input.seek(_startIndex)
|
||||
let predSucceeds: Bool = try evalSemanticContext(pt.getPredicate(), _outerContext, config.alt, fullCtx)
|
||||
try _input.seek(currentPosition)
|
||||
if predSucceeds {
|
||||
c = ATNConfig(config, pt.target) // no pred context
|
||||
}
|
||||
} else {
|
||||
let newSemCtx: SemanticContext =
|
||||
SemanticContext.and(config.semanticContext, pt.getPredicate())
|
||||
c = ATNConfig(config, pt.target, newSemCtx)
|
||||
}
|
||||
var c: ATNConfig? = nil
|
||||
if collectPredicates &&
|
||||
(!pt.isCtxDependent || (pt.isCtxDependent && inContext)) {
|
||||
if fullCtx {
|
||||
// In full context mode, we can evaluate predicates on-the-fly
|
||||
// during closure, which dramatically reduces the size of
|
||||
// the config sets. It also obviates the need to test predicates
|
||||
// later during conflict resolution.
|
||||
let currentPosition = _input.index()
|
||||
try _input.seek(_startIndex)
|
||||
let predSucceeds = try evalSemanticContext(pt.getPredicate(), _outerContext, config.alt, fullCtx)
|
||||
try _input.seek(currentPosition)
|
||||
if predSucceeds {
|
||||
c = ATNConfig(config, pt.target) // no pred context
|
||||
}
|
||||
} else {
|
||||
c = ATNConfig(config, pt.target)
|
||||
let newSemCtx = SemanticContext.and(config.semanticContext, pt.getPredicate())
|
||||
c = ATNConfig(config, pt.target, newSemCtx)
|
||||
}
|
||||
} else {
|
||||
c = ATNConfig(config, pt.target)
|
||||
}
|
||||
|
||||
if debug {
|
||||
print("config from pred transition=\(String(describing: c))")
|
||||
}
|
||||
return c
|
||||
if debug {
|
||||
print("config from pred transition=\(String(describing: c))")
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
|
||||
|
@ -1833,8 +1820,8 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
/// conflicting alternative subsets. If `configs` does not contain any
|
||||
/// conflicting subsets, this method returns an empty _java.util.BitSet_.
|
||||
///
|
||||
final func getConflictingAlts(_ configs: ATNConfigSet) throws -> BitSet {
|
||||
let altsets = try PredictionMode.getConflictingAltSubsets(configs)
|
||||
final func getConflictingAlts(_ configs: ATNConfigSet) -> BitSet {
|
||||
let altsets = PredictionMode.getConflictingAltSubsets(configs)
|
||||
return PredictionMode.getAlts(altsets)
|
||||
}
|
||||
|
||||
|
@ -1874,11 +1861,11 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
/// ignore a set of conflicting alts when we have an alternative
|
||||
/// that we still need to pursue.
|
||||
///
|
||||
final func getConflictingAltsOrUniqueAlt(_ configs: ATNConfigSet) throws -> BitSet {
|
||||
final func getConflictingAltsOrUniqueAlt(_ configs: ATNConfigSet) -> BitSet {
|
||||
var conflictingAlts: BitSet
|
||||
if configs.uniqueAlt != ATN.INVALID_ALT_NUMBER {
|
||||
conflictingAlts = BitSet()
|
||||
try conflictingAlts.set(configs.uniqueAlt)
|
||||
try! conflictingAlts.set(configs.uniqueAlt)
|
||||
} else {
|
||||
conflictingAlts = configs.conflictingAlts!
|
||||
}
|
||||
|
@ -1928,13 +1915,17 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
|
||||
|
||||
final func noViableAlt(_ input: TokenStream,
|
||||
_ outerContext: ParserRuleContext,
|
||||
_ configs: ATNConfigSet,
|
||||
_ startIndex: Int) throws -> NoViableAltException {
|
||||
return try NoViableAltException(parser, input,
|
||||
input.get(startIndex),
|
||||
input.LT(1)!,
|
||||
configs, outerContext)
|
||||
_ outerContext: ParserRuleContext,
|
||||
_ configs: ATNConfigSet,
|
||||
_ startIndex: Int) -> NoViableAltException {
|
||||
let startToken = try! input.get(startIndex)
|
||||
var offendingToken: Token? = nil
|
||||
do {
|
||||
offendingToken = try input.LT(1)
|
||||
}
|
||||
catch {
|
||||
}
|
||||
return NoViableAltException(parser, input, startToken, offendingToken, configs, outerContext)
|
||||
}
|
||||
|
||||
internal static func getUniqueAlt(_ configs: ATNConfigSet) -> Int {
|
||||
|
@ -1966,7 +1957,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
final func addDFAEdge(_ dfa: DFA,
|
||||
_ from: DFAState?,
|
||||
_ t: Int,
|
||||
_ to: DFAState?) throws -> DFAState? {
|
||||
_ to: DFAState?) -> DFAState? {
|
||||
var to = to
|
||||
if debug {
|
||||
print("EDGE \(String(describing: from)) -> \(String(describing: to)) upon \(getTokenName(t))")
|
||||
|
@ -1976,7 +1967,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
return nil
|
||||
}
|
||||
|
||||
to = try addDFAState(dfa, to!) // used existing if possible not incoming
|
||||
to = addDFAState(dfa, to!) // used existing if possible not incoming
|
||||
if from == nil || t < -1 || t > atn.maxTokenType {
|
||||
return to
|
||||
}
|
||||
|
@ -2014,12 +2005,12 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
/// state if `D` is already in the DFA, or `D` itself if the
|
||||
/// state was not already present.
|
||||
///
|
||||
final func addDFAState(_ dfa: DFA, _ D: DFAState) throws -> DFAState {
|
||||
final func addDFAState(_ dfa: DFA, _ D: DFAState) -> DFAState {
|
||||
if D == ATNSimulator.ERROR {
|
||||
return D
|
||||
}
|
||||
|
||||
return try dfaStatesMutex.synchronized {
|
||||
return dfaStatesMutex.synchronized {
|
||||
if let existing = dfa.states[D] {
|
||||
return existing!
|
||||
}
|
||||
|
@ -2027,7 +2018,7 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
D.stateNumber = dfa.states.count
|
||||
|
||||
if !D.configs.isReadonly() {
|
||||
try D.configs.optimizeConfigs(self)
|
||||
try! D.configs.optimizeConfigs(self)
|
||||
D.configs.setReadonly(true)
|
||||
}
|
||||
|
||||
|
@ -2040,20 +2031,20 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
}
|
||||
}
|
||||
|
||||
func reportAttemptingFullContext(_ dfa: DFA, _ conflictingAlts: BitSet?, _ configs: ATNConfigSet, _ startIndex: Int, _ stopIndex: Int) throws {
|
||||
func reportAttemptingFullContext(_ dfa: DFA, _ conflictingAlts: BitSet?, _ configs: ATNConfigSet, _ startIndex: Int, _ stopIndex: Int) {
|
||||
if debug || retry_debug {
|
||||
let input = getTextInInterval(startIndex, stopIndex)
|
||||
print("reportAttemptingFullContext decision=\(dfa.decision):\(configs), input=\(input)")
|
||||
}
|
||||
try parser.getErrorListenerDispatch().reportAttemptingFullContext(parser, dfa, startIndex, stopIndex, conflictingAlts, configs)
|
||||
parser.getErrorListenerDispatch().reportAttemptingFullContext(parser, dfa, startIndex, stopIndex, conflictingAlts, configs)
|
||||
}
|
||||
|
||||
func reportContextSensitivity(_ dfa: DFA, _ prediction: Int, _ configs: ATNConfigSet, _ startIndex: Int, _ stopIndex: Int) throws {
|
||||
func reportContextSensitivity(_ dfa: DFA, _ prediction: Int, _ configs: ATNConfigSet, _ startIndex: Int, _ stopIndex: Int) {
|
||||
if debug || retry_debug {
|
||||
let input = getTextInInterval(startIndex, stopIndex)
|
||||
print("reportContextSensitivity decision=\(dfa.decision):\(configs), input=\(input)")
|
||||
}
|
||||
try parser.getErrorListenerDispatch().reportContextSensitivity(parser, dfa, startIndex, stopIndex, prediction, configs)
|
||||
parser.getErrorListenerDispatch().reportContextSensitivity(parser, dfa, startIndex, stopIndex, prediction, configs)
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -2065,13 +2056,13 @@ open class ParserATNSimulator: ATNSimulator {
|
|||
_ startIndex: Int, _ stopIndex: Int,
|
||||
_ exact: Bool,
|
||||
_ ambigAlts: BitSet,
|
||||
_ configs: ATNConfigSet) throws
|
||||
_ configs: ATNConfigSet)
|
||||
{
|
||||
if debug || retry_debug {
|
||||
let input = getTextInInterval(startIndex, stopIndex)
|
||||
print("reportAmbiguity \(ambigAlts):\(configs), input=\(input)")
|
||||
}
|
||||
try parser.getErrorListenerDispatch().reportAmbiguity(parser, dfa, startIndex, stopIndex,
|
||||
parser.getErrorListenerDispatch().reportAmbiguity(parser, dfa, startIndex, stopIndex,
|
||||
exact, ambigAlts, configs)
|
||||
}
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ public enum PredictionMode {
|
|||
/// the configurations to strip out all of the predicates so that a standard
|
||||
/// _org.antlr.v4.runtime.atn.ATNConfigSet_ will merge everything ignoring predicates.
|
||||
///
|
||||
public static func hasSLLConflictTerminatingPrediction(_ mode: PredictionMode,_ configs: ATNConfigSet) throws -> Bool {
|
||||
public static func hasSLLConflictTerminatingPrediction(_ mode: PredictionMode,_ configs: ATNConfigSet) -> Bool {
|
||||
var configs = configs
|
||||
///
|
||||
/// Configs in rule stop states indicate reaching the end of the decision
|
||||
|
@ -183,17 +183,16 @@ public enum PredictionMode {
|
|||
// since we'll often fail over anyway.
|
||||
if configs.hasSemanticContext {
|
||||
// dup configs, tossing out semantic predicates
|
||||
configs = try configs.dupConfigsWithoutSemanticPredicates()
|
||||
configs = configs.dupConfigsWithoutSemanticPredicates()
|
||||
}
|
||||
// now we have combined contexts for configs with dissimilar preds
|
||||
}
|
||||
|
||||
// pure SLL or combined SLL+LL mode parsing
|
||||
|
||||
let altsets: Array<BitSet> = try getConflictingAltSubsets(configs)
|
||||
let altsets = getConflictingAltSubsets(configs)
|
||||
|
||||
let heuristic: Bool =
|
||||
try hasConflictingAltSet(altsets) && !hasStateAssociatedWithOneAlt(configs)
|
||||
let heuristic = hasConflictingAltSet(altsets) && !hasStateAssociatedWithOneAlt(configs)
|
||||
return heuristic
|
||||
}
|
||||
|
||||
|
@ -364,8 +363,8 @@ public enum PredictionMode {
|
|||
/// we need exact ambiguity detection when the sets look like
|
||||
/// `A={{1,2`}} or `{{1,2`,{1,2}}}, etc...
|
||||
///
|
||||
public static func resolvesToJustOneViableAlt(_ altsets: Array<BitSet>) throws -> Int {
|
||||
return try getSingleViableAlt(altsets)
|
||||
public static func resolvesToJustOneViableAlt(_ altsets: [BitSet]) -> Int {
|
||||
return getSingleViableAlt(altsets)
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -440,10 +439,10 @@ public enum PredictionMode {
|
|||
///
|
||||
/// - parameter altsets: a collection of alternative subsets
|
||||
///
|
||||
public static func getUniqueAlt(_ altsets: Array<BitSet>) throws -> Int {
|
||||
public static func getUniqueAlt(_ altsets: [BitSet]) -> Int {
|
||||
let all: BitSet = getAlts(altsets)
|
||||
if all.cardinality() == 1 {
|
||||
return try all.nextSetBit(0)
|
||||
return all.firstSetBit()
|
||||
}
|
||||
return ATN.INVALID_ALT_NUMBER
|
||||
}
|
||||
|
@ -467,9 +466,8 @@ public enum PredictionMode {
|
|||
///
|
||||
/// Get union of all alts from configs. - Since: 4.5.1
|
||||
///
|
||||
public static func getAlts(_ configs: ATNConfigSet) throws -> BitSet {
|
||||
|
||||
return try configs.getAltBitSet()
|
||||
public static func getAlts(_ configs: ATNConfigSet) -> BitSet {
|
||||
return configs.getAltBitSet()
|
||||
|
||||
}
|
||||
|
||||
|
@ -483,9 +481,8 @@ public enum PredictionMode {
|
|||
///
|
||||
///
|
||||
|
||||
public static func getConflictingAltSubsets(_ configs: ATNConfigSet) throws -> Array<BitSet> {
|
||||
|
||||
return try configs.getConflictingAltSubsets()
|
||||
public static func getConflictingAltSubsets(_ configs: ATNConfigSet) -> [BitSet] {
|
||||
return configs.getConflictingAltSubsets()
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -496,16 +493,13 @@ public enum PredictionMode {
|
|||
/// map[c._org.antlr.v4.runtime.atn.ATNConfig#state state_] U= c._org.antlr.v4.runtime.atn.ATNConfig#alt alt_
|
||||
///
|
||||
///
|
||||
public static func getStateToAltMap(_ configs: ATNConfigSet) throws -> HashMap<ATNState, BitSet> {
|
||||
|
||||
return try configs.getStateToAltMap()
|
||||
public static func getStateToAltMap(_ configs: ATNConfigSet) -> HashMap<ATNState, BitSet> {
|
||||
return configs.getStateToAltMap()
|
||||
}
|
||||
|
||||
public static func hasStateAssociatedWithOneAlt(_ configs: ATNConfigSet) throws -> Bool {
|
||||
let x: HashMap<ATNState, BitSet> = try getStateToAltMap(configs)
|
||||
let values = x.values
|
||||
for alts: BitSet in values {
|
||||
|
||||
public static func hasStateAssociatedWithOneAlt(_ configs: ATNConfigSet) -> Bool {
|
||||
let x = getStateToAltMap(configs)
|
||||
for alts in x.values {
|
||||
if alts.cardinality() == 1 {
|
||||
return true
|
||||
}
|
||||
|
@ -513,17 +507,17 @@ public enum PredictionMode {
|
|||
return false
|
||||
}
|
||||
|
||||
public static func getSingleViableAlt(_ altsets: Array<BitSet>) throws -> Int {
|
||||
let viableAlts: BitSet = BitSet()
|
||||
for alts: BitSet in altsets {
|
||||
let minAlt: Int = try alts.nextSetBit(0)
|
||||
try viableAlts.set(minAlt)
|
||||
public static func getSingleViableAlt(_ altsets: [BitSet]) -> Int {
|
||||
let viableAlts = BitSet()
|
||||
for alts in altsets {
|
||||
let minAlt = alts.firstSetBit()
|
||||
try! viableAlts.set(minAlt)
|
||||
if viableAlts.cardinality() > 1 {
|
||||
// more than 1 viable alt
|
||||
return ATN.INVALID_ALT_NUMBER
|
||||
}
|
||||
}
|
||||
return try viableAlts.nextSetBit(0)
|
||||
return viableAlts.firstSetBit()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ public class ProfilingATNSimulator: ParserATNSimulator {
|
|||
let fullContext = _llStopIndex >= 0
|
||||
let stopIndex = fullContext ? _llStopIndex : _sllStopIndex
|
||||
decisions[currentDecision].predicateEvals.append(
|
||||
PredicateEvalInfo(currentDecision, _input, _startIndex, stopIndex, pred, result, alt, fullCtx)
|
||||
PredicateEvalInfo(currentDecision, _input, _startIndex, stopIndex, pred, result, alt, fullCtx)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -165,34 +165,36 @@ public class ProfilingATNSimulator: ParserATNSimulator {
|
|||
}
|
||||
|
||||
override
|
||||
internal func reportAttemptingFullContext(_ dfa: DFA, _ conflictingAlts: BitSet?, _ configs: ATNConfigSet, _ startIndex: Int, _ stopIndex: Int) throws {
|
||||
internal func reportAttemptingFullContext(_ dfa: DFA, _ conflictingAlts: BitSet?, _ configs: ATNConfigSet, _ startIndex: Int, _ stopIndex: Int) {
|
||||
if let conflictingAlts = conflictingAlts {
|
||||
conflictingAltResolvedBySLL = try conflictingAlts.nextSetBit(0)
|
||||
conflictingAltResolvedBySLL = conflictingAlts.firstSetBit()
|
||||
} else {
|
||||
conflictingAltResolvedBySLL = try configs.getAlts().nextSetBit(0)
|
||||
let configAlts = configs.getAlts()
|
||||
conflictingAltResolvedBySLL = configAlts.firstSetBit()
|
||||
}
|
||||
decisions[currentDecision].LL_Fallback += 1
|
||||
try super.reportAttemptingFullContext(dfa, conflictingAlts, configs, startIndex, stopIndex)
|
||||
super.reportAttemptingFullContext(dfa, conflictingAlts, configs, startIndex, stopIndex)
|
||||
}
|
||||
|
||||
override
|
||||
internal func reportContextSensitivity(_ dfa: DFA, _ prediction: Int, _ configs: ATNConfigSet, _ startIndex: Int, _ stopIndex: Int) throws {
|
||||
internal func reportContextSensitivity(_ dfa: DFA, _ prediction: Int, _ configs: ATNConfigSet, _ startIndex: Int, _ stopIndex: Int) {
|
||||
if prediction != conflictingAltResolvedBySLL {
|
||||
decisions[currentDecision].contextSensitivities.append(
|
||||
ContextSensitivityInfo(currentDecision, configs, _input, startIndex, stopIndex)
|
||||
)
|
||||
}
|
||||
try super.reportContextSensitivity(dfa, prediction, configs, startIndex, stopIndex)
|
||||
super.reportContextSensitivity(dfa, prediction, configs, startIndex, stopIndex)
|
||||
}
|
||||
|
||||
override
|
||||
internal func reportAmbiguity(_ dfa: DFA, _ D: DFAState, _ startIndex: Int, _ stopIndex: Int, _ exact: Bool,
|
||||
_ ambigAlts: BitSet?, _ configs: ATNConfigSet) throws {
|
||||
_ ambigAlts: BitSet?, _ configs: ATNConfigSet) {
|
||||
var prediction: Int
|
||||
if let ambigAlts = ambigAlts {
|
||||
prediction = try ambigAlts.nextSetBit(0)
|
||||
prediction = ambigAlts.firstSetBit()
|
||||
} else {
|
||||
prediction = try configs.getAlts().nextSetBit(0)
|
||||
let configAlts = configs.getAlts()
|
||||
prediction = configAlts.firstSetBit()
|
||||
}
|
||||
if configs.fullCtx && prediction != conflictingAltResolvedBySLL {
|
||||
// Even though this is an ambiguity we are reporting, we can
|
||||
|
@ -208,7 +210,7 @@ public class ProfilingATNSimulator: ParserATNSimulator {
|
|||
AmbiguityInfo(currentDecision, configs, ambigAlts!,
|
||||
_input, startIndex, stopIndex, configs.fullCtx)
|
||||
)
|
||||
try super.reportAmbiguity(dfa, D, startIndex, stopIndex, exact, ambigAlts!, configs)
|
||||
super.reportAmbiguity(dfa, D, startIndex, stopIndex, exact, ambigAlts!, configs)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,9 +22,8 @@ public final class RangeTransition: Transition, CustomStringConvertible {
|
|||
}
|
||||
|
||||
override
|
||||
//old label()
|
||||
public func labelIntervalSet() throws -> IntervalSet {
|
||||
return try IntervalSet.of(from, to)
|
||||
public func labelIntervalSet() -> IntervalSet? {
|
||||
return IntervalSet.of(from, to)
|
||||
}
|
||||
|
||||
override
|
||||
|
|
|
@ -125,12 +125,12 @@ public class SemanticContext: Hashable, CustomStringConvertible {
|
|||
|
||||
override
|
||||
public func eval<T>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> Bool {
|
||||
return try parser.precpred(parserCallStack, precedence)
|
||||
return parser.precpred(parserCallStack, precedence)
|
||||
}
|
||||
|
||||
override
|
||||
public func evalPrecedence<T>(_ parser: Recognizer<T>, _ parserCallStack: RuleContext) throws -> SemanticContext? {
|
||||
if try parser.precpred(parserCallStack, precedence) {
|
||||
if parser.precpred(parserCallStack, precedence) {
|
||||
return SemanticContext.NONE
|
||||
} else {
|
||||
return nil
|
||||
|
|
|
@ -26,10 +26,7 @@ public class SetTransition: Transition, CustomStringConvertible {
|
|||
}
|
||||
|
||||
override
|
||||
///
|
||||
/// /old label()
|
||||
///
|
||||
public func labelIntervalSet() -> IntervalSet {
|
||||
public func labelIntervalSet() -> IntervalSet? {
|
||||
return set
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ public class Transition {
|
|||
}
|
||||
|
||||
|
||||
public func labelIntervalSet() throws -> IntervalSet? {
|
||||
public func labelIntervalSet() -> IntervalSet? {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -592,7 +592,14 @@ public class BitSet: Hashable, CustomStringConvertible {
|
|||
return result
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
/// Equivalent to nextSetBit(0), but guaranteed not to throw an exception.
|
||||
///
|
||||
public func firstSetBit() -> Int {
|
||||
return try! nextSetBit(0)
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns the index of the first bit that is set to `true`
|
||||
/// that occurs on or after the specified starting index. If no such
|
||||
/// bit exists then `-1` is returned.
|
||||
|
@ -601,7 +608,7 @@ public class BitSet: Hashable, CustomStringConvertible {
|
|||
/// use the following loop:
|
||||
///
|
||||
/// `
|
||||
/// for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
|
||||
/// for (int i = bs.firstSetBit(); i >= 0; i = bs.nextSetBit(i+1)) {
|
||||
/// // operate on index i here
|
||||
/// `}
|
||||
///
|
||||
|
@ -1114,24 +1121,20 @@ public class BitSet: Hashable, CustomStringConvertible {
|
|||
|
||||
//let numBits: Int = (wordsInUse > 128) ?
|
||||
// cardinality() : wordsInUse * BitSet.BITS_PER_WORD
|
||||
let b: StringBuilder = StringBuilder()
|
||||
let b = StringBuilder()
|
||||
b.append("{")
|
||||
do {
|
||||
var i: Int = try nextSetBit(0)
|
||||
if i != -1 {
|
||||
b.append(i)
|
||||
i = try nextSetBit(i + 1)
|
||||
while i >= 0 {
|
||||
let endOfRun: Int = try nextClearBit(i)
|
||||
repeat {
|
||||
b.append(", ").append(i)
|
||||
i += 1
|
||||
} while i < endOfRun
|
||||
i = try nextSetBit(i + 1)
|
||||
}
|
||||
var i = firstSetBit()
|
||||
if i != -1 {
|
||||
b.append(i)
|
||||
i = try! nextSetBit(i + 1)
|
||||
while i >= 0 {
|
||||
let endOfRun = try! nextClearBit(i)
|
||||
repeat {
|
||||
b.append(", ").append(i)
|
||||
i += 1
|
||||
} while i < endOfRun
|
||||
i = try! nextSetBit(i + 1)
|
||||
}
|
||||
} catch {
|
||||
print("BitSet description error")
|
||||
}
|
||||
b.append("}")
|
||||
return b.toString()
|
||||
|
|
|
@ -43,7 +43,7 @@ public protocol IntSet {
|
|||
/// current set and `a`. The value `null` may be returned in
|
||||
/// place of an empty result set.
|
||||
///
|
||||
func and(_ a: IntSet?) throws -> IntSet?
|
||||
func and(_ a: IntSet?) -> IntSet?
|
||||
|
||||
///
|
||||
/// Return a new _org.antlr.v4.runtime.misc.IntSet_ object containing all elements that are
|
||||
|
@ -60,7 +60,7 @@ public protocol IntSet {
|
|||
/// `elements` but not present in the current set. The value
|
||||
/// `null` may be returned in place of an empty result set.
|
||||
///
|
||||
func complement(_ elements: IntSet?) throws -> IntSet?
|
||||
func complement(_ elements: IntSet?) -> IntSet?
|
||||
|
||||
///
|
||||
/// Return a new _org.antlr.v4.runtime.misc.IntSet_ object containing all elements that are
|
||||
|
@ -76,7 +76,7 @@ public protocol IntSet {
|
|||
/// set and `a`. The value `null` may be returned in place of an
|
||||
/// empty result set.
|
||||
///
|
||||
func or(_ a: IntSet) throws -> IntSet
|
||||
func or(_ a: IntSet) -> IntSet
|
||||
|
||||
///
|
||||
/// Return a new _org.antlr.v4.runtime.misc.IntSet_ object containing all elements that are
|
||||
|
@ -93,7 +93,7 @@ public protocol IntSet {
|
|||
/// `elements` but not present in the current set. The value
|
||||
/// `null` may be returned in place of an empty result set.
|
||||
///
|
||||
func subtract(_ a: IntSet?) throws -> IntSet
|
||||
func subtract(_ a: IntSet?) -> IntSet
|
||||
|
||||
///
|
||||
/// Return the total number of elements represented by the current set.
|
||||
|
@ -145,7 +145,7 @@ public protocol IntSet {
|
|||
/// - returns: A list containing all element present in the current set, sorted
|
||||
/// in ascending numerical order.
|
||||
///
|
||||
func toList() -> Array<Int>
|
||||
func toList() -> [Int]
|
||||
|
||||
func toString() -> String
|
||||
}
|
||||
|
|
|
@ -21,13 +21,13 @@
|
|||
public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
||||
public static let COMPLETE_CHAR_SET: IntervalSet =
|
||||
{
|
||||
let set = try! IntervalSet.of(Lexer.MIN_CHAR_VALUE, Lexer.MAX_CHAR_VALUE)
|
||||
let set = IntervalSet.of(Lexer.MIN_CHAR_VALUE, Lexer.MAX_CHAR_VALUE)
|
||||
try! set.setReadonly(true)
|
||||
return set
|
||||
}()
|
||||
|
||||
public static let EMPTY_SET: IntervalSet = {
|
||||
let set = try! IntervalSet()
|
||||
let set = IntervalSet()
|
||||
try! set.setReadonly(true)
|
||||
return set
|
||||
}()
|
||||
|
@ -36,47 +36,36 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
///
|
||||
/// The list of sorted, disjoint intervals.
|
||||
///
|
||||
internal var intervals: Array<Interval>
|
||||
internal var intervals: [Interval]
|
||||
|
||||
internal var readonly: Bool = false
|
||||
|
||||
public init(_ intervals: Array<Interval>) {
|
||||
internal var readonly = false
|
||||
|
||||
public init(_ intervals: [Interval]) {
|
||||
self.intervals = intervals
|
||||
}
|
||||
|
||||
public convenience init(_ set: IntervalSet) throws {
|
||||
try self.init()
|
||||
try addAll(set)
|
||||
public convenience init(_ set: IntervalSet) {
|
||||
self.init()
|
||||
try! addAll(set)
|
||||
}
|
||||
|
||||
public init(_ els: Int...) throws {
|
||||
public init(_ els: Int...) {
|
||||
if els.isEmpty {
|
||||
intervals = [Interval]() // most sets are 1 or 2 elements
|
||||
} else {
|
||||
intervals = [Interval]()
|
||||
for e in els {
|
||||
try add(e)
|
||||
try! add(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Create a set with a single element, el.
|
||||
///
|
||||
|
||||
public static func of(_ a: Int) throws -> IntervalSet {
|
||||
let s: IntervalSet = try IntervalSet()
|
||||
try s.add(a)
|
||||
return s
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
/// Create a set with all ints within range [a..b] (inclusive)
|
||||
///
|
||||
public static func of(_ a: Int, _ b: Int) throws -> IntervalSet {
|
||||
let s: IntervalSet = try IntervalSet()
|
||||
try s.add(a, b)
|
||||
public static func of(_ a: Int, _ b: Int) -> IntervalSet {
|
||||
let s = IntervalSet()
|
||||
try! s.add(a, b)
|
||||
return s
|
||||
}
|
||||
|
||||
|
@ -96,7 +85,7 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
if readonly {
|
||||
throw ANTLRError.illegalState(msg: "can't alter readonly IntervalSet")
|
||||
}
|
||||
try add(el, el)
|
||||
try! add(el, el)
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -126,21 +115,20 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
|
||||
while i < intervals.count {
|
||||
|
||||
let r: Interval = intervals[i]
|
||||
let r = intervals[i]
|
||||
if addition == r {
|
||||
return
|
||||
}
|
||||
if addition.adjacent(r) || !addition.disjoint(r) {
|
||||
// next to each other, make a single larger interval
|
||||
let bigger: Interval = addition.union(r)
|
||||
let bigger = addition.union(r)
|
||||
//iter.set(bigger);
|
||||
intervals[i] = bigger
|
||||
// make sure we didn't just create an interval that
|
||||
// should be merged with next interval in list
|
||||
//while iter.hasNext() {
|
||||
while i < intervals.count - 1 {
|
||||
i += 1
|
||||
let next: Interval = intervals[i] //iter.next();
|
||||
let next = intervals[i]
|
||||
if !bigger.adjacent(next) && bigger.disjoint(next) {
|
||||
break
|
||||
}
|
||||
|
@ -155,14 +143,11 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
intervals.remove(at: i)
|
||||
i -= 1
|
||||
intervals[i] = bigger.union(next)
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
if addition.startsBeforeDisjoint(r) {
|
||||
// insert before r
|
||||
//iter.previous();
|
||||
//iter.add(addition);
|
||||
intervals.insert(addition, at: i)
|
||||
return
|
||||
}
|
||||
|
@ -178,10 +163,10 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
///
|
||||
/// combine all sets in the array returned the or'd value
|
||||
///
|
||||
public func or(_ sets: [IntervalSet]) throws -> IntSet {
|
||||
let r: IntervalSet = try IntervalSet()
|
||||
for s: IntervalSet in sets {
|
||||
try r.addAll(s)
|
||||
public func or(_ sets: [IntervalSet]) -> IntSet {
|
||||
let r = IntervalSet()
|
||||
for s in sets {
|
||||
try! r.addAll(s)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
@ -194,14 +179,12 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
}
|
||||
if let other = set as? IntervalSet {
|
||||
// walk set and add each interval
|
||||
let n: Int = other.intervals.count
|
||||
for i in 0..<n {
|
||||
let I: Interval = other.intervals[i]
|
||||
try self.add(I.a, I.b)
|
||||
for interval in other.intervals {
|
||||
try add(interval)
|
||||
}
|
||||
} else {
|
||||
let setList = set.toList()
|
||||
for value: Int in setList {
|
||||
for value in setList {
|
||||
try add(value)
|
||||
}
|
||||
}
|
||||
|
@ -209,41 +192,41 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
return self
|
||||
}
|
||||
|
||||
public func complement(_ minElement: Int, _ maxElement: Int) throws -> IntSet? {
|
||||
return try self.complement(IntervalSet.of(minElement, maxElement))
|
||||
public func complement(_ minElement: Int, _ maxElement: Int) -> IntSet? {
|
||||
return complement(IntervalSet.of(minElement, maxElement))
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
|
||||
public func complement(_ vocabulary: IntSet?) throws -> IntSet? {
|
||||
guard let vocabulary = vocabulary , !vocabulary.isNil() else {
|
||||
public func complement(_ vocabulary: IntSet?) -> IntSet? {
|
||||
guard let vocabulary = vocabulary, !vocabulary.isNil() else {
|
||||
return nil // nothing in common with null set
|
||||
}
|
||||
var vocabularyIS: IntervalSet
|
||||
if let vocabulary = vocabulary as? IntervalSet {
|
||||
vocabularyIS = vocabulary
|
||||
} else {
|
||||
vocabularyIS = try IntervalSet()
|
||||
try vocabularyIS.addAll(vocabulary)
|
||||
vocabularyIS = IntervalSet()
|
||||
try! vocabularyIS.addAll(vocabulary)
|
||||
}
|
||||
|
||||
return try vocabularyIS.subtract(self)
|
||||
return vocabularyIS.subtract(self)
|
||||
}
|
||||
|
||||
|
||||
public func subtract(_ a: IntSet?) throws -> IntSet {
|
||||
guard let a = a , !a.isNil() else {
|
||||
return try IntervalSet(self)
|
||||
public func subtract(_ a: IntSet?) -> IntSet {
|
||||
guard let a = a, !a.isNil() else {
|
||||
return IntervalSet(self)
|
||||
}
|
||||
if let a = a as? IntervalSet {
|
||||
return try subtract(self, a)
|
||||
return subtract(self, a)
|
||||
}
|
||||
|
||||
let other: IntervalSet = try IntervalSet()
|
||||
try other.addAll(a)
|
||||
return try subtract(self, other)
|
||||
let other = IntervalSet()
|
||||
try! other.addAll(a)
|
||||
return subtract(self, other)
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -252,23 +235,23 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
/// `null`, it is treated as though it was an empty set.
|
||||
///
|
||||
|
||||
public func subtract(_ left: IntervalSet?, _ right: IntervalSet?) throws -> IntervalSet {
|
||||
public func subtract(_ left: IntervalSet?, _ right: IntervalSet?) -> IntervalSet {
|
||||
|
||||
guard let left = left , !left.isNil() else {
|
||||
return try IntervalSet()
|
||||
guard let left = left, !left.isNil() else {
|
||||
return IntervalSet()
|
||||
}
|
||||
|
||||
let result: IntervalSet = try IntervalSet(left)
|
||||
let result = IntervalSet(left)
|
||||
|
||||
guard let right = right , !right.isNil() else {
|
||||
guard let right = right, !right.isNil() else {
|
||||
// right set has no elements; just return the copy of the current set
|
||||
return result
|
||||
}
|
||||
var resultI: Int = 0
|
||||
var rightI: Int = 0
|
||||
var resultI = 0
|
||||
var rightI = 0
|
||||
while resultI < result.intervals.count && rightI < right.intervals.count {
|
||||
let resultInterval: Interval = result.intervals[resultI]
|
||||
let rightInterval: Interval = right.intervals[rightI]
|
||||
let resultInterval = result.intervals[resultI]
|
||||
let rightInterval = right.intervals[rightI]
|
||||
|
||||
// operation: (resultInterval - rightInterval) and update indexes
|
||||
|
||||
|
@ -296,9 +279,7 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
if let afterCurrent = afterCurrent {
|
||||
// split the current interval into two
|
||||
result.intervals[resultI] = beforeCurrent
|
||||
//result.intervals.set(beforeCurrent,resultI);
|
||||
result.intervals.insert(afterCurrent, at: resultI + 1)
|
||||
//result.intervals.add(, afterCurrent);
|
||||
resultI += 1
|
||||
rightI += 1
|
||||
continue
|
||||
|
@ -330,10 +311,10 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
}
|
||||
|
||||
|
||||
public func or(_ a: IntSet) throws -> IntSet {
|
||||
let o: IntervalSet = try IntervalSet()
|
||||
try o.addAll(self)
|
||||
try o.addAll(a)
|
||||
public func or(_ a: IntSet) -> IntSet {
|
||||
let o = IntervalSet()
|
||||
try! o.addAll(self)
|
||||
try! o.addAll(a)
|
||||
return o
|
||||
}
|
||||
|
||||
|
@ -341,24 +322,23 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
///
|
||||
///
|
||||
|
||||
public func and(_ other: IntSet?) throws -> IntSet? {
|
||||
public func and(_ other: IntSet?) -> IntSet? {
|
||||
if other == nil {
|
||||
//|| !(other instanceof IntervalSet) ) {
|
||||
return nil // nothing in common with null set
|
||||
}
|
||||
|
||||
var myIntervals: Array<Interval> = self.intervals
|
||||
var theirIntervals: Array<Interval> = (other as! IntervalSet).intervals
|
||||
var myIntervals = self.intervals
|
||||
var theirIntervals = (other as! IntervalSet).intervals
|
||||
var intersection: IntervalSet? = nil
|
||||
let mySize: Int = myIntervals.count
|
||||
let theirSize: Int = theirIntervals.count
|
||||
var i: Int = 0
|
||||
var j: Int = 0
|
||||
let mySize = myIntervals.count
|
||||
let theirSize = theirIntervals.count
|
||||
var i = 0
|
||||
var j = 0
|
||||
// iterate down both interval lists looking for nondisjoint intervals
|
||||
while i < mySize && j < theirSize {
|
||||
let mine: Interval = myIntervals[i]
|
||||
let theirs: Interval = theirIntervals[j]
|
||||
//System.out.println("mine="+mine+" and theirs="+theirs);
|
||||
let mine = myIntervals[i]
|
||||
let theirs = theirIntervals[j]
|
||||
|
||||
if mine.startsBeforeDisjoint(theirs) {
|
||||
// move this iterator looking for interval that might overlap
|
||||
i += 1
|
||||
|
@ -370,26 +350,26 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
if mine.properlyContains(theirs) {
|
||||
// overlap, add intersection, get next theirs
|
||||
if intersection == nil {
|
||||
intersection = try IntervalSet()
|
||||
intersection = IntervalSet()
|
||||
}
|
||||
|
||||
try intersection!.add(mine.intersection(theirs))
|
||||
try! intersection!.add(mine.intersection(theirs))
|
||||
j += 1
|
||||
} else {
|
||||
if theirs.properlyContains(mine) {
|
||||
// overlap, add intersection, get next mine
|
||||
if intersection == nil {
|
||||
intersection = try IntervalSet()
|
||||
intersection = IntervalSet()
|
||||
}
|
||||
try intersection!.add(mine.intersection(theirs))
|
||||
try! intersection!.add(mine.intersection(theirs))
|
||||
i += 1
|
||||
} else {
|
||||
if !mine.disjoint(theirs) {
|
||||
// overlap, add intersection
|
||||
if intersection == nil {
|
||||
intersection = try IntervalSet()
|
||||
intersection = IntervalSet()
|
||||
}
|
||||
try intersection!.add(mine.intersection(theirs))
|
||||
try! intersection!.add(mine.intersection(theirs))
|
||||
// Move the iterator of lower range [a..b], but not
|
||||
// the upper range as it may contain elements that will collide
|
||||
// with the next iterator. So, if mine=[0..115] and
|
||||
|
@ -411,7 +391,7 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
}
|
||||
}
|
||||
if intersection == nil {
|
||||
return try IntervalSet()
|
||||
return IntervalSet()
|
||||
}
|
||||
return intersection
|
||||
}
|
||||
|
@ -421,11 +401,9 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
///
|
||||
|
||||
public func contains(_ el: Int) -> Bool {
|
||||
let n: Int = intervals.count
|
||||
for i in 0..<n {
|
||||
let I: Interval = intervals[i]
|
||||
let a: Int = I.a
|
||||
let b: Int = I.b
|
||||
for interval in intervals {
|
||||
let a = interval.a
|
||||
let b = interval.b
|
||||
if el < a {
|
||||
break // list is sorted and el is before this interval; not here
|
||||
}
|
||||
|
@ -434,18 +412,6 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
}
|
||||
}
|
||||
return false
|
||||
///
|
||||
/// for (ListIterator iter = intervals.listIterator(); iter.hasNext();) {
|
||||
/// Interval I = (Interval) iter.next();
|
||||
/// if ( el<I.a ) {
|
||||
/// break; // list is sorted and el is before this interval; not here
|
||||
/// }
|
||||
/// if ( el>=I.a && el<=I.b ) {
|
||||
/// return true; // found in this interval
|
||||
/// }
|
||||
/// }
|
||||
/// return false;
|
||||
///
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -461,11 +427,10 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
///
|
||||
|
||||
public func getSingleElement() -> Int {
|
||||
//intervals=nil && intervals.count==1 )
|
||||
if intervals.count == 1 {
|
||||
let I: Interval = intervals[0]
|
||||
if I.a == I.b {
|
||||
return I.a
|
||||
let interval = intervals[0]
|
||||
if interval.a == interval.b {
|
||||
return interval.a
|
||||
}
|
||||
}
|
||||
return CommonToken.INVALID_TYPE
|
||||
|
@ -481,7 +446,7 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
if isNil() {
|
||||
return CommonToken.INVALID_TYPE
|
||||
}
|
||||
let last: Interval = intervals[intervals.count - 1]
|
||||
let last = intervals[intervals.count - 1]
|
||||
return last.b
|
||||
}
|
||||
|
||||
|
@ -502,7 +467,7 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
///
|
||||
/// Return a list of Interval objects.
|
||||
///
|
||||
public func getIntervals() -> Array<Interval> {
|
||||
public func getIntervals() -> [Interval] {
|
||||
return intervals
|
||||
}
|
||||
|
||||
|
@ -549,25 +514,21 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
}
|
||||
|
||||
public func toString(_ elemAreChar: Bool) -> String {
|
||||
let buf: StringBuilder = StringBuilder()
|
||||
//if ( self.intervals==nil || self.intervals.isEmpty() ) {
|
||||
let buf = StringBuilder()
|
||||
if self.intervals.isEmpty {
|
||||
return "{}"
|
||||
}
|
||||
if self.size() > 1 {
|
||||
buf.append("{")
|
||||
}
|
||||
//var iter : Iterator<Interval> = self.intervals.iterator();
|
||||
//while iter.hasNext() {
|
||||
var first = true
|
||||
for I: Interval in intervals {
|
||||
for interval in intervals {
|
||||
if !first {
|
||||
buf.append(", ")
|
||||
}
|
||||
first = false
|
||||
//var I : Interval = iter.next();
|
||||
let a: Int = I.a
|
||||
let b: Int = I.b
|
||||
let a = interval.a
|
||||
let b = interval.b
|
||||
if a == b {
|
||||
if a == CommonToken.EOF {
|
||||
buf.append("<EOF>")
|
||||
|
@ -585,9 +546,6 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
buf.append(a).append("..").append(b)
|
||||
}
|
||||
}
|
||||
//if ( iter.hasNext() ) {
|
||||
// buf.append(", ");
|
||||
//}
|
||||
}
|
||||
if self.size() > 1 {
|
||||
buf.append("}")
|
||||
|
@ -646,43 +604,25 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
|
||||
|
||||
public func size() -> Int {
|
||||
var n: Int = 0
|
||||
let numIntervals: Int = intervals.count
|
||||
var n = 0
|
||||
let numIntervals = intervals.count
|
||||
if numIntervals == 1 {
|
||||
let firstInterval: Interval = self.intervals[0]
|
||||
let firstInterval = intervals[0]
|
||||
return firstInterval.b - firstInterval.a + 1
|
||||
}
|
||||
for i in 0..<numIntervals {
|
||||
let I: Interval = intervals[i]
|
||||
n += (I.b - I.a + 1)
|
||||
let interval = intervals[i]
|
||||
n += (interval.b - interval.a + 1)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
||||
public func toIntegerList() -> Array<Int> {
|
||||
var values: Array<Int> = Array<Int>()
|
||||
let n: Int = intervals.count
|
||||
for i in 0..<n {
|
||||
let I: Interval = intervals[i]
|
||||
let a: Int = I.a
|
||||
let b: Int = I.b
|
||||
|
||||
for v in a...b {
|
||||
values.append(v)
|
||||
}
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
|
||||
public func toList() -> Array<Int> {
|
||||
var values: Array<Int> = Array<Int>()
|
||||
let n: Int = intervals.count
|
||||
for i in 0..<n {
|
||||
let I: Interval = intervals[i]
|
||||
let a: Int = I.a
|
||||
let b: Int = I.b
|
||||
public func toList() -> [Int] {
|
||||
var values = [Int]()
|
||||
for interval in intervals {
|
||||
let a = interval.a
|
||||
let b = interval.b
|
||||
|
||||
for v in a...b {
|
||||
values.append(v)
|
||||
|
@ -692,13 +632,12 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
}
|
||||
|
||||
public func toSet() -> Set<Int> {
|
||||
var s: Set<Int> = Set<Int>()
|
||||
for I: Interval in intervals {
|
||||
let a: Int = I.a
|
||||
let b: Int = I.b
|
||||
var s = Set<Int>()
|
||||
for interval in intervals {
|
||||
let a = interval.a
|
||||
let b = interval.b
|
||||
for v in a...b {
|
||||
s.insert(v)
|
||||
//s.add(v);
|
||||
}
|
||||
}
|
||||
return s
|
||||
|
@ -710,12 +649,10 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
/// ANTLR code gen target.
|
||||
///
|
||||
public func get(_ i: Int) -> Int {
|
||||
let n: Int = intervals.count
|
||||
var index: Int = 0
|
||||
for j in 0..<n {
|
||||
let I: Interval = intervals[j]
|
||||
let a: Int = I.a
|
||||
let b: Int = I.b
|
||||
var index = 0
|
||||
for interval in intervals {
|
||||
let a = interval.a
|
||||
let b = interval.b
|
||||
for v in a...b {
|
||||
if index == i {
|
||||
return v
|
||||
|
@ -726,11 +663,6 @@ public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
|
|||
return -1
|
||||
}
|
||||
|
||||
public func toArray() -> [Int] {
|
||||
return toIntegerList()
|
||||
}
|
||||
|
||||
|
||||
public func remove(_ el: Int) throws {
|
||||
if readonly {
|
||||
throw ANTLRError.illegalState(msg: "can't alter readonly IntervalSet")
|
||||
|
|
Loading…
Reference in New Issue