forked from jasder/antlr
Merge pull request #2074 from ewanmellor/swift-intervalset-exceptions
Tidy up the exception behavior around IntervalSet and ATNConfigSet.
This commit is contained in:
commit
5f4b9b49da
|
@ -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)
|
||||
|
@ -138,10 +138,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)
|
||||
}
|
||||
|
||||
|
@ -204,7 +204,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
|
||||
}
|
||||
|
@ -223,9 +223,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
|
||||
|
||||
|
@ -245,13 +245,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)
|
||||
|
@ -307,16 +313,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)
|
||||
}
|
||||
|
@ -338,15 +344,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)
|
||||
|
@ -446,10 +452,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
|
||||
|
@ -478,7 +484,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)+
|
||||
|
@ -681,19 +687,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>"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ public class NoViableAltException: RecognitionException {
|
|||
public init(_ recognizer: Parser?,
|
||||
_ input: IntStream,
|
||||
_ startToken: Token,
|
||||
_ offendingToken: Token,
|
||||
_ offendingToken: Token?,
|
||||
_ deadEndConfigs: ATNConfigSet?,
|
||||
_ ctx: ParserRuleContext?) {
|
||||
|
||||
|
@ -44,7 +44,9 @@ public class NoViableAltException: RecognitionException {
|
|||
self.startToken = startToken
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -198,7 +198,7 @@ open class Recognizer<ATNInterpreter: ATNSimulator>: RecognizerProtocol {
|
|||
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