github.com/hattya/go.sh@v0.0.0-20240328132134-f53276d95cc6/parser/parser.go (about)

     1  // Code generated by goyacc -l -o parser.go parser.go.y. DO NOT EDIT.
     2  //
     3  // go.sh/parser :: parser.go
     4  //
     5  //   Copyright (c) 2018-2021 Akinori Hattori <hattya@gmail.com>
     6  //
     7  //   SPDX-License-Identifier: MIT
     8  //
     9  
    10  package parser
    11  
    12  import __yyfmt__ "fmt"
    13  
    14  import (
    15  	"bufio"
    16  	"bytes"
    17  	"errors"
    18  	"io"
    19  	"strings"
    20  
    21  	"github.com/hattya/go.sh/ast"
    22  	"github.com/hattya/go.sh/interp"
    23  )
    24  
    25  type yySymType struct {
    26  	yys   int
    27  	list  interface{}
    28  	node  ast.Node
    29  	elt   *element
    30  	word  ast.Word
    31  	token token
    32  }
    33  
    34  const AND = 57346
    35  const OR = 57347
    36  const LAE = 57348
    37  const RAE = 57349
    38  const BREAK = 57350
    39  const CLOBBER = 57351
    40  const APPEND = 57352
    41  const HEREDOC = 57353
    42  const HEREDOCI = 57354
    43  const DUPIN = 57355
    44  const DUPOUT = 57356
    45  const RDWR = 57357
    46  const IO_NUMBER = 57358
    47  const WORD = 57359
    48  const NAME = 57360
    49  const ASSIGNMENT_WORD = 57361
    50  const Bang = 57362
    51  const Lbrace = 57363
    52  const Rbrace = 57364
    53  const For = 57365
    54  const Case = 57366
    55  const Esac = 57367
    56  const In = 57368
    57  const If = 57369
    58  const Elif = 57370
    59  const Then = 57371
    60  const Else = 57372
    61  const Fi = 57373
    62  const While = 57374
    63  const Until = 57375
    64  const Do = 57376
    65  const Done = 57377
    66  
    67  var yyToknames = [...]string{
    68  	"$end",
    69  	"error",
    70  	"$unk",
    71  	"AND",
    72  	"OR",
    73  	"'|'",
    74  	"'('",
    75  	"')'",
    76  	"LAE",
    77  	"RAE",
    78  	"BREAK",
    79  	"'&'",
    80  	"';'",
    81  	"'<'",
    82  	"'>'",
    83  	"CLOBBER",
    84  	"APPEND",
    85  	"HEREDOC",
    86  	"HEREDOCI",
    87  	"DUPIN",
    88  	"DUPOUT",
    89  	"RDWR",
    90  	"IO_NUMBER",
    91  	"WORD",
    92  	"NAME",
    93  	"ASSIGNMENT_WORD",
    94  	"Bang",
    95  	"Lbrace",
    96  	"Rbrace",
    97  	"For",
    98  	"Case",
    99  	"Esac",
   100  	"In",
   101  	"If",
   102  	"Elif",
   103  	"Then",
   104  	"Else",
   105  	"Fi",
   106  	"While",
   107  	"Until",
   108  	"Do",
   109  	"Done",
   110  	"'\\n'",
   111  }
   112  
   113  var yyStatenames = [...]string{}
   114  
   115  const yyEofCode = 1
   116  const yyErrCode = 2
   117  const yyInitialStackSize = 16
   118  
   119  func init() {
   120  	yyErrorVerbose = true
   121  
   122  	for i, s := range yyToknames {
   123  		switch s {
   124  		case "$end":
   125  			s = "EOF"
   126  		case "AND":
   127  			s = "'&&'"
   128  		case "OR":
   129  			s = "'||'"
   130  		case "LAE":
   131  			s = "(("
   132  		case "RAE":
   133  			s = "))"
   134  		case "BREAK":
   135  			s = "';;'"
   136  		case "CLOBBER":
   137  			s = "'>|'"
   138  		case "APPEND":
   139  			s = "'>>'"
   140  		case "HEREDOC":
   141  			s = "'<<'"
   142  		case "HEREDOCI":
   143  			s = "'<<-'"
   144  		case "DUPIN":
   145  			s = "'<&'"
   146  		case "DUPOUT":
   147  			s = "'>&'"
   148  		case "RDWR":
   149  			s = "'<>'"
   150  		case "Bang":
   151  			s = "'!'"
   152  		case "Lbrace":
   153  			s = "'{'"
   154  		case "Rbrace":
   155  			s = "'}'"
   156  		case "For":
   157  			s = "'for'"
   158  		case "Case":
   159  			s = "'case'"
   160  		case "Esac":
   161  			s = "'esac'"
   162  		case "In":
   163  			s = "'in'"
   164  		case "If":
   165  			s = "'if'"
   166  		case "Elif":
   167  			s = "'elif'"
   168  		case "Then":
   169  			s = "'then'"
   170  		case "Else":
   171  			s = "'else'"
   172  		case "Fi":
   173  			s = "'fi'"
   174  		case "While":
   175  			s = "'while'"
   176  		case "Until":
   177  			s = "'until'"
   178  		case "Do":
   179  			s = "'do'"
   180  		case "Done":
   181  			s = "'done'"
   182  		}
   183  		yyToknames[i] = s
   184  	}
   185  }
   186  
   187  type element struct {
   188  	redirs  []*ast.Redir
   189  	assigns []*ast.Assign
   190  	args    []ast.Word
   191  }
   192  
   193  func extract(cmd *ast.AndOrList) ast.Command {
   194  	switch {
   195  	case len(cmd.List) != 0 || !cmd.SepPos.IsZero():
   196  		return cmd
   197  	case !cmd.Pipeline.Bang.IsZero() || len(cmd.Pipeline.List) != 0:
   198  		return cmd.Pipeline
   199  	}
   200  	return cmd.Pipeline.Cmd
   201  }
   202  
   203  func assign(w ast.Word) *ast.Assign {
   204  	n := w[0].(*ast.Lit)
   205  	if i := strings.IndexRune(n.Value, '='); 0 < i && i < len(n.Value)-1 {
   206  		w[0] = &ast.Lit{
   207  			ValuePos: ast.NewPos(n.ValuePos.Line(), n.ValuePos.Col()+i+1),
   208  			Value:    n.Value[i+1:],
   209  		}
   210  		n.Value = n.Value[:i]
   211  	} else {
   212  		w = w[1:]
   213  		n.Value = n.Value[:len(n.Value)-1]
   214  	}
   215  	return &ast.Assign{
   216  		Name:  n,
   217  		Op:    "=",
   218  		Value: w,
   219  	}
   220  }
   221  
   222  // ParseCommands parses src, including alias substitution, and returns
   223  // commands.
   224  func ParseCommands(env *interp.ExecEnv, name string, src interface{}) ([]ast.Command, []*ast.Comment, error) {
   225  	r, err := open(src)
   226  	if err != nil {
   227  		return nil, nil, err
   228  	}
   229  
   230  	l := newLexer(env, name, r)
   231  	yyParse(l)
   232  	return l.cmds, l.comments, l.err
   233  }
   234  
   235  // ParseCommand parses src and returns a command.
   236  func ParseCommand(name string, src interface{}) (ast.Command, []*ast.Comment, error) {
   237  	cmds, comments, err := ParseCommands(nil, name, src)
   238  	if len(cmds) == 0 {
   239  		return nil, comments, err
   240  	}
   241  	return cmds[0], comments, err
   242  }
   243  
   244  func open(src interface{}) (r io.RuneScanner, err error) {
   245  	switch src := src.(type) {
   246  	case []byte:
   247  		r = bytes.NewReader(src)
   248  	case string:
   249  		r = strings.NewReader(src)
   250  	case io.RuneScanner:
   251  		r = src
   252  	case io.Reader:
   253  		r = bufio.NewReader(src)
   254  	default:
   255  		err = errors.New("invalid source")
   256  	}
   257  	return
   258  }
   259  
   260  var yyExca = [...]int{
   261  	-1, 1,
   262  	1, -1,
   263  	-2, 0,
   264  	-1, 101,
   265  	41, 101,
   266  	-2, 104,
   267  }
   268  
   269  const yyPrivate = 57344
   270  
   271  const yyLast = 386
   272  
   273  var yyAct = [...]int{
   274  	68, 67, 145, 48, 130, 24, 144, 58, 143, 69,
   275  	98, 11, 49, 94, 5, 63, 51, 59, 9, 61,
   276  	64, 3, 6, 26, 100, 28, 50, 100, 100, 70,
   277  	52, 53, 82, 74, 75, 76, 168, 161, 139, 127,
   278  	136, 134, 133, 122, 27, 152, 29, 30, 137, 111,
   279  	31, 105, 97, 104, 50, 32, 33, 50, 50, 148,
   280  	131, 50, 132, 5, 87, 83, 64, 160, 103, 89,
   281  	146, 81, 36, 99, 102, 86, 88, 84, 85, 146,
   282  	34, 131, 101, 132, 129, 114, 112, 147, 156, 95,
   283  	72, 165, 106, 147, 89, 153, 147, 80, 79, 110,
   284  	73, 113, 71, 109, 140, 115, 116, 117, 78, 121,
   285  	108, 52, 53, 123, 177, 128, 77, 170, 119, 96,
   286  	7, 120, 126, 124, 158, 59, 166, 135, 158, 57,
   287  	157, 92, 91, 149, 150, 126, 138, 66, 56, 151,
   288  	2, 87, 54, 55, 1, 107, 38, 37, 155, 159,
   289  	154, 93, 142, 141, 162, 125, 118, 22, 163, 164,
   290  	21, 20, 167, 19, 18, 17, 16, 171, 172, 15,
   291  	174, 175, 173, 26, 13, 28, 10, 178, 179, 12,
   292  	39, 40, 41, 42, 46, 47, 43, 44, 45, 35,
   293  	14, 23, 25, 8, 27, 4, 29, 30, 0, 0,
   294  	31, 0, 0, 0, 0, 32, 33, 0, 26, 82,
   295  	28, 0, 176, 0, 0, 39, 40, 41, 42, 46,
   296  	47, 43, 44, 45, 35, 14, 23, 25, 8, 27,
   297  	0, 29, 30, 0, 0, 31, 0, 0, 0, 0,
   298  	32, 33, 26, 0, 28, 0, 169, 0, 0, 39,
   299  	40, 41, 42, 46, 47, 43, 44, 45, 35, 14,
   300  	23, 25, 8, 27, 0, 29, 30, 0, 0, 31,
   301  	26, 0, 28, 0, 32, 33, 0, 39, 40, 41,
   302  	42, 46, 47, 43, 44, 45, 35, 14, 23, 25,
   303  	8, 27, 0, 29, 30, 0, 0, 31, 26, 0,
   304  	28, 0, 32, 33, 0, 39, 40, 41, 42, 46,
   305  	47, 43, 44, 45, 35, 14, 23, 25, 0, 27,
   306  	0, 29, 30, 0, 0, 31, 0, 0, 0, 0,
   307  	32, 33, 39, 40, 41, 42, 46, 47, 43, 44,
   308  	45, 35, 60, 0, 62, 39, 40, 41, 42, 46,
   309  	47, 43, 44, 45, 35, 90, 39, 40, 41, 42,
   310  	46, 47, 43, 44, 45, 35, 65, 39, 40, 41,
   311  	42, 46, 47, 43, 44, 45, 35, 39, 40, 41,
   312  	42, 46, 47, 43, 44, 45,
   313  }
   314  
   315  var yyPact = [...]int{
   316  	263, -1000, -17, -1000, 99, 138, -1000, 132, 291, -1000,
   317  	-1000, 353, -1000, 318, 342, -1000, -1000, -1000, -1000, -1000,
   318  	-1000, -1000, -1000, 130, -1000, -1000, -17, -17, 78, 65,
   319  	76, -17, -17, -17, -1000, 363, -1000, 74, 73, -1000,
   320  	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 166,
   321  	-1000, 263, -1000, -1000, 263, 263, 291, 132, 353, -1000,
   322  	342, -1000, -1000, 331, -1000, -1000, 124, 123, 263, -11,
   323  	60, 109, 11, -17, 32, 12, 10, -1000, -1000, -1000,
   324  	-1000, -1000, -1000, 138, -1000, -1000, -1000, -1000, 331, -1000,
   325  	-1000, -17, -1000, 18, 138, -1000, -1000, -17, 8, 53,
   326  	-17, -11, 52, -17, -17, -17, 16, 263, -17, -11,
   327  	1, -17, 15, -1000, -17, 46, 0, -1, -1000, 353,
   328  	138, -1000, -1000, -2, 7, 14, -11, -1000, 72, -1000,
   329  	21, -17, -17, -1000, -1000, 353, -1000, -17, 4, -1000,
   330  	-1000, 63, 56, -1000, -1000, 122, 69, -1000, -1000, 31,
   331  	-1000, -5, -17, -1000, -1000, -1000, -1000, -17, 67, 118,
   332  	-17, -1000, -6, 235, 106, -1000, -17, 25, -1000, -17,
   333  	-17, 201, 103, -1000, -1000, -1000, -17, -17, -1000, -1000,
   334  }
   335  
   336  var yyPgo = [...]int{
   337  	0, 21, 195, 13, 22, 120, 18, 179, 176, 174,
   338  	15, 11, 169, 166, 165, 164, 163, 161, 160, 157,
   339  	156, 155, 2, 153, 152, 8, 6, 4, 1, 151,
   340  	7, 5, 80, 72, 147, 146, 145, 10, 16, 144,
   341  	140, 0, 9,
   342  }
   343  
   344  var yyR1 = [...]int{
   345  	0, 39, 39, 40, 40, 1, 1, 2, 2, 3,
   346  	3, 3, 4, 4, 5, 5, 6, 6, 6, 6,
   347  	8, 8, 8, 8, 8, 9, 9, 9, 9, 10,
   348  	10, 10, 10, 11, 11, 11, 11, 11, 11, 11,
   349  	11, 12, 13, 14, 15, 15, 15, 15, 21, 21,
   350  	16, 16, 16, 23, 23, 25, 25, 25, 25, 24,
   351  	24, 26, 26, 26, 26, 22, 22, 17, 17, 27,
   352  	27, 27, 18, 19, 7, 20, 20, 28, 28, 29,
   353  	29, 30, 30, 31, 31, 31, 31, 32, 34, 34,
   354  	34, 34, 34, 34, 34, 33, 35, 35, 36, 36,
   355  	37, 37, 38, 38, 41, 41, 42, 42,
   356  }
   357  
   358  var yyR2 = [...]int{
   359  	0, 2, 0, 1, 3, 2, 1, 1, 3, 1,
   360  	3, 3, 1, 2, 1, 3, 1, 1, 2, 1,
   361  	3, 2, 1, 2, 1, 1, 2, 1, 2, 1,
   362  	2, 1, 2, 1, 1, 1, 1, 1, 1, 1,
   363  	1, 3, 3, 3, 5, 6, 8, 9, 1, 2,
   364  	6, 7, 7, 1, 2, 5, 5, 6, 6, 1,
   365  	2, 3, 3, 4, 4, 1, 3, 5, 6, 4,
   366  	5, 2, 5, 5, 5, 1, 2, 3, 2, 1,
   367  	3, 1, 2, 1, 2, 1, 2, 2, 1, 1,
   368  	1, 1, 1, 1, 1, 2, 1, 1, 2, 1,
   369  	2, 1, 1, 1, 1, 0, 1, 2,
   370  }
   371  
   372  var yyChk = [...]int{
   373  	-1000, -39, -40, -1, -2, -3, -4, -5, 27, -6,
   374  	-8, -11, -7, -9, 24, -12, -13, -14, -15, -16,
   375  	-17, -18, -19, 25, -31, 26, 7, 28, 9, 30,
   376  	31, 34, 39, 40, -32, 23, -33, -34, -35, 14,
   377  	15, 16, 17, 20, 21, 22, 18, 19, -41, -42,
   378  	43, -38, 12, 13, 4, 5, 6, -5, -30, -31,
   379  	24, -31, 26, -10, -31, 24, 7, -28, -41, -42,
   380  	-28, 24, 25, 24, -28, -28, -28, -32, -33, 24,
   381  	24, -1, 43, -3, -4, -4, -6, -31, -10, -31,
   382  	24, 8, 8, -29, -3, 29, 10, 41, -37, -41,
   383  	13, -42, -41, 36, 41, 41, -41, -36, -38, -42,
   384  	-28, 41, 33, -41, 33, -28, -28, -28, -20, -11,
   385  	-3, -41, 42, -28, -37, -21, -42, 24, -41, 38,
   386  	-27, 35, 37, 42, 42, -30, 42, 41, -37, 24,
   387  	32, -23, -24, -25, -26, -22, 7, 24, 38, -28,
   388  	-28, -28, 41, 32, -25, -26, 32, 8, 6, -22,
   389  	36, 42, -28, -41, -28, 24, 8, -28, 42, 11,
   390  	11, -41, -28, -27, -41, -41, 11, 11, -41, -41,
   391  }
   392  
   393  var yyDef = [...]int{
   394  	2, -2, 105, 3, 6, 7, 9, 12, 0, 14,
   395  	16, 17, 19, 22, 24, 33, 34, 35, 36, 37,
   396  	38, 39, 40, 0, 25, 27, 105, 105, 0, 0,
   397  	0, 105, 105, 105, 83, 0, 85, 0, 0, 88,
   398  	89, 90, 91, 92, 93, 94, 96, 97, 1, 104,
   399  	106, 5, 102, 103, 0, 0, 0, 13, 18, 81,
   400  	21, 26, 28, 23, 29, 31, 0, 0, 0, 104,
   401  	0, 0, 105, 105, 0, 0, 0, 84, 86, 87,
   402  	95, 4, 107, 8, 10, 11, 15, 82, 20, 30,
   403  	32, 105, 41, 78, 79, 42, 43, 105, 0, 0,
   404  	105, -2, 0, 105, 105, 105, 0, 77, 105, 99,
   405  	0, 105, 0, 100, 105, 0, 0, 0, 74, 75,
   406  	80, 98, 44, 0, 0, 0, 101, 48, 0, 67,
   407  	0, 105, 105, 72, 73, 76, 45, 105, 0, 49,
   408  	50, 0, 0, 53, 59, 0, 0, 65, 68, 0,
   409  	71, 0, 105, 51, 54, 60, 52, 105, 0, 0,
   410  	105, 46, 0, 61, 62, 66, 105, 69, 47, 105,
   411  	105, 63, 64, 70, 55, 56, 105, 105, 57, 58,
   412  }
   413  
   414  var yyTok1 = [...]int{
   415  	1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
   416  	43, 3, 3, 3, 3, 3, 3, 3, 3, 3,
   417  	3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
   418  	3, 3, 3, 3, 3, 3, 3, 3, 12, 3,
   419  	7, 8, 3, 3, 3, 3, 3, 3, 3, 3,
   420  	3, 3, 3, 3, 3, 3, 3, 3, 3, 13,
   421  	14, 3, 15, 3, 3, 3, 3, 3, 3, 3,
   422  	3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
   423  	3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
   424  	3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
   425  	3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
   426  	3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
   427  	3, 3, 3, 3, 6,
   428  }
   429  
   430  var yyTok2 = [...]int{
   431  	2, 3, 4, 5, 9, 10, 11, 16, 17, 18,
   432  	19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
   433  	29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
   434  	39, 40, 41, 42,
   435  }
   436  
   437  var yyTok3 = [...]int{
   438  	0,
   439  }
   440  
   441  var yyErrorMessages = [...]struct {
   442  	state int
   443  	token int
   444  	msg   string
   445  }{}
   446  
   447  /*	parser for yacc output	*/
   448  
   449  var (
   450  	yyDebug        = 0
   451  	yyErrorVerbose = false
   452  )
   453  
   454  type yyLexer interface {
   455  	Lex(lval *yySymType) int
   456  	Error(s string)
   457  }
   458  
   459  type yyParser interface {
   460  	Parse(yyLexer) int
   461  	Lookahead() int
   462  }
   463  
   464  type yyParserImpl struct {
   465  	lval  yySymType
   466  	stack [yyInitialStackSize]yySymType
   467  	char  int
   468  }
   469  
   470  func (p *yyParserImpl) Lookahead() int {
   471  	return p.char
   472  }
   473  
   474  func yyNewParser() yyParser {
   475  	return &yyParserImpl{}
   476  }
   477  
   478  const yyFlag = -1000
   479  
   480  func yyTokname(c int) string {
   481  	if c >= 1 && c-1 < len(yyToknames) {
   482  		if yyToknames[c-1] != "" {
   483  			return yyToknames[c-1]
   484  		}
   485  	}
   486  	return __yyfmt__.Sprintf("tok-%v", c)
   487  }
   488  
   489  func yyStatname(s int) string {
   490  	if s >= 0 && s < len(yyStatenames) {
   491  		if yyStatenames[s] != "" {
   492  			return yyStatenames[s]
   493  		}
   494  	}
   495  	return __yyfmt__.Sprintf("state-%v", s)
   496  }
   497  
   498  func yyErrorMessage(state, lookAhead int) string {
   499  	const TOKSTART = 4
   500  
   501  	if !yyErrorVerbose {
   502  		return "syntax error"
   503  	}
   504  
   505  	for _, e := range yyErrorMessages {
   506  		if e.state == state && e.token == lookAhead {
   507  			return "syntax error: " + e.msg
   508  		}
   509  	}
   510  
   511  	res := "syntax error: unexpected " + yyTokname(lookAhead)
   512  
   513  	// To match Bison, suggest at most four expected tokens.
   514  	expected := make([]int, 0, 4)
   515  
   516  	// Look for shiftable tokens.
   517  	base := yyPact[state]
   518  	for tok := TOKSTART; tok-1 < len(yyToknames); tok++ {
   519  		if n := base + tok; n >= 0 && n < yyLast && yyChk[yyAct[n]] == tok {
   520  			if len(expected) == cap(expected) {
   521  				return res
   522  			}
   523  			expected = append(expected, tok)
   524  		}
   525  	}
   526  
   527  	if yyDef[state] == -2 {
   528  		i := 0
   529  		for yyExca[i] != -1 || yyExca[i+1] != state {
   530  			i += 2
   531  		}
   532  
   533  		// Look for tokens that we accept or reduce.
   534  		for i += 2; yyExca[i] >= 0; i += 2 {
   535  			tok := yyExca[i]
   536  			if tok < TOKSTART || yyExca[i+1] == 0 {
   537  				continue
   538  			}
   539  			if len(expected) == cap(expected) {
   540  				return res
   541  			}
   542  			expected = append(expected, tok)
   543  		}
   544  
   545  		// If the default action is to accept or reduce, give up.
   546  		if yyExca[i+1] != 0 {
   547  			return res
   548  		}
   549  	}
   550  
   551  	for i, tok := range expected {
   552  		if i == 0 {
   553  			res += ", expecting "
   554  		} else {
   555  			res += " or "
   556  		}
   557  		res += yyTokname(tok)
   558  	}
   559  	return res
   560  }
   561  
   562  func yylex1(lex yyLexer, lval *yySymType) (char, token int) {
   563  	token = 0
   564  	char = lex.Lex(lval)
   565  	if char <= 0 {
   566  		token = yyTok1[0]
   567  		goto out
   568  	}
   569  	if char < len(yyTok1) {
   570  		token = yyTok1[char]
   571  		goto out
   572  	}
   573  	if char >= yyPrivate {
   574  		if char < yyPrivate+len(yyTok2) {
   575  			token = yyTok2[char-yyPrivate]
   576  			goto out
   577  		}
   578  	}
   579  	for i := 0; i < len(yyTok3); i += 2 {
   580  		token = yyTok3[i+0]
   581  		if token == char {
   582  			token = yyTok3[i+1]
   583  			goto out
   584  		}
   585  	}
   586  
   587  out:
   588  	if token == 0 {
   589  		token = yyTok2[1] /* unknown char */
   590  	}
   591  	if yyDebug >= 3 {
   592  		__yyfmt__.Printf("lex %s(%d)\n", yyTokname(token), uint(char))
   593  	}
   594  	return char, token
   595  }
   596  
   597  func yyParse(yylex yyLexer) int {
   598  	return yyNewParser().Parse(yylex)
   599  }
   600  
   601  func (yyrcvr *yyParserImpl) Parse(yylex yyLexer) int {
   602  	var yyn int
   603  	var yyVAL yySymType
   604  	var yyDollar []yySymType
   605  	_ = yyDollar // silence set and not used
   606  	yyS := yyrcvr.stack[:]
   607  
   608  	Nerrs := 0   /* number of errors */
   609  	Errflag := 0 /* error recovery flag */
   610  	yystate := 0
   611  	yyrcvr.char = -1
   612  	yytoken := -1 // yyrcvr.char translated into internal numbering
   613  	defer func() {
   614  		// Make sure we report no lookahead when not parsing.
   615  		yystate = -1
   616  		yyrcvr.char = -1
   617  		yytoken = -1
   618  	}()
   619  	yyp := -1
   620  	goto yystack
   621  
   622  ret0:
   623  	return 0
   624  
   625  ret1:
   626  	return 1
   627  
   628  yystack:
   629  	/* put a state and value onto the stack */
   630  	if yyDebug >= 4 {
   631  		__yyfmt__.Printf("char %v in %v\n", yyTokname(yytoken), yyStatname(yystate))
   632  	}
   633  
   634  	yyp++
   635  	if yyp >= len(yyS) {
   636  		nyys := make([]yySymType, len(yyS)*2)
   637  		copy(nyys, yyS)
   638  		yyS = nyys
   639  	}
   640  	yyS[yyp] = yyVAL
   641  	yyS[yyp].yys = yystate
   642  
   643  yynewstate:
   644  	yyn = yyPact[yystate]
   645  	if yyn <= yyFlag {
   646  		goto yydefault /* simple state */
   647  	}
   648  	if yyrcvr.char < 0 {
   649  		yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval)
   650  	}
   651  	yyn += yytoken
   652  	if yyn < 0 || yyn >= yyLast {
   653  		goto yydefault
   654  	}
   655  	yyn = yyAct[yyn]
   656  	if yyChk[yyn] == yytoken { /* valid shift */
   657  		yyrcvr.char = -1
   658  		yytoken = -1
   659  		yyVAL = yyrcvr.lval
   660  		yystate = yyn
   661  		if Errflag > 0 {
   662  			Errflag--
   663  		}
   664  		goto yystack
   665  	}
   666  
   667  yydefault:
   668  	/* default state action */
   669  	yyn = yyDef[yystate]
   670  	if yyn == -2 {
   671  		if yyrcvr.char < 0 {
   672  			yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval)
   673  		}
   674  
   675  		/* look through exception table */
   676  		xi := 0
   677  		for {
   678  			if yyExca[xi+0] == -1 && yyExca[xi+1] == yystate {
   679  				break
   680  			}
   681  			xi += 2
   682  		}
   683  		for xi += 2; ; xi += 2 {
   684  			yyn = yyExca[xi+0]
   685  			if yyn < 0 || yyn == yytoken {
   686  				break
   687  			}
   688  		}
   689  		yyn = yyExca[xi+1]
   690  		if yyn < 0 {
   691  			goto ret0
   692  		}
   693  	}
   694  	if yyn == 0 {
   695  		/* error ... attempt to resume parsing */
   696  		switch Errflag {
   697  		case 0: /* brand new error */
   698  			yylex.Error(yyErrorMessage(yystate, yytoken))
   699  			Nerrs++
   700  			if yyDebug >= 1 {
   701  				__yyfmt__.Printf("%s", yyStatname(yystate))
   702  				__yyfmt__.Printf(" saw %s\n", yyTokname(yytoken))
   703  			}
   704  			fallthrough
   705  
   706  		case 1, 2: /* incompletely recovered error ... try again */
   707  			Errflag = 3
   708  
   709  			/* find a state where "error" is a legal shift action */
   710  			for yyp >= 0 {
   711  				yyn = yyPact[yyS[yyp].yys] + yyErrCode
   712  				if yyn >= 0 && yyn < yyLast {
   713  					yystate = yyAct[yyn] /* simulate a shift of "error" */
   714  					if yyChk[yystate] == yyErrCode {
   715  						goto yystack
   716  					}
   717  				}
   718  
   719  				/* the current p has no shift on "error", pop stack */
   720  				if yyDebug >= 2 {
   721  					__yyfmt__.Printf("error recovery pops state %d\n", yyS[yyp].yys)
   722  				}
   723  				yyp--
   724  			}
   725  			/* there is no state on the stack with an error shift ... abort */
   726  			goto ret1
   727  
   728  		case 3: /* no shift yet; clobber input char */
   729  			if yyDebug >= 2 {
   730  				__yyfmt__.Printf("error recovery discards %s\n", yyTokname(yytoken))
   731  			}
   732  			if yytoken == yyEofCode {
   733  				goto ret1
   734  			}
   735  			yyrcvr.char = -1
   736  			yytoken = -1
   737  			goto yynewstate /* try again in the same state */
   738  		}
   739  	}
   740  
   741  	/* reduction by production yyn */
   742  	if yyDebug >= 2 {
   743  		__yyfmt__.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate))
   744  	}
   745  
   746  	yynt := yyn
   747  	yypt := yyp
   748  	_ = yypt // guard against "declared and not used"
   749  
   750  	yyp -= yyR2[yyn]
   751  	// yyp is now the index of $0. Perform the default action. Iff the
   752  	// reduced production is ε, $1 is possibly out of range.
   753  	if yyp+1 >= len(yyS) {
   754  		nyys := make([]yySymType, len(yyS)*2)
   755  		copy(nyys, yyS)
   756  		yyS = nyys
   757  	}
   758  	yyVAL = yyS[yyp+1]
   759  
   760  	/* consult goto table to find next state */
   761  	yyn = yyR1[yyn]
   762  	yyg := yyPgo[yyn]
   763  	yyj := yyg + yyS[yyp].yys + 1
   764  
   765  	if yyj >= yyLast {
   766  		yystate = yyAct[yyg]
   767  	} else {
   768  		yystate = yyAct[yyj]
   769  		if yyChk[yystate] != -yyn {
   770  			yystate = yyAct[yyg]
   771  		}
   772  	}
   773  	// dummy call; replaced with literal code
   774  	switch yynt {
   775  
   776  	case 3:
   777  		yyDollar = yyS[yypt-1 : yypt+1]
   778  		{
   779  			l := yyDollar[1].list.(ast.List)
   780  			if len(l) > 1 {
   781  				yylex.(*lexer).cmds = append(yylex.(*lexer).cmds, l)
   782  			} else {
   783  				yylex.(*lexer).cmds = append(yylex.(*lexer).cmds, extract(l[0]))
   784  			}
   785  		}
   786  	case 4:
   787  		yyDollar = yyS[yypt-3 : yypt+1]
   788  		{
   789  			l := yyDollar[3].list.(ast.List)
   790  			if len(l) > 1 {
   791  				yylex.(*lexer).cmds = append(yylex.(*lexer).cmds, l)
   792  			} else {
   793  				yylex.(*lexer).cmds = append(yylex.(*lexer).cmds, extract(l[0]))
   794  			}
   795  		}
   796  	case 5:
   797  		yyDollar = yyS[yypt-2 : yypt+1]
   798  		{
   799  			l := yyDollar[1].list.(ast.List)
   800  			ao := l[len(l)-1]
   801  			ao.SepPos = yyDollar[2].token.pos
   802  			ao.Sep = yyDollar[2].token.val
   803  		}
   804  	case 7:
   805  		yyDollar = yyS[yypt-1 : yypt+1]
   806  		{
   807  			yyVAL.list = ast.List{yyDollar[1].node.(*ast.AndOrList)}
   808  		}
   809  	case 8:
   810  		yyDollar = yyS[yypt-3 : yypt+1]
   811  		{
   812  			l := yyVAL.list.(ast.List)
   813  			ao := l[len(l)-1]
   814  			ao.SepPos = yyDollar[2].token.pos
   815  			ao.Sep = yyDollar[2].token.val
   816  			yyVAL.list = append(l, yyDollar[3].node.(*ast.AndOrList))
   817  		}
   818  	case 9:
   819  		yyDollar = yyS[yypt-1 : yypt+1]
   820  		{
   821  			yyVAL.node = &ast.AndOrList{Pipeline: yyDollar[1].node.(*ast.Pipeline)}
   822  		}
   823  	case 10:
   824  		yyDollar = yyS[yypt-3 : yypt+1]
   825  		{
   826  			yyVAL.node.(*ast.AndOrList).List = append(yyVAL.node.(*ast.AndOrList).List, &ast.AndOr{
   827  				OpPos:    yyDollar[2].token.pos,
   828  				Op:       yyDollar[2].token.val,
   829  				Pipeline: yyDollar[3].node.(*ast.Pipeline),
   830  			})
   831  		}
   832  	case 11:
   833  		yyDollar = yyS[yypt-3 : yypt+1]
   834  		{
   835  			yyVAL.node.(*ast.AndOrList).List = append(yyVAL.node.(*ast.AndOrList).List, &ast.AndOr{
   836  				OpPos:    yyDollar[2].token.pos,
   837  				Op:       yyDollar[2].token.val,
   838  				Pipeline: yyDollar[3].node.(*ast.Pipeline),
   839  			})
   840  		}
   841  	case 13:
   842  		yyDollar = yyS[yypt-2 : yypt+1]
   843  		{
   844  			yyVAL.node = yyDollar[2].node
   845  			yyVAL.node.(*ast.Pipeline).Bang = yyDollar[1].token.pos
   846  		}
   847  	case 14:
   848  		yyDollar = yyS[yypt-1 : yypt+1]
   849  		{
   850  			yyVAL.node = &ast.Pipeline{Cmd: yyDollar[1].node.(*ast.Cmd)}
   851  		}
   852  	case 15:
   853  		yyDollar = yyS[yypt-3 : yypt+1]
   854  		{
   855  			yyVAL.node.(*ast.Pipeline).List = append(yyVAL.node.(*ast.Pipeline).List, &ast.Pipe{
   856  				OpPos: yyDollar[2].token.pos,
   857  				Op:    yyDollar[2].token.val,
   858  				Cmd:   yyDollar[3].node.(*ast.Cmd),
   859  			})
   860  		}
   861  	case 16:
   862  		yyDollar = yyS[yypt-1 : yypt+1]
   863  		{
   864  			yyVAL.node = &ast.Cmd{
   865  				Expr: &ast.SimpleCmd{
   866  					Assigns: yyDollar[1].elt.assigns,
   867  					Args:    yyDollar[1].elt.args,
   868  				},
   869  				Redirs: yyDollar[1].elt.redirs,
   870  			}
   871  		}
   872  	case 17:
   873  		yyDollar = yyS[yypt-1 : yypt+1]
   874  		{
   875  			yyVAL.node = &ast.Cmd{Expr: yyDollar[1].node.(ast.CmdExpr)}
   876  		}
   877  	case 18:
   878  		yyDollar = yyS[yypt-2 : yypt+1]
   879  		{
   880  			yyVAL.node = &ast.Cmd{
   881  				Expr:   yyDollar[1].node.(ast.CmdExpr),
   882  				Redirs: yyDollar[2].list.([]*ast.Redir),
   883  			}
   884  		}
   885  	case 20:
   886  		yyDollar = yyS[yypt-3 : yypt+1]
   887  		{
   888  			yyVAL.elt = &element{
   889  				redirs:  append(yyDollar[1].elt.redirs, yyDollar[3].elt.redirs...),
   890  				assigns: yyDollar[1].elt.assigns,
   891  				args:    append([]ast.Word{yyDollar[2].word}, yyDollar[3].elt.args...),
   892  			}
   893  		}
   894  	case 21:
   895  		yyDollar = yyS[yypt-2 : yypt+1]
   896  		{
   897  			yyVAL.elt = yyDollar[1].elt
   898  			yyVAL.elt.args = append(yyVAL.elt.args, yyDollar[2].word)
   899  		}
   900  	case 23:
   901  		yyDollar = yyS[yypt-2 : yypt+1]
   902  		{
   903  			yyVAL.elt = &element{
   904  				redirs: yyDollar[2].elt.redirs,
   905  				args:   append([]ast.Word{yyDollar[1].word}, yyDollar[2].elt.args...),
   906  			}
   907  		}
   908  	case 24:
   909  		yyDollar = yyS[yypt-1 : yypt+1]
   910  		{
   911  			yyVAL.elt = &element{args: []ast.Word{yyDollar[1].word}}
   912  		}
   913  	case 25:
   914  		yyDollar = yyS[yypt-1 : yypt+1]
   915  		{
   916  			yyVAL.elt = &element{redirs: []*ast.Redir{yyDollar[1].node.(*ast.Redir)}}
   917  		}
   918  	case 26:
   919  		yyDollar = yyS[yypt-2 : yypt+1]
   920  		{
   921  			yyVAL.elt.redirs = append(yyVAL.elt.redirs, yyDollar[2].node.(*ast.Redir))
   922  		}
   923  	case 27:
   924  		yyDollar = yyS[yypt-1 : yypt+1]
   925  		{
   926  			yyVAL.elt = &element{assigns: []*ast.Assign{assign(yyDollar[1].word)}}
   927  		}
   928  	case 28:
   929  		yyDollar = yyS[yypt-2 : yypt+1]
   930  		{
   931  			yyVAL.elt.assigns = append(yyVAL.elt.assigns, assign(yyDollar[2].word))
   932  		}
   933  	case 29:
   934  		yyDollar = yyS[yypt-1 : yypt+1]
   935  		{
   936  			yyVAL.elt = &element{redirs: []*ast.Redir{yyDollar[1].node.(*ast.Redir)}}
   937  		}
   938  	case 30:
   939  		yyDollar = yyS[yypt-2 : yypt+1]
   940  		{
   941  			yyVAL.elt.redirs = append(yyVAL.elt.redirs, yyDollar[2].node.(*ast.Redir))
   942  		}
   943  	case 31:
   944  		yyDollar = yyS[yypt-1 : yypt+1]
   945  		{
   946  			yyVAL.elt = &element{args: []ast.Word{yyDollar[1].word}}
   947  		}
   948  	case 32:
   949  		yyDollar = yyS[yypt-2 : yypt+1]
   950  		{
   951  			yyVAL.elt.args = append(yyVAL.elt.args, yyDollar[2].word)
   952  		}
   953  	case 41:
   954  		yyDollar = yyS[yypt-3 : yypt+1]
   955  		{
   956  			yyVAL.node = &ast.Subshell{
   957  				Lparen: yyDollar[1].token.pos,
   958  				List:   yyDollar[2].list.([]ast.Command),
   959  				Rparen: yyDollar[3].token.pos,
   960  			}
   961  		}
   962  	case 42:
   963  		yyDollar = yyS[yypt-3 : yypt+1]
   964  		{
   965  			yyVAL.node = &ast.Group{
   966  				Lbrace: yyDollar[1].token.pos,
   967  				List:   yyDollar[2].list.([]ast.Command),
   968  				Rbrace: yyDollar[3].token.pos,
   969  			}
   970  		}
   971  	case 43:
   972  		yyDollar = yyS[yypt-3 : yypt+1]
   973  		{
   974  			yyVAL.node = &ast.ArithEval{
   975  				Left:  yyDollar[1].token.pos,
   976  				Expr:  yyDollar[2].word,
   977  				Right: yyDollar[3].token.pos,
   978  			}
   979  		}
   980  	case 44:
   981  		yyDollar = yyS[yypt-5 : yypt+1]
   982  		{
   983  			yyVAL.node = &ast.ForClause{
   984  				For:  yyDollar[1].token.pos,
   985  				Name: yyDollar[2].word[0].(*ast.Lit),
   986  				Do:   yyDollar[3].token.pos,
   987  				List: yyDollar[4].list.([]ast.Command),
   988  				Done: yyDollar[5].token.pos,
   989  			}
   990  		}
   991  	case 45:
   992  		yyDollar = yyS[yypt-6 : yypt+1]
   993  		{
   994  			yyVAL.node = &ast.ForClause{
   995  				For:       yyDollar[1].token.pos,
   996  				Name:      yyDollar[2].word[0].(*ast.Lit),
   997  				Semicolon: yyDollar[3].token.pos,
   998  				Do:        yyDollar[4].token.pos,
   999  				List:      yyDollar[5].list.([]ast.Command),
  1000  				Done:      yyDollar[6].token.pos,
  1001  			}
  1002  		}
  1003  	case 46:
  1004  		yyDollar = yyS[yypt-8 : yypt+1]
  1005  		{
  1006  			yyVAL.node = &ast.ForClause{
  1007  				For:       yyDollar[1].token.pos,
  1008  				Name:      yyDollar[2].word[0].(*ast.Lit),
  1009  				In:        yyDollar[4].token.pos,
  1010  				Semicolon: yyDollar[5].token.pos,
  1011  				Do:        yyDollar[6].token.pos,
  1012  				List:      yyDollar[7].list.([]ast.Command),
  1013  				Done:      yyDollar[8].token.pos,
  1014  			}
  1015  		}
  1016  	case 47:
  1017  		yyDollar = yyS[yypt-9 : yypt+1]
  1018  		{
  1019  			yyVAL.node = &ast.ForClause{
  1020  				For:       yyDollar[1].token.pos,
  1021  				Name:      yyDollar[2].word[0].(*ast.Lit),
  1022  				In:        yyDollar[4].token.pos,
  1023  				Items:     yyDollar[5].list.([]ast.Word),
  1024  				Semicolon: yyDollar[6].token.pos,
  1025  				Do:        yyDollar[7].token.pos,
  1026  				List:      yyDollar[8].list.([]ast.Command),
  1027  				Done:      yyDollar[9].token.pos,
  1028  			}
  1029  		}
  1030  	case 48:
  1031  		yyDollar = yyS[yypt-1 : yypt+1]
  1032  		{
  1033  			yyVAL.list = []ast.Word{yyDollar[1].word}
  1034  		}
  1035  	case 49:
  1036  		yyDollar = yyS[yypt-2 : yypt+1]
  1037  		{
  1038  			yyVAL.list = append(yyVAL.list.([]ast.Word), yyDollar[2].word)
  1039  		}
  1040  	case 50:
  1041  		yyDollar = yyS[yypt-6 : yypt+1]
  1042  		{
  1043  			yyVAL.node = &ast.CaseClause{
  1044  				Case: yyDollar[1].token.pos,
  1045  				Word: yyDollar[2].word,
  1046  				In:   yyDollar[4].token.pos,
  1047  				Esac: yyDollar[6].token.pos,
  1048  			}
  1049  		}
  1050  	case 51:
  1051  		yyDollar = yyS[yypt-7 : yypt+1]
  1052  		{
  1053  			yyVAL.node = &ast.CaseClause{
  1054  				Case:  yyDollar[1].token.pos,
  1055  				Word:  yyDollar[2].word,
  1056  				In:    yyDollar[4].token.pos,
  1057  				Items: yyDollar[6].list.([]*ast.CaseItem),
  1058  				Esac:  yyDollar[7].token.pos,
  1059  			}
  1060  		}
  1061  	case 52:
  1062  		yyDollar = yyS[yypt-7 : yypt+1]
  1063  		{
  1064  			yyVAL.node = &ast.CaseClause{
  1065  				Case:  yyDollar[1].token.pos,
  1066  				Word:  yyDollar[2].word,
  1067  				In:    yyDollar[4].token.pos,
  1068  				Items: yyDollar[6].list.([]*ast.CaseItem),
  1069  				Esac:  yyDollar[7].token.pos,
  1070  			}
  1071  		}
  1072  	case 53:
  1073  		yyDollar = yyS[yypt-1 : yypt+1]
  1074  		{
  1075  			yyVAL.list = []*ast.CaseItem{yyDollar[1].node.(*ast.CaseItem)}
  1076  		}
  1077  	case 54:
  1078  		yyDollar = yyS[yypt-2 : yypt+1]
  1079  		{
  1080  			yyVAL.list = append(yyVAL.list.([]*ast.CaseItem), yyDollar[2].node.(*ast.CaseItem))
  1081  		}
  1082  	case 55:
  1083  		yyDollar = yyS[yypt-5 : yypt+1]
  1084  		{
  1085  			yyVAL.node = &ast.CaseItem{
  1086  				Patterns: yyDollar[1].list.([]ast.Word),
  1087  				Rparen:   yyDollar[2].token.pos,
  1088  				Break:    yyDollar[4].token.pos,
  1089  			}
  1090  		}
  1091  	case 56:
  1092  		yyDollar = yyS[yypt-5 : yypt+1]
  1093  		{
  1094  			yyVAL.node = &ast.CaseItem{
  1095  				Patterns: yyDollar[1].list.([]ast.Word),
  1096  				Rparen:   yyDollar[2].token.pos,
  1097  				List:     yyDollar[3].list.([]ast.Command),
  1098  				Break:    yyDollar[4].token.pos,
  1099  			}
  1100  		}
  1101  	case 57:
  1102  		yyDollar = yyS[yypt-6 : yypt+1]
  1103  		{
  1104  			yyVAL.node = &ast.CaseItem{
  1105  				Lparen:   yyDollar[1].token.pos,
  1106  				Patterns: yyDollar[2].list.([]ast.Word),
  1107  				Rparen:   yyDollar[3].token.pos,
  1108  				Break:    yyDollar[5].token.pos,
  1109  			}
  1110  		}
  1111  	case 58:
  1112  		yyDollar = yyS[yypt-6 : yypt+1]
  1113  		{
  1114  			yyVAL.node = &ast.CaseItem{
  1115  				Lparen:   yyDollar[1].token.pos,
  1116  				Patterns: yyDollar[2].list.([]ast.Word),
  1117  				Rparen:   yyDollar[3].token.pos,
  1118  				List:     yyDollar[4].list.([]ast.Command),
  1119  				Break:    yyDollar[5].token.pos,
  1120  			}
  1121  		}
  1122  	case 59:
  1123  		yyDollar = yyS[yypt-1 : yypt+1]
  1124  		{
  1125  			yyVAL.list = []*ast.CaseItem{yyDollar[1].node.(*ast.CaseItem)}
  1126  		}
  1127  	case 60:
  1128  		yyDollar = yyS[yypt-2 : yypt+1]
  1129  		{
  1130  			yyVAL.list = append(yyVAL.list.([]*ast.CaseItem), yyDollar[2].node.(*ast.CaseItem))
  1131  		}
  1132  	case 61:
  1133  		yyDollar = yyS[yypt-3 : yypt+1]
  1134  		{
  1135  			yyVAL.node = &ast.CaseItem{
  1136  				Patterns: yyDollar[1].list.([]ast.Word),
  1137  				Rparen:   yyDollar[2].token.pos,
  1138  			}
  1139  		}
  1140  	case 62:
  1141  		yyDollar = yyS[yypt-3 : yypt+1]
  1142  		{
  1143  			yyVAL.node = &ast.CaseItem{
  1144  				Patterns: yyDollar[1].list.([]ast.Word),
  1145  				Rparen:   yyDollar[2].token.pos,
  1146  				List:     yyDollar[3].list.([]ast.Command),
  1147  			}
  1148  		}
  1149  	case 63:
  1150  		yyDollar = yyS[yypt-4 : yypt+1]
  1151  		{
  1152  			yyVAL.node = &ast.CaseItem{
  1153  				Lparen:   yyDollar[1].token.pos,
  1154  				Patterns: yyDollar[2].list.([]ast.Word),
  1155  				Rparen:   yyDollar[3].token.pos,
  1156  			}
  1157  		}
  1158  	case 64:
  1159  		yyDollar = yyS[yypt-4 : yypt+1]
  1160  		{
  1161  			yyVAL.node = &ast.CaseItem{
  1162  				Lparen:   yyDollar[1].token.pos,
  1163  				Patterns: yyDollar[2].list.([]ast.Word),
  1164  				Rparen:   yyDollar[3].token.pos,
  1165  				List:     yyDollar[4].list.([]ast.Command),
  1166  			}
  1167  		}
  1168  	case 65:
  1169  		yyDollar = yyS[yypt-1 : yypt+1]
  1170  		{
  1171  			yyVAL.list = []ast.Word{yyDollar[1].word}
  1172  		}
  1173  	case 66:
  1174  		yyDollar = yyS[yypt-3 : yypt+1]
  1175  		{
  1176  			yyVAL.list = append(yyVAL.list.([]ast.Word), yyDollar[3].word)
  1177  		}
  1178  	case 67:
  1179  		yyDollar = yyS[yypt-5 : yypt+1]
  1180  		{
  1181  			yyVAL.node = &ast.IfClause{
  1182  				If:   yyDollar[1].token.pos,
  1183  				Cond: yyDollar[2].list.([]ast.Command),
  1184  				Then: yyDollar[3].token.pos,
  1185  				List: yyDollar[4].list.([]ast.Command),
  1186  				Fi:   yyDollar[5].token.pos,
  1187  			}
  1188  		}
  1189  	case 68:
  1190  		yyDollar = yyS[yypt-6 : yypt+1]
  1191  		{
  1192  			yyVAL.node = &ast.IfClause{
  1193  				If:   yyDollar[1].token.pos,
  1194  				Cond: yyDollar[2].list.([]ast.Command),
  1195  				Then: yyDollar[3].token.pos,
  1196  				List: yyDollar[4].list.([]ast.Command),
  1197  				Else: yyDollar[5].list.([]ast.ElsePart),
  1198  				Fi:   yyDollar[6].token.pos,
  1199  			}
  1200  		}
  1201  	case 69:
  1202  		yyDollar = yyS[yypt-4 : yypt+1]
  1203  		{
  1204  			yyVAL.list = []ast.ElsePart{&ast.ElifClause{
  1205  				Elif: yyDollar[1].token.pos,
  1206  				Cond: yyDollar[2].list.([]ast.Command),
  1207  				Then: yyDollar[3].token.pos,
  1208  				List: yyDollar[4].list.([]ast.Command),
  1209  			}}
  1210  		}
  1211  	case 70:
  1212  		yyDollar = yyS[yypt-5 : yypt+1]
  1213  		{
  1214  			yyVAL.list = append([]ast.ElsePart{&ast.ElifClause{
  1215  				Elif: yyDollar[1].token.pos,
  1216  				Cond: yyDollar[2].list.([]ast.Command),
  1217  				Then: yyDollar[3].token.pos,
  1218  				List: yyDollar[4].list.([]ast.Command),
  1219  			}}, yyDollar[5].list.([]ast.ElsePart)...)
  1220  		}
  1221  	case 71:
  1222  		yyDollar = yyS[yypt-2 : yypt+1]
  1223  		{
  1224  			yyVAL.list = []ast.ElsePart{&ast.ElseClause{
  1225  				Else: yyDollar[1].token.pos,
  1226  				List: yyDollar[2].list.([]ast.Command),
  1227  			}}
  1228  		}
  1229  	case 72:
  1230  		yyDollar = yyS[yypt-5 : yypt+1]
  1231  		{
  1232  			yyVAL.node = &ast.WhileClause{
  1233  				While: yyDollar[1].token.pos,
  1234  				Cond:  yyDollar[2].list.([]ast.Command),
  1235  				Do:    yyDollar[3].token.pos,
  1236  				List:  yyDollar[4].list.([]ast.Command),
  1237  				Done:  yyDollar[5].token.pos,
  1238  			}
  1239  		}
  1240  	case 73:
  1241  		yyDollar = yyS[yypt-5 : yypt+1]
  1242  		{
  1243  			yyVAL.node = &ast.UntilClause{
  1244  				Until: yyDollar[1].token.pos,
  1245  				Cond:  yyDollar[2].list.([]ast.Command),
  1246  				Do:    yyDollar[3].token.pos,
  1247  				List:  yyDollar[4].list.([]ast.Command),
  1248  				Done:  yyDollar[5].token.pos,
  1249  			}
  1250  		}
  1251  	case 74:
  1252  		yyDollar = yyS[yypt-5 : yypt+1]
  1253  		{
  1254  			x := yyDollar[5].node.(*ast.FuncDef)
  1255  			x.Name = yyDollar[1].word[0].(*ast.Lit)
  1256  			x.Lparen = yyDollar[2].token.pos
  1257  			x.Rparen = yyDollar[3].token.pos
  1258  			yyVAL.node = &ast.Cmd{Expr: yyDollar[5].node.(ast.CmdExpr)}
  1259  		}
  1260  	case 75:
  1261  		yyDollar = yyS[yypt-1 : yypt+1]
  1262  		{
  1263  			yyVAL.node = &ast.FuncDef{
  1264  				Body: &ast.Cmd{
  1265  					Expr: yyDollar[1].node.(ast.CmdExpr),
  1266  				},
  1267  			}
  1268  		}
  1269  	case 76:
  1270  		yyDollar = yyS[yypt-2 : yypt+1]
  1271  		{
  1272  			yyVAL.node = &ast.FuncDef{
  1273  				Body: &ast.Cmd{
  1274  					Expr:   yyDollar[1].node.(ast.CmdExpr),
  1275  					Redirs: yyDollar[2].list.([]*ast.Redir),
  1276  				},
  1277  			}
  1278  		}
  1279  	case 77:
  1280  		yyDollar = yyS[yypt-3 : yypt+1]
  1281  		{
  1282  			cmds := yyDollar[2].list.([]ast.Command)
  1283  			l := cmds[len(cmds)-1].(ast.List)
  1284  			if yyDollar[3].token.typ != '\n' {
  1285  				ao := l[len(l)-1]
  1286  				ao.SepPos = yyDollar[3].token.pos
  1287  				ao.Sep = yyDollar[3].token.val
  1288  			}
  1289  			if len(l) == 1 {
  1290  				cmds[len(cmds)-1] = extract(l[0])
  1291  			}
  1292  			yyVAL.list = yyDollar[2].list
  1293  		}
  1294  	case 78:
  1295  		yyDollar = yyS[yypt-2 : yypt+1]
  1296  		{
  1297  			cmds := yyDollar[2].list.([]ast.Command)
  1298  			l := cmds[len(cmds)-1].(ast.List)
  1299  			if len(l) == 1 {
  1300  				cmds[len(cmds)-1] = extract(l[0])
  1301  			}
  1302  			yyVAL.list = yyDollar[2].list
  1303  		}
  1304  	case 79:
  1305  		yyDollar = yyS[yypt-1 : yypt+1]
  1306  		{
  1307  			yyVAL.list = []ast.Command{ast.List{yyDollar[1].node.(*ast.AndOrList)}}
  1308  		}
  1309  	case 80:
  1310  		yyDollar = yyS[yypt-3 : yypt+1]
  1311  		{
  1312  			cmds := yyVAL.list.([]ast.Command)
  1313  			l := cmds[len(cmds)-1].(ast.List)
  1314  			if yyDollar[2].token.typ != '\n' {
  1315  				ao := l[len(l)-1]
  1316  				ao.SepPos = yyDollar[2].token.pos
  1317  				ao.Sep = yyDollar[2].token.val
  1318  				cmds[len(cmds)-1] = append(l, yyDollar[3].node.(*ast.AndOrList))
  1319  			} else {
  1320  				if len(l) == 1 {
  1321  					cmds[len(cmds)-1] = extract(l[0])
  1322  				}
  1323  				yyVAL.list = append(cmds, ast.List{yyDollar[3].node.(*ast.AndOrList)})
  1324  			}
  1325  		}
  1326  	case 81:
  1327  		yyDollar = yyS[yypt-1 : yypt+1]
  1328  		{
  1329  			yyVAL.list = []*ast.Redir{yyDollar[1].node.(*ast.Redir)}
  1330  		}
  1331  	case 82:
  1332  		yyDollar = yyS[yypt-2 : yypt+1]
  1333  		{
  1334  			yyVAL.list = append(yyVAL.list.([]*ast.Redir), yyDollar[2].node.(*ast.Redir))
  1335  		}
  1336  	case 84:
  1337  		yyDollar = yyS[yypt-2 : yypt+1]
  1338  		{
  1339  			yyVAL.node = yyDollar[2].node
  1340  			yyVAL.node.(*ast.Redir).N = yyDollar[1].word[0].(*ast.Lit)
  1341  		}
  1342  	case 86:
  1343  		yyDollar = yyS[yypt-2 : yypt+1]
  1344  		{
  1345  			yyVAL.node = yyDollar[2].node
  1346  			yyVAL.node.(*ast.Redir).N = yyDollar[1].word[0].(*ast.Lit)
  1347  		}
  1348  	case 87:
  1349  		yyDollar = yyS[yypt-2 : yypt+1]
  1350  		{
  1351  			yyVAL.node = &ast.Redir{
  1352  				OpPos: yyDollar[1].token.pos,
  1353  				Op:    yyDollar[1].token.val,
  1354  				Word:  yyDollar[2].word,
  1355  			}
  1356  		}
  1357  	case 95:
  1358  		yyDollar = yyS[yypt-2 : yypt+1]
  1359  		{
  1360  			yyVAL.node = &ast.Redir{
  1361  				OpPos: yyDollar[1].token.pos,
  1362  				Op:    yyDollar[1].token.val,
  1363  				Word:  yyDollar[2].word,
  1364  			}
  1365  			yylex.(*lexer).heredoc.push(yyVAL.node.(*ast.Redir))
  1366  		}
  1367  	case 99:
  1368  		yyDollar = yyS[yypt-1 : yypt+1]
  1369  		{
  1370  		}
  1371  	case 101:
  1372  		yyDollar = yyS[yypt-1 : yypt+1]
  1373  		{
  1374  			yyVAL.token.pos = ast.Pos{}
  1375  		}
  1376  	}
  1377  	goto yystack /* stack new state and value */
  1378  }