github.com/TIBCOSoftware/flogo-lib@v0.5.9/core/mapper/exprmapper/expression/gocc/parser/parser.go (about)

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