Ported ATNStates

This commit is contained in:
Peter Boyer 2015-12-17 17:05:28 -05:00
parent e96e55e66d
commit 5ef465e8e2
10 changed files with 235 additions and 125 deletions

View File

@ -168,13 +168,13 @@ func (bt *BufferedTokenStream) fetch(n int) int {
}
// Get all tokens from start..stop inclusively///
func (bt *BufferedTokenStream) getTokens(start int, stop int, types []int) []Token {
func (bt *BufferedTokenStream) getTokens(start int, stop int, types []int) []*Token {
if (start < 0 || stop < 0) {
return nil
}
bt.lazyInit()
var subset = []
var subset = (make[]*Token)
if (stop >= len(bt.tokens)) {
stop = len(bt.tokens) - 1
}
@ -295,7 +295,12 @@ func (bt *BufferedTokenStream) getHiddenTokensToRight(tokenIndex, channel int) {
var nextOnChannel = bt.nextTokenOnChannel(tokenIndex + 1, LexerDefaultTokenChannel)
var from_ = tokenIndex + 1
// if none onchannel to right, nextOnChannel=-1 so set to = last token
var to = nextOnChannel == -1 ? len(bt.tokens) - 1 : nextOnChannel
var to int
if (nextOnChannel == -1){
to = len(bt.tokens) - 1
} else {
to = nextOnChannel
}
return bt.filterForChannel(from_, to, channel)
}
@ -305,7 +310,7 @@ func (bt *BufferedTokenStream) getHiddenTokensToRight(tokenIndex, channel int) {
func (bt *BufferedTokenStream) getHiddenTokensToLeft(tokenIndex, channel int) {
bt.lazyInit()
if (tokenIndex < 0 || tokenIndex >= len(bt.tokens)) {
panic( "" + tokenIndex + " not in 0.." + len(bt.tokens) - 1
panic( "" + tokenIndex + " not in 0.." + len(bt.tokens) - 1 )
}
var prevOnChannel = bt.previousTokenOnChannel(tokenIndex - 1, LexerDefaultTokenChannel)
if (prevOnChannel == tokenIndex - 1) {

View File

@ -30,21 +30,20 @@ const (
//
// @param s the ATN state
// @return the expected symbols for each outgoing transition of {@code s}.
///
func (la *LL1Analyzer) getDecisionLookahead(s) {
func (la *LL1Analyzer) getDecisionLookahead(s *atn.ATNState) []*IntervalSet {
if (s == nil) {
return nil
}
var count = len(s.transitions)
var look = []
var look = make([]*IntervalSet)
for alt := 0; alt < count; alt++ {
look[alt] = NewIntervalSet()
var lookBusy = NewSet()
var lookBusy = NewSet(nil,nil)
var seeThruPreds = false // fail to get lookahead upon pred
la._LOOK(s.transition(alt).target, nil, PredictionContext.EMPTY, look[alt], lookBusy, NewBitSet(), seeThruPreds, false)
la._LOOK(s.transitions(alt).target, nil, PredictionContextEMPTY, look[alt], lookBusy, NewBitSet(), seeThruPreds, false)
// Wipe out lookahead for la alternative if we found nothing
// or we had a predicate when we !seeThruPreds
if (look[alt].length==0 || look[alt].contains(LL1Analyzer.HIT_PRED)) {
if (look[alt].length==0 || look[alt].contains(LL1AnalyzerHIT_PRED)) {
look[alt] = nil
}
}

View File

@ -101,7 +101,7 @@ func (p *Parser) reset() {
p._precedenceStack = make([]int, 0)
p._precedenceStack.Push(0)
if (p._interp != nil) {
p._interp.reset()
*p._interp.reset()
}
}
@ -154,7 +154,7 @@ func (p *Parser) match(ttype int) *Token {
// a wildcard and the error strategy could not recover from the mismatched
// symbol
func (p *Parser) matchWildcard() {
func (p *Parser) matchWildcard() *Token {
var t = p.getCurrentToken()
if (t.tokenType > 0) {
p._errHandler.reportMatch(p)
@ -171,8 +171,11 @@ func (p *Parser) matchWildcard() {
return t
}
func (p *Parser) getParseListeners() {
return p._parseListeners || []
func (p *Parser) getParseListeners() []*tree.ParseTreeListener {
if (p._parseListeners == nil){
return make([]*tree.ParseTreeListener)
}
return p._parseListeners
}
// Registers {@code listener} to receive events during the parsing process.
@ -392,19 +395,19 @@ func (p *Parser) consume() {
if (o.tokenType != TokenEOF) {
p.getInputStream().consume()
}
var hasListener = p._parseListeners != nil && p._parseListeners.length > 0
var hasListener = p._parseListeners != nil && len(p._parseListeners) > 0
if (p.buildParseTrees || hasListener) {
var node
if (p._errHandler.inErrorRecoveryMode(p.) {
var node *tree.ErrorNodeImpl
if (p._errHandler.inErrorRecoveryMode(p)) {
node = p._ctx.addErrorNode(o)
} else {
node = p._ctx.addTokenNode(o)
}
node.invokingState = p.state
if (hasListener) {
p._parseListeners.map(function(listener) {
listener.visitTerminal(node)
})
for _, l := range p._parseListeners {
l.visitTerminal(node)
}
}
}
return o
@ -420,7 +423,7 @@ func (p *Parser) addContextToParseTree() {
// Always called by generated parsers upon entry to a rule. Access field
// {@link //_ctx} get the current context.
func (p *Parser) enterRule(localctx, state, ruleIndex int) {
func (p *Parser) enterRule(localctx *ParserRuleContext, state, ruleIndex int) {
p.state = state
p._ctx = localctx
p._ctx.start = p._input.LT(1)
@ -442,7 +445,7 @@ func (p *Parser) exitRule() {
p._ctx = p._ctx.parentCtx
}
func (p *Parser) enterOuterAlt(localctx, altNum) {
func (p *Parser) enterOuterAlt(localctx *ParserRuleContext, altNum int) {
// if we have Newlocalctx, make sure we replace existing ctx
// that is previous child of parse tree
if (p.buildParseTrees && p._ctx != localctx) {
@ -459,17 +462,17 @@ func (p *Parser) enterOuterAlt(localctx, altNum) {
// @return The precedence level for the top-most precedence rule, or -1 if
// the parser context is not nested within a precedence rule.
func (p *Parser) getPrecedence() {
if (p._precedenceStack.length == 0) {
func (p *Parser) getPrecedence() int {
if ( len(p._precedenceStack) == 0) {
return -1
} else {
return p._precedenceStack[p._precedenceStack.length-1]
return p._precedenceStack[ len(p._precedenceStack) -1]
}
}
func (p *Parser) enterRecursionRule(localctx, state, ruleIndex, precedence) {
func (p *Parser) enterRecursionRule(localctx *ParserRuleContext, state, ruleIndex, precedence int) {
p.state = state
p._precedenceStack.push(precedence)
p._precedenceStack.Push(precedence)
p._ctx = localctx
p._ctx.start = p._input.LT(1)
if (p._parseListeners != nil) {
@ -481,7 +484,7 @@ func (p *Parser) enterRecursionRule(localctx, state, ruleIndex, precedence) {
//
// Like {@link //enterRule} but for recursive rules.
func (p *Parser) pushNewRecursionContext(localctx, state, ruleIndex) {
func (p *Parser) pushNewRecursionContext(localctx *ParserRuleContext, state, ruleIndex int) {
var previous = p._ctx
previous.parentCtx = localctx
previous.invokingState = state
@ -498,8 +501,8 @@ func (p *Parser) pushNewRecursionContext(localctx, state, ruleIndex) {
}
}
func (p *Parser) unrollRecursionContexts(parentCtx) {
p._precedenceStack.pop()
func (p *Parser) unrollRecursionContexts(parentCtx *ParserRuleContext) {
p._precedenceStack.Pop()
p._ctx.stop = p._input.LT(-1)
var retCtx = p._ctx // save current ctx (return value)
// unroll so _ctx is as it was before call to recursive method
@ -519,7 +522,7 @@ func (p *Parser) unrollRecursionContexts(parentCtx) {
}
}
func (p *Parser) getInvokingContext(ruleIndex) {
func (p *Parser) getInvokingContext(ruleIndex int) *ParserRuleContext {
var ctx = p._ctx
for (ctx != nil) {
if (ctx.ruleIndex == ruleIndex) {
@ -530,11 +533,11 @@ func (p *Parser) getInvokingContext(ruleIndex) {
return nil
}
func (p *Parser) precpred(localctx, precedence) {
return precedence >= p._precedenceStack[p._precedenceStack.length-1]
func (p *Parser) precpred(localctx, precedence int) {
return precedence >= p._precedenceStack[ len(p._precedenceStack) -1]
}
func (p *Parser) inContext(context) {
func (p *Parser) inContext(context *ParserRuleContext) bool {
// TODO: useful in parser?
return false
}
@ -553,8 +556,8 @@ func (p *Parser) inContext(context) {
// @return {@code true} if {@code symbol} can follow the current state in
// the ATN, otherwise {@code false}.
func (p *Parser) isExpectedToken(symbol) {
var atn = p._interp.atn
func (p *Parser) isExpectedToken(symbol *Token) bool {
var atn *atn.ATN = p._interp.atn
var ctx = p._ctx
var s = atn.states[p.state]
var following = atn.nextTokens(s)
@ -586,11 +589,11 @@ func (p *Parser) isExpectedToken(symbol) {
//
// @see ATN//getExpectedTokens(int, RuleContext)
//
func (p *Parser) getExpectedTokens() {
func (p *Parser) getExpectedTokens() []*Token {
return p._interp.atn.getExpectedTokens(p.state, p._ctx)
}
func (p *Parser) getExpectedTokensWithinCurrentRule() {
func (p *Parser) getExpectedTokensWithinCurrentRule() []*Token {
var atn = p._interp.atn
var s = atn.states[p.state]
return atn.nextTokens(s)
@ -611,31 +614,31 @@ func (p *Parser) getRuleIndex(ruleName string) int {
// you want more details such as the file/line info of where
// in the ATN a rule is invoked.
//
// p.is very useful for error messages.
//
func (p *Parser) getRuleInvocationStack(p) {
p = p || nil
// this very useful for error messages.
func (this *Parser) getRuleInvocationStack(p *ParserRuleContext) []string {
if (p == nil) {
p = p._ctx
p = this._ctx;
}
var stack = []
var stack = make([]string)
for (p != nil) {
// compute what follows who invoked us
var ruleIndex = p.ruleIndex
var ruleIndex = p.ruleIndex;
if (ruleIndex < 0) {
stack.push("n/a")
stack = append(stack, "n/a")
} else {
stack.push(p.ruleNames[ruleIndex])
stack = append(stack, this.getRuleNames()[ruleIndex]);
}
p = p.parentCtx
p = p.parentCtx;
}
return stack
}
return stack;
};
// For debugging and other purposes.//
func (p *Parser) getDFAStrings() {
return p._interp.decisionToDFA.toString()
}
// For debugging and other purposes.//
func (p *Parser) dumpDFA() {
var seenOne = false

View File

@ -32,6 +32,7 @@ import (
type ParserRuleContext struct {
RuleContext
ruleIndex int
children []RuleContext
start, stop *Token
@ -225,8 +226,7 @@ type InterpreterRuleContext struct {
func NewInterpreterRuleContext(parent *InterpreterRuleContext, invokingStateNumber, ruleIndex int) {
prc := new(InterpreterRuleContext)
prc.init(parent, invokingStateNumber)
prc.initParserRuleContext( parent, invokingStateNumber )
prc.ruleIndex = ruleIndex

View File

@ -36,8 +36,6 @@ type RuleContext struct {
func NewRuleContext(parent *RuleContext, invokingState int) *RuleContext {
rn := &RuleContext{tree.RuleNode{}}
rn.initRuleNode()
rn.initRuleContext(parent, invokingState)
return rn

View File

@ -35,6 +35,8 @@ func arrayToString(a []interface{}) string{
}
func hashCode(s string) int {
h := fnv.New32a()
h.Write([]byte((s)))

View File

@ -1,15 +1,16 @@
package atn
//var DFAState = require('./../dfa/DFAState').DFAState
//var ATNConfigSet = require('./ATNConfigSet').ATNConfigSet
//var getCachedPredictionContext = require('./../PredictionContext').getCachedPredictionContext
import (
"antlr4"
"antlr4/dfa"
)
type ATNSimulator struct {
atn *ATN
sharedContextCache
sharedContextCache *antlr4.PredictionContextCache
}
func ATNSimulator(atn, sharedContextCache) {
func ATNSimulator(atn *ATN, sharedContextCache *antlr4.PredictionContextCache) *ATNSimulator {
// The context cache maps all PredictionContext objects that are ==
// to a single cached copy. This cache is shared across all contexts
@ -30,21 +31,23 @@ func ATNSimulator(atn, sharedContextCache) {
// whacked after each adaptivePredict(). It cost a little bit
// more time I think and doesn't save on the overall footprint
// so it's not worth the complexity.</p>
///
this := new(ATNSimulator)
this.atn = atn
this.sharedContextCache = sharedContextCache
return this
}
// Must distinguish between missing edge and edge we know leads nowhere///
ATNSimulator.ERROR = NewDFAState(0x7FFFFFFF, NewATNConfigSet())
var ATNSimulatorERROR = dfa.NewDFAState(0x7FFFFFFF, NewATNConfigSet())
func (this *ATNSimulator) getCachedContext(context) {
if (this.sharedContextCache ==nil) {
func (this *ATNSimulator) getCachedContext(context *antlr4.PredictionContext) *antlr4.PredictionContext {
if (this.sharedContextCache == nil) {
return context
}
var visited = {}
var visited = make(map[*antlr4.PredictionContext]*antlr4.PredictionContext)
return getCachedPredictionContext(context, this.sharedContextCache, visited)
}

View File

@ -1,4 +1,5 @@
package atn
import "antlr4"
// The following images show the relation of states and
// {@link ATNState//transitions} for various grammar constructs.
@ -70,29 +71,34 @@ type ATNState struct {
ruleIndex int
epsilonOnlyTransitions bool
// Track the transitions emanating from this ATN state.
transitions []Transition
transitions []*Transition
// Used to cache lookahead during parsing, not used during construction
nextTokenWithinRule *Token
nextTokenWithinRule *antlr4.Token
}
func NewATNState() *ATNState {
as := new(ATNState)
// Which ATN are we in?
as.atn = nil
as.stateNumber = ATNStateINVALID_STATE_NUMBER
as.stateType = nil
as.ruleIndex = 0 // at runtime, we don't have Rule objects
as.epsilonOnlyTransitions = false
// Track the transitions emanating from this ATN state.
as.transitions = make([]Transition, 0)
// Used to cache lookahead during parsing, not used during construction
as.nextTokenWithinRule = nil
as.initATNState()
return as
}
func (as *ATNState) initATNState(){
// Which ATN are we in?
as.atn = nil
as.stateNumber = ATNStateINVALID_STATE_NUMBER
as.stateType = nil
as.ruleIndex = 0 // at runtime, we don't have Rule objects
as.epsilonOnlyTransitions = false
// Track the transitions emanating from this ATN state.
as.transitions = make([]Transition, 0)
// Used to cache lookahead during parsing, not used during construction
as.nextTokenWithinRule = nil
}
const (
// constants for serialization
ATNStateInvalidType = 0
@ -111,21 +117,21 @@ const (
ATNStateINVALID_STATE_NUMBER = -1
)
var ATNState.serializationNames = [
"INVALID",
"BASIC",
"RULE_START",
"BLOCK_START",
"PLUS_BLOCK_START",
"STAR_BLOCK_START",
"TOKEN_START",
"RULE_STOP",
"BLOCK_END",
"STAR_LOOP_BACK",
"STAR_LOOP_ENTRY",
"PLUS_LOOP_BACK",
"LOOP_END" ]
//
//var ATNState.serializationNames = [
// "INVALID",
// "BASIC",
// "RULE_START",
// "BLOCK_START",
// "PLUS_BLOCK_START",
// "STAR_BLOCK_START",
// "TOKEN_START",
// "RULE_STOP",
// "BLOCK_END",
// "STAR_LOOP_BACK",
// "STAR_LOOP_ENTRY",
// "PLUS_LOOP_BACK",
// "LOOP_END" ]
func (this *ATNState) toString() string {
return this.stateNumber
@ -143,71 +149,109 @@ func (this *ATNState) isNonGreedyExitState() {
return false
}
func (this *ATNState) addTransition(trans int, index int) {
func (this *ATNState) addTransition(trans *Transition, index int) {
if ( len(this.transitions) == 0 ) {
this.epsilonOnlyTransitions = trans.isEpsilon
} else if(this.epsilonOnlyTransitions != trans.isEpsilon) {
this.epsilonOnlyTransitions = false
}
if (index==-1) {
this.transitions.push(trans)
this.transitions = append(this.transitions, trans)
} else {
this.transitions.splice(index, 1, trans)
}
}
type BasicState struct {
ATNState
}
func NewBasicState() *BasicState {
ATNState.call(this)
this := new(BasicState)
this.initATNState()
this.stateType = ATNStateBASIC
return this
}
type DecisionState struct {
ATNState
decision int
nonGreedy bool
}
func NewDecisionState() *DecisionState {
ATNState.call(this)
this.decision = -1
this.nonGreedy = false
this := new(DecisionState)
this.initATNState()
this.initDecisionState()
return this
}
func (this *DecisionState) initDecisionState() {
this.decision = -1
this.nonGreedy = false
}
// The start of a regular {@code (...)} block.
type BlockStartState struct {
DecisionState
endState *ATNState
}
func NewBlockStartState() *BlockStartState {
DecisionState.call(this)
this.endState = nil
this := new(BlockStartState)
this.initATNState()
this.initDecisionState()
return this
}
type BasicBlockStartState struct {
func (this *BlockStartState) initBlockStartState() {
this.endState = nil
}
type BasicBlockStartState struct {
BlockStartState
}
func NewBasicBlockStartState() *BasicBlockStartState {
BlockStartState.call(this)
this := new(BasicBlockStartState)
this.initATNState()
this.initDecisionState()
this.initBlockStartState()
this.stateType = ATNStateBLOCK_START
return this
}
// Terminal node of a simple {@code (a|b|c)} block.
type BlockEndState struct {
ATNState
startState *ATNState
}
func NewBlockEndState() *BlockEndState {
ATNState.call(this)
this := new(BlockEndState)
this.initATNState()
this.stateType = ATNStateBLOCK_END
this.startState = nil
return this
}
@ -217,24 +261,33 @@ func NewBlockEndState() *BlockEndState {
// error handling.
//
type RuleStopState struct {
ATNState
}
func NewRuleStopState() *RuleStopState {
ATNState.call(this)
this := new(RuleStopState)
this.initATNState()
this.stateType = ATNStateRULE_STOP
return this
}
type RuleStartState struct {
ATNState
stopState *ATNState
isPrecedenceRule bool
}
func NewRuleStartState() *RuleStartState {
ATNState.call(this)
this := new(RuleStartState)
this.initATNState()
this.stateType = ATNStateRULE_START
this.stopState = nil
this.isPrecedenceRule = false
return this
}
@ -242,11 +295,17 @@ func NewRuleStartState() *RuleStartState {
// one to the loop back to start of the block and one to exit.
//
type PlusLoopbackState struct {
BlockStartState
}
func NewPlusLoopbackState() *PlusLoopbackState {
DecisionState.call(this)
this := new(PlusLoopbackState)
this.initATNState()
this.initDecisionState()
this.initBlockStartState()
this.stateType = ATNStatePLUS_LOOP_BACK
return this
}
@ -257,72 +316,113 @@ func NewPlusLoopbackState() *PlusLoopbackState {
// real decision-making note for {@code A+}.
//
type PlusBlockStartState struct {
BlockStartState
loopBackState *ATNState
}
func NewPlusBlockStartState() *PlusBlockStartState {
BlockStartState.call(this)
this := new(PlusBlockStartState)
this.initATNState()
this.initDecisionState()
this.initBlockStartState()
this.stateType = ATNStatePLUS_BLOCK_START
this.loopBackState = nil
return this
}
// The block that begins a closure loop.
type StarBlockStartState struct {
BlockStartState
}
func NewStarBlockStartState() *StarBlockStartState {
BlockStartState.call(this)
this := new(StarBlockStartState)
this.initATNState()
this.initDecisionState()
this.initBlockStartState()
this.stateType = ATNStateSTAR_BLOCK_START
return this
}
type StarLoopbackState struct {
ATNState
}
func NewStarLoopbackState() *StarLoopbackState {
ATNState.call(this)
this := new(StarLoopbackState)
this.initATNState()
this.stateType = ATNStateSTAR_LOOP_BACK
return this
}
type StarLoopEntryState struct {
DecisionState
loopBackState *ATNState
precedenceRuleDecision bool
}
func NewStarLoopEntryState() *StarLoopEntryState {
DecisionState.call(this)
this := new(StarLoopEntryState)
this.initATNState()
this.initDecisionState()
this.stateType = ATNStateSTAR_LOOP_ENTRY
this.loopBackState = nil
// Indicates whether this state can benefit from a precedence DFA during SLL decision making.
this.precedenceRuleDecision = nil
this.precedenceRuleDecision = false
return this
}
// Mark the end of a * or + loop.
type LoopEndState struct {
ATNState
loopBackState *ATNState
}
func NewLoopEndState() *LoopEndState {
ATNState.call(this)
this := new(LoopEndState)
this.initATNState()
this.stateType = ATNStateLOOP_END
this.loopBackState = nil
return this
}
// The Tokens rule start state linking to each lexer rule start state */
type TokensStartState struct {
DecisionState
}
func NewTokensStartState() *TokensStartState {
DecisionState.call(this)
this := new(TokensStartState)
this.initATNState()
this.initDecisionState()
this.stateType = ATNStateTOKEN_START
return this
}

View File

@ -174,7 +174,7 @@ const (
// the configurations to strip out all of the predicates so that a standard
// {@link ATNConfigSet} will merge everything ignoring predicates.</p>
//
PredictionModehasSLLConflictTerminatingPrediction = function( mode, configs) {
func PredictionModehasSLLConflictTerminatingPrediction( mode, configs ) {
// Configs in rule stop states indicate reaching the end of the decision
// rule (local context) or end of start rule (full context). If all
// configs meet this condition, then none of the configurations is able

View File

@ -35,7 +35,7 @@ type DiagnosticErrorListener struct {
func DiagnosticErrorListener(exactOnly bool) {
n = new(DiagnosticErrorListener)
n := new(DiagnosticErrorListener)
// whether all ambiguities or only exact ambiguities are reported.
n.exactOnly = exactOnly
@ -75,7 +75,7 @@ func (this *DiagnosticErrorListener) reportContextSensitivity(recognizer *antlr4
recognizer.notifyErrorListeners(msg)
}
func (this *DiagnosticErrorListener) getDecisionDescription(recognizer, dfa *dfa.DFA) {
func (this *DiagnosticErrorListener) getDecisionDescription(recognizer *antlr4.Parser, dfa *dfa.DFA) {
var decision = dfa.decision
var ruleIndex = dfa.atnStartState.ruleIndex