gonum.org/v1/gonum@v0.14.0/graph/formats/dot/internal/parser/parser.go (about) 1 // Code generated by gocc; DO NOT EDIT. 2 3 // This file is dual licensed under CC0 and The Gonum License. 4 // 5 // Copyright ©2017 The Gonum Authors. All rights reserved. 6 // Use of this source code is governed by a BSD-style 7 // license that can be found in the LICENSE file. 8 // 9 // Copyright ©2017 Robin Eklind. 10 // This file is made available under a Creative Commons CC0 1.0 11 // Universal Public Domain Dedication. 12 13 package parser 14 15 import ( 16 "fmt" 17 "strings" 18 19 parseError "gonum.org/v1/gonum/graph/formats/dot/internal/errors" 20 "gonum.org/v1/gonum/graph/formats/dot/internal/token" 21 ) 22 23 const ( 24 numProductions = 55 25 numStates = 87 26 numSymbols = 50 27 ) 28 29 // Stack 30 31 type stack struct { 32 state []int 33 attrib []Attrib 34 } 35 36 const iNITIAL_STACK_SIZE = 100 37 38 func newStack() *stack { 39 return &stack{ 40 state: make([]int, 0, iNITIAL_STACK_SIZE), 41 attrib: make([]Attrib, 0, iNITIAL_STACK_SIZE), 42 } 43 } 44 45 func (s *stack) reset() { 46 s.state = s.state[:0] 47 s.attrib = s.attrib[:0] 48 } 49 50 func (s *stack) push(state int, a Attrib) { 51 s.state = append(s.state, state) 52 s.attrib = append(s.attrib, a) 53 } 54 55 func (s *stack) top() int { 56 return s.state[len(s.state)-1] 57 } 58 59 func (s *stack) peek(pos int) int { 60 return s.state[pos] 61 } 62 63 func (s *stack) topIndex() int { 64 return len(s.state) - 1 65 } 66 67 func (s *stack) popN(items int) []Attrib { 68 lo, hi := len(s.state)-items, len(s.state) 69 70 attrib := s.attrib[lo:hi] 71 72 s.state = s.state[:lo] 73 s.attrib = s.attrib[:lo] 74 75 return attrib 76 } 77 78 func (s *stack) String() string { 79 w := new(strings.Builder) 80 fmt.Fprintf(w, "stack:\n") 81 for i, st := range s.state { 82 fmt.Fprintf(w, "\t%d: %d , ", i, st) 83 if s.attrib[i] == nil { 84 fmt.Fprintf(w, "nil") 85 } else { 86 switch attr := s.attrib[i].(type) { 87 case *token.Token: 88 fmt.Fprintf(w, "%s", attr.Lit) 89 default: 90 fmt.Fprintf(w, "%v", attr) 91 } 92 } 93 fmt.Fprintf(w, "\n") 94 } 95 return w.String() 96 } 97 98 // Parser 99 100 type Parser struct { 101 stack *stack 102 nextToken *token.Token 103 pos int 104 Context Context 105 } 106 107 type Scanner interface { 108 Scan() (tok *token.Token) 109 } 110 111 func NewParser() *Parser { 112 p := &Parser{stack: newStack()} 113 p.Reset() 114 return p 115 } 116 117 func (p *Parser) Reset() { 118 p.stack.reset() 119 p.stack.push(0, nil) 120 } 121 122 func (p *Parser) Error(err error, scanner Scanner) (recovered bool, errorAttrib *parseError.Error) { 123 errorAttrib = &parseError.Error{ 124 Err: err, 125 ErrorToken: p.nextToken, 126 ErrorSymbols: p.popNonRecoveryStates(), 127 ExpectedTokens: make([]string, 0, 8), 128 } 129 for t, action := range actionTab[p.stack.top()].actions { 130 if action != nil { 131 errorAttrib.ExpectedTokens = append(errorAttrib.ExpectedTokens, token.TokMap.Id(token.Type(t))) 132 } 133 } 134 135 if action := actionTab[p.stack.top()].actions[token.TokMap.Type("error")]; action != nil { 136 p.stack.push(int(action.(shift)), errorAttrib) // action can only be shift 137 } else { 138 return 139 } 140 141 if action := actionTab[p.stack.top()].actions[p.nextToken.Type]; action != nil { 142 recovered = true 143 } 144 for !recovered && p.nextToken.Type != token.EOF { 145 p.nextToken = scanner.Scan() 146 if action := actionTab[p.stack.top()].actions[p.nextToken.Type]; action != nil { 147 recovered = true 148 } 149 } 150 151 return 152 } 153 154 func (p *Parser) popNonRecoveryStates() (removedAttribs []parseError.ErrorSymbol) { 155 if rs, ok := p.firstRecoveryState(); ok { 156 errorSymbols := p.stack.popN(p.stack.topIndex() - rs) 157 removedAttribs = make([]parseError.ErrorSymbol, len(errorSymbols)) 158 for i, e := range errorSymbols { 159 removedAttribs[i] = e 160 } 161 } else { 162 removedAttribs = []parseError.ErrorSymbol{} 163 } 164 return 165 } 166 167 // recoveryState points to the highest state on the stack, which can recover 168 func (p *Parser) firstRecoveryState() (recoveryState int, canRecover bool) { 169 recoveryState, canRecover = p.stack.topIndex(), actionTab[p.stack.top()].canRecover 170 for recoveryState > 0 && !canRecover { 171 recoveryState-- 172 canRecover = actionTab[p.stack.peek(recoveryState)].canRecover 173 } 174 return 175 } 176 177 func (p *Parser) newError(err error) error { 178 e := &parseError.Error{ 179 Err: err, 180 StackTop: p.stack.top(), 181 ErrorToken: p.nextToken, 182 } 183 actRow := actionTab[p.stack.top()] 184 for i, t := range actRow.actions { 185 if t != nil { 186 e.ExpectedTokens = append(e.ExpectedTokens, token.TokMap.Id(token.Type(i))) 187 } 188 } 189 return e 190 } 191 192 func (p *Parser) Parse(scanner Scanner) (res interface{}, err error) { 193 p.Reset() 194 p.nextToken = scanner.Scan() 195 for acc := false; !acc; { 196 action := actionTab[p.stack.top()].actions[p.nextToken.Type] 197 if action == nil { 198 if recovered, errAttrib := p.Error(nil, scanner); !recovered { 199 p.nextToken = errAttrib.ErrorToken 200 return nil, p.newError(nil) 201 } 202 if action = actionTab[p.stack.top()].actions[p.nextToken.Type]; action == nil { 203 panic("Error recovery led to invalid action") 204 } 205 } 206 207 switch act := action.(type) { 208 case accept: 209 res = p.stack.popN(1)[0] 210 acc = true 211 case shift: 212 p.stack.push(int(act), p.nextToken) 213 p.nextToken = scanner.Scan() 214 case reduce: 215 prod := productionsTable[int(act)] 216 attrib, err := prod.ReduceFunc(p.stack.popN(prod.NumSymbols), p.Context) 217 if err != nil { 218 return nil, p.newError(err) 219 } else { 220 p.stack.push(gotoTab[p.stack.top()][prod.NTType], attrib) 221 } 222 default: 223 panic("unknown action: " + action.String()) 224 } 225 } 226 return res, nil 227 }