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  }