gonum.org/v1/gonum@v0.14.0/graph/formats/dot/internal/errors/errors.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 errors
    14  
    15  import (
    16  	"fmt"
    17  	"strconv"
    18  	"strings"
    19  	"unicode"
    20  
    21  	"gonum.org/v1/gonum/graph/formats/dot/internal/token"
    22  )
    23  
    24  type ErrorSymbol interface {
    25  }
    26  
    27  type Error struct {
    28  	Err            error
    29  	ErrorToken     *token.Token
    30  	ErrorSymbols   []ErrorSymbol
    31  	ExpectedTokens []string
    32  	StackTop       int
    33  }
    34  
    35  func (e *Error) String() string {
    36  	w := new(strings.Builder)
    37  	if e.Err != nil {
    38  		fmt.Fprintln(w, "Error ", e.Err)
    39  	} else {
    40  		fmt.Fprintln(w, "Error")
    41  	}
    42  	fmt.Fprintf(w, "Token: type=%d, lit=%s\n", e.ErrorToken.Type, e.ErrorToken.Lit)
    43  	fmt.Fprintf(w, "Pos: offset=%d, line=%d, column=%d\n", e.ErrorToken.Pos.Offset, e.ErrorToken.Pos.Line, e.ErrorToken.Pos.Column)
    44  	fmt.Fprint(w, "Expected one of: ")
    45  	for _, sym := range e.ExpectedTokens {
    46  		fmt.Fprint(w, string(sym), " ")
    47  	}
    48  	fmt.Fprintln(w, "ErrorSymbol:")
    49  	for _, sym := range e.ErrorSymbols {
    50  		fmt.Fprintf(w, "%v\n", sym)
    51  	}
    52  
    53  	return w.String()
    54  }
    55  
    56  func DescribeExpected(tokens []string) string {
    57  	switch len(tokens) {
    58  	case 0:
    59  		return "unexpected additional tokens"
    60  
    61  	case 1:
    62  		return "expected " + tokens[0]
    63  
    64  	case 2:
    65  		return "expected either " + tokens[0] + " or " + tokens[1]
    66  
    67  	case 3:
    68  		// Oxford-comma rules require more than 3 items in a list for the
    69  		// comma to appear before the 'or'
    70  		return fmt.Sprintf("expected one of %s, %s or %s", tokens[0], tokens[1], tokens[2])
    71  
    72  	default:
    73  		// Oxford-comma separated alternatives list.
    74  		tokens = append(tokens[:len(tokens)-1], "or "+tokens[len(tokens)-1])
    75  		return "expected one of " + strings.Join(tokens, ", ")
    76  	}
    77  }
    78  
    79  func DescribeToken(tok *token.Token) string {
    80  	switch tok.Type {
    81  	case token.INVALID:
    82  		return fmt.Sprintf("unknown/invalid token %q", tok.Lit)
    83  	case token.EOF:
    84  		return "end-of-file"
    85  	default:
    86  		return fmt.Sprintf("%q", tok.Lit)
    87  	}
    88  }
    89  
    90  func (e *Error) Error() string {
    91  	// identify the line and column of the error in 'gnu' style so it can be understood
    92  	// by editors and IDEs; user will need to prefix it with a filename.
    93  	text := fmt.Sprintf("%d:%d: error: ", e.ErrorToken.Pos.Line, e.ErrorToken.Pos.Column)
    94  
    95  	// See if the error token can provide us with the filename.
    96  	switch src := e.ErrorToken.Pos.Context.(type) {
    97  	case token.Sourcer:
    98  		text = src.Source() + ":" + text
    99  	}
   100  
   101  	if e.Err != nil {
   102  		// Custom error specified, e.g. by << nil, errors.New("missing newline") >>
   103  		text += e.Err.Error()
   104  	} else {
   105  		tokens := make([]string, len(e.ExpectedTokens))
   106  		for idx, token := range e.ExpectedTokens {
   107  			if !unicode.IsLetter(rune(token[0])) {
   108  				token = strconv.Quote(token)
   109  			}
   110  			tokens[idx] = token
   111  		}
   112  		text += DescribeExpected(tokens)
   113  		actual := DescribeToken(e.ErrorToken)
   114  		text += fmt.Sprintf("; got: %s", actual)
   115  	}
   116  
   117  	return text
   118  }