github.com/hirochachacha/plua@v0.0.0-20170217012138-c82f520cc725/compiler/parser/parser.go (about)

     1  // Original: src/go/parser/parser.go
     2  //
     3  // Copyright 2009 The Go Authors. All rights reserved.
     4  // Portions Copyright 2016 Hiroshi Ioka. All rights reserved.
     5  //
     6  // Redistribution and use in source and binary forms, with or without
     7  // modification, are permitted provided that the following conditions are
     8  // met:
     9  //
    10  //    * Redistributions of source code must retain the above copyright
    11  // notice, this list of conditions and the following disclaimer.
    12  //    * Redistributions in binary form must reproduce the above
    13  // copyright notice, this list of conditions and the following disclaimer
    14  // in the documentation and/or other materials provided with the
    15  // distribution.
    16  //    * Neither the name of Google Inc. nor the names of its
    17  // contributors may be used to endorse or promote products derived from
    18  // this software without specific prior written permission.
    19  //
    20  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    21  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    22  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    23  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    24  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    25  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    26  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    27  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    28  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    29  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    30  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31  
    32  package parser
    33  
    34  import (
    35  	"errors"
    36  	"fmt"
    37  	"os"
    38  
    39  	"github.com/hirochachacha/plua/compiler/ast"
    40  	"github.com/hirochachacha/plua/compiler/scanner"
    41  	"github.com/hirochachacha/plua/compiler/token"
    42  	"github.com/hirochachacha/plua/position"
    43  )
    44  
    45  var (
    46  	errIllegalVararg = errors.New("cannot use '...' outside of vararg function")
    47  	errIllegalBreak  = errors.New("cannot use 'break' outside of loop")
    48  )
    49  
    50  type Mode uint
    51  
    52  const (
    53  	ParseComments Mode = 1 << iota
    54  )
    55  
    56  func ParseFile(filename string, mode Mode) (*ast.File, error) {
    57  	f, err := os.Open(filename)
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  	defer f.Close()
    62  
    63  	var m scanner.Mode
    64  	if mode&ParseComments != 0 {
    65  		m = scanner.ScanComments
    66  	}
    67  
    68  	s := scanner.Scan(f, "@"+filename, m)
    69  
    70  	return Parse(s, mode)
    71  }
    72  
    73  func Parse(s *scanner.ScanState, mode Mode) (f *ast.File, err error) {
    74  	p := &parser{
    75  		scanState: s,
    76  	}
    77  
    78  	defer func() {
    79  		if r := recover(); r != nil {
    80  			_ = r.(bailout)
    81  
    82  			err = p.err
    83  		}
    84  	}()
    85  
    86  	p.next()
    87  
    88  	f = p.parseFile()
    89  
    90  	return
    91  }
    92  
    93  // The parser structure holds the parser's internal state.
    94  type parser struct {
    95  	scanState *scanner.ScanState
    96  
    97  	// Comments
    98  	comments    []*ast.CommentGroup
    99  	leadComment *ast.CommentGroup // last lead comment
   100  	lineComment *ast.CommentGroup // last line comment
   101  
   102  	// Next token
   103  	tok token.Token
   104  
   105  	// allow vararg in this function scope?
   106  	allowEllipsis bool
   107  
   108  	// allow break in this scope?
   109  	allowBreak bool
   110  
   111  	err error
   112  }
   113  
   114  type bailout struct{}
   115  
   116  func (p *parser) markLHS(x ast.Expr) {
   117  	// switch t := x.(type) {
   118  	// case *ast.Name:
   119  	// t.IsLHS = true
   120  	// case *ast.SelectorExpr:
   121  	// t.IsLHS = true
   122  	// case *ast.IndexExpr:
   123  	// t.IsLHS = true
   124  	// }
   125  }
   126  
   127  func (p *parser) markRHS(x ast.Expr) {
   128  	// switch t := x.(type) {
   129  	// case *ast.Name:
   130  	// if !t.IsLHS {
   131  	// panic("name already marked as RHS")
   132  	// }
   133  
   134  	// t.IsLHS = false
   135  	// case *ast.SelectorExpr:
   136  	// if !t.IsLHS {
   137  	// panic("selector expression already marked as RHS")
   138  	// }
   139  
   140  	// t.IsLHS = false
   141  	// case *ast.IndexExpr:
   142  	// if !t.IsLHS {
   143  	// panic("index expression already marked as RHS")
   144  	// }
   145  
   146  	// t.IsLHS = false
   147  	// }
   148  }
   149  
   150  // ----------------------------------------------------------------------------
   151  // Parsing support
   152  
   153  // Advance to the next token.
   154  func (p *parser) next0() {
   155  	tok, err := p.scanState.Token()
   156  	if err != nil {
   157  		p.err = err
   158  		panic(bailout{})
   159  	}
   160  	p.tok = tok
   161  }
   162  
   163  // Consume a comment and return it and the line on which it ends.
   164  func (p *parser) consumeComment() (comment *ast.Comment, endLine int) {
   165  	endLine = p.tok.Pos.Line
   166  	for _, r := range p.tok.Lit {
   167  		if r == '\n' {
   168  			endLine++
   169  		}
   170  	}
   171  
   172  	if p.tok.Type == token.COMMENT {
   173  		comment = &ast.Comment{Hyphen: p.tok.Pos, Text: p.tok.Lit}
   174  		p.next0()
   175  
   176  		return
   177  	}
   178  
   179  	comment = &ast.Comment{Hyphen: p.tok.Pos, Text: p.tok.Lit}
   180  	p.next0()
   181  
   182  	return
   183  }
   184  
   185  // Consume a group of adjacent comments, add it to the parser's
   186  // comments list, and return it together with the line at which
   187  // the last comment in the group ends. A non-comment token or n
   188  // empty lines terminate a comment group.
   189  //
   190  func (p *parser) consumeCommentGroup(n int) (comments *ast.CommentGroup, endLine int) {
   191  	var list []*ast.Comment
   192  	endLine = p.tok.Pos.Line
   193  	for p.tok.Type == token.COMMENT && p.tok.Pos.Line <= endLine+n {
   194  		var comment *ast.Comment
   195  		comment, endLine = p.consumeComment()
   196  		list = append(list, comment)
   197  	}
   198  
   199  	// add comment group to the comments list
   200  	comments = &ast.CommentGroup{List: list}
   201  	p.comments = append(p.comments, comments)
   202  
   203  	return
   204  }
   205  
   206  // Advance to the next non-comment token. In the process, collect
   207  // any comment groups encountered, and remember the last lead and
   208  // and line comments.
   209  //
   210  // A lead comment is a comment group that starts and ends in a
   211  // line without any other tokens and that is followed by a non-comment
   212  // token on the line immediately after the comment group.
   213  //
   214  // A line comment is a comment group that follows a non-comment
   215  // token on the same line, and that has no tokens after it on the line
   216  // where it ends.
   217  //
   218  // Lead and line comments may be considered documentation that is
   219  // stored in the AST.
   220  //
   221  func (p *parser) next() {
   222  	p.leadComment = nil
   223  	p.lineComment = nil
   224  	prevLine := p.tok.Pos.Line
   225  	p.next0()
   226  
   227  	if p.tok.Type == token.COMMENT {
   228  		var comment *ast.CommentGroup
   229  		var endLine int
   230  
   231  		if p.tok.Pos.Line == prevLine {
   232  			// The comment is on same line as the previous token; it
   233  			// cannot be a lead comment but may be a line comment.
   234  			comment, endLine = p.consumeCommentGroup(0)
   235  			if p.tok.Pos.Line != endLine {
   236  				// The next token is on a different line, thus
   237  				// the last comment group is a line comment.
   238  				p.lineComment = comment
   239  			}
   240  		}
   241  
   242  		// consume successor comments, if any
   243  		endLine = -1
   244  		for p.tok.Type == token.COMMENT {
   245  			comment, endLine = p.consumeCommentGroup(1)
   246  		}
   247  
   248  		if endLine+1 == p.tok.Pos.Line {
   249  			// The next token is following on the line immediately after the
   250  			// comment group, thus the last comment group is a lead comment.
   251  			p.leadComment = comment
   252  		}
   253  	}
   254  }
   255  
   256  func (p *parser) error(pos position.Position, err error) {
   257  	pos.SourceName = p.scanState.SourceName()
   258  
   259  	p.err = &Error{
   260  		Pos: pos,
   261  		Err: err,
   262  	}
   263  
   264  	panic(bailout{})
   265  }
   266  
   267  func (p *parser) errorExpected(actual token.Token, expected string) {
   268  	found := "'" + actual.Type.String() + "'"
   269  	if len(actual.Lit) > 0 {
   270  		found += " " + actual.Lit
   271  	}
   272  
   273  	p.error(actual.Pos, fmt.Errorf("expected %s, found %s", expected, found))
   274  }
   275  
   276  func (p *parser) expect(expected token.Type) position.Position {
   277  	if p.tok.Type != expected {
   278  		p.errorExpected(p.tok, "'"+expected.String()+"'")
   279  
   280  		return position.NoPos
   281  	}
   282  
   283  	pos := p.tok.Pos
   284  
   285  	p.next() // make progress
   286  
   287  	return pos
   288  }
   289  
   290  func (p *parser) skip() position.Position {
   291  	pos := p.tok.Pos
   292  
   293  	p.next() // make progress
   294  
   295  	return pos
   296  }
   297  
   298  func (p *parser) accept(tok token.Type, toks ...token.Type) bool {
   299  	if p.tok.Type == tok {
   300  		p.next() // make progress
   301  		return true
   302  	}
   303  
   304  	for _, tok := range toks {
   305  		if p.tok.Type == tok {
   306  			p.next() // make progress
   307  			return true
   308  		}
   309  	}
   310  	return false
   311  }
   312  
   313  // ----------------------------------------------------------------------------
   314  // Name
   315  
   316  func (p *parser) parseName() *ast.Name {
   317  	pos := p.tok.Pos
   318  	name := "_"
   319  	if p.tok.Type == token.NAME {
   320  		name = p.tok.Lit
   321  		p.next()
   322  	} else {
   323  		p.expect(token.NAME) // use expect() error handling
   324  	}
   325  	// return &ast.Name{NamePos: pos, Name: name, IsLHS: true}
   326  	return &ast.Name{NamePos: pos, Name: name}
   327  }
   328  
   329  func (p *parser) parseNameList() (list []*ast.Name) {
   330  	list = append(list, p.parseName())
   331  	for p.accept(token.COMMA) {
   332  		list = append(list, p.parseName())
   333  	}
   334  
   335  	return
   336  }
   337  
   338  // ----------------------------------------------------------------------------
   339  // Common productions
   340  
   341  func (p *parser) parseCallExprOrLHSList() (CallExpr *ast.CallExpr, LHS []ast.Expr) {
   342  	expr := p.parseBinaryExpr(true, token.LowestPrec)
   343  
   344  	if expr, ok := expr.(*ast.CallExpr); ok {
   345  		return expr, nil
   346  	}
   347  
   348  	LHS = append(LHS, p.checkLHS(expr))
   349  	for p.accept(token.COMMA) {
   350  		LHS = append(LHS, p.parseLHS())
   351  	}
   352  
   353  	return
   354  }
   355  
   356  func (p *parser) parseRHSList() (rhs []ast.Expr) {
   357  	rhs = append(rhs, p.parseRHS())
   358  	for p.accept(token.COMMA) {
   359  		rhs = append(rhs, p.parseRHS())
   360  	}
   361  
   362  	return
   363  }
   364  
   365  func (p *parser) parseReturnList() (rhs []ast.Expr) {
   366  	rhs = append(rhs, p.parseRHS())
   367  	for p.accept(token.COMMA) {
   368  		rhs = append(rhs, p.parseRHS())
   369  	}
   370  
   371  	return
   372  }
   373  
   374  func (p *parser) parseParameterList() (params []*ast.Name) {
   375  	if p.tok.Type == token.ELLIPSIS {
   376  		return
   377  	}
   378  
   379  	name := p.parseName()
   380  	params = append(params, name)
   381  
   382  	for p.accept(token.COMMA) {
   383  		if p.tok.Type == token.ELLIPSIS {
   384  			break
   385  		}
   386  
   387  		name := p.parseName()
   388  
   389  		params = append(params, name)
   390  	}
   391  
   392  	return
   393  }
   394  
   395  func (p *parser) parseParameters() *ast.ParamList {
   396  	var params []*ast.Name
   397  
   398  	ellipsis := position.NoPos
   399  
   400  	lparen := p.expect(token.LPAREN)
   401  	if p.tok.Type != token.RPAREN {
   402  		params = p.parseParameterList()
   403  		if p.tok.Type == token.ELLIPSIS {
   404  			ellipsis = p.tok.Pos
   405  			p.next()
   406  		}
   407  	}
   408  	rparen := p.expect(token.RPAREN)
   409  
   410  	return &ast.ParamList{Lparen: lparen, List: params, Ellipsis: ellipsis, Rparen: rparen}
   411  }
   412  
   413  // ----------------------------------------------------------------------------
   414  // Blocks
   415  
   416  func (p *parser) isEndOfBlock() bool {
   417  	switch p.tok.Type {
   418  	case token.EOF, token.ELSE, token.ELSEIF, token.END:
   419  		return true
   420  	case token.UNTIL:
   421  		return true
   422  	}
   423  
   424  	return false
   425  }
   426  
   427  func (p *parser) parseStmtList() (list []ast.Stmt, closing position.Position) {
   428  	for {
   429  		if p.isEndOfBlock() {
   430  			break
   431  		}
   432  		if p.tok.Type == token.RETURN {
   433  			list = append(list, p.parseReturnStmt())
   434  			break
   435  		}
   436  		list = append(list, p.parseStmt())
   437  	}
   438  
   439  	closing = p.tok.Pos
   440  
   441  	return list, closing
   442  }
   443  
   444  func (p *parser) parseChunk() []ast.Stmt {
   445  	p.allowEllipsis = true
   446  
   447  	list, _ := p.parseStmtList()
   448  
   449  	p.expect(token.EOF)
   450  
   451  	return list
   452  }
   453  
   454  func (p *parser) parseThenBlock() (then position.Position, body *ast.Block) {
   455  	then = p.expect(token.THEN)
   456  
   457  	body = p.parseBody(then.Offset("then"))
   458  
   459  	switch p.tok.Type {
   460  	case token.ELSEIF:
   461  	case token.ELSE:
   462  	case token.END:
   463  	default:
   464  		p.errorExpected(p.tok, "ELSEIF, ELSE or END")
   465  	}
   466  
   467  	return then, body
   468  }
   469  
   470  func (p *parser) parseRepeatBlockUntil() (repeat position.Position, body *ast.Block, until position.Position) {
   471  	repeat = p.skip()
   472  	body = p.parseBody(repeat.Offset("repeat"))
   473  	until = p.expect(token.UNTIL)
   474  
   475  	return repeat, body, until
   476  }
   477  
   478  func (p *parser) parseDoBlockEnd() (do position.Position, body *ast.Block, end position.Position) {
   479  	do = p.expect(token.DO)
   480  	body = p.parseBody(do.Offset("do"))
   481  	end = p.expect(token.END)
   482  
   483  	return do, body, end
   484  }
   485  
   486  func (p *parser) parseBody(opening position.Position) *ast.Block {
   487  	list, closing := p.parseStmtList()
   488  
   489  	return &ast.Block{
   490  		Opening: opening,
   491  		List:    list,
   492  		Closing: closing,
   493  	}
   494  }
   495  
   496  func (p *parser) parseFuncBodyEnd() (fbody *ast.FuncBody, end position.Position) {
   497  	params := p.parseParameters()
   498  
   499  	old := p.allowEllipsis
   500  	p.allowEllipsis = params.Ellipsis.IsValid()
   501  
   502  	body := p.parseBody(params.End())
   503  
   504  	p.allowEllipsis = old
   505  
   506  	end = p.expect(token.END)
   507  
   508  	fbody = &ast.FuncBody{
   509  		Params: params,
   510  		Body:   body,
   511  	}
   512  
   513  	return fbody, end
   514  }
   515  
   516  // ----------------------------------------------------------------------------
   517  // Expressions
   518  
   519  func (p *parser) parseSelector(x ast.Expr) ast.Expr {
   520  	period := p.skip()
   521  
   522  	sel := p.parseName()
   523  
   524  	return &ast.SelectorExpr{X: x, Period: period, Sel: sel}
   525  }
   526  
   527  func (p *parser) parseIndex(x ast.Expr) ast.Expr {
   528  	lbrack := p.skip()
   529  
   530  	index := p.parseRHS()
   531  
   532  	rbrack := p.expect(token.RBRACK)
   533  
   534  	return &ast.IndexExpr{X: x, Lbrack: lbrack, Index: index, Rbrack: rbrack}
   535  }
   536  
   537  func (p *parser) parseCall(isMethod bool, x ast.Expr) ast.Expr {
   538  	colon := position.NoPos
   539  	var name *ast.Name
   540  
   541  	if isMethod {
   542  		colon = p.skip()
   543  		name = p.parseName()
   544  	}
   545  
   546  	tok := p.tok
   547  
   548  	switch tok.Type {
   549  	case token.LPAREN:
   550  		lparen := tok.Pos
   551  		p.next()
   552  		var args []ast.Expr
   553  
   554  		for p.tok.Type != token.RPAREN && p.tok.Type != token.EOF {
   555  			args = append(args, p.parseRHS())
   556  			if !p.accept(token.COMMA) {
   557  				break
   558  			}
   559  		}
   560  
   561  		rparen := p.expect(token.RPAREN)
   562  
   563  		return &ast.CallExpr{X: x, Colon: colon, Name: name, Lparen: lparen, Args: args, Rparen: rparen}
   564  	case token.LBRACE:
   565  		y := p.parseTableLit()
   566  
   567  		return &ast.CallExpr{X: x, Colon: colon, Name: name, Args: []ast.Expr{y}}
   568  	case token.STRING:
   569  		y := &ast.BasicLit{Token: tok}
   570  
   571  		p.next()
   572  
   573  		return &ast.CallExpr{X: x, Colon: colon, Name: name, Args: []ast.Expr{y}}
   574  	}
   575  
   576  	// we have an error
   577  	p.errorExpected(tok, "callable")
   578  
   579  	// syncStmt(p)
   580  
   581  	return &ast.BadExpr{From: tok.Pos, To: p.tok.Pos}
   582  }
   583  
   584  func (p *parser) parseElement() ast.Expr {
   585  	lbrack := position.NoPos
   586  	rbrack := position.NoPos
   587  
   588  	var x ast.Expr
   589  
   590  	switch p.tok.Type {
   591  	case token.LBRACK: // [key]
   592  		lbrack = p.tok.Pos
   593  
   594  		p.next()
   595  
   596  		x = p.parseRHS()
   597  
   598  		rbrack = p.expect(token.RBRACK)
   599  	default: // key
   600  		x = p.parseBinaryExpr(true, token.LowestPrec)
   601  	}
   602  
   603  	if p.tok.Type == token.ASSIGN {
   604  		// key = value
   605  
   606  		eq := p.tok.Pos
   607  
   608  		p.next()
   609  
   610  		y := p.parseRHS()
   611  
   612  		return &ast.KeyValueExpr{Lbrack: lbrack, Key: x, Rbrack: rbrack, Equal: eq, Value: y}
   613  	}
   614  
   615  	// value
   616  	// p.markRHS(x)
   617  
   618  	return x
   619  }
   620  
   621  func (p *parser) parseElementList() (fields []ast.Expr) {
   622  	for p.tok.Type != token.RBRACE && p.tok.Type != token.EOF {
   623  		e := p.parseElement()
   624  
   625  		fields = append(fields, e)
   626  
   627  		if !p.accept(token.COMMA, token.SEMICOLON) {
   628  			break
   629  		}
   630  	}
   631  
   632  	return
   633  }
   634  
   635  func (p *parser) parseTableLit() *ast.TableLit {
   636  	lbrace := p.expect(token.LBRACE)
   637  
   638  	var fields []ast.Expr
   639  	if p.tok.Type != token.RBRACE {
   640  		fields = p.parseElementList()
   641  	}
   642  
   643  	rbrace := p.expect(token.RBRACE)
   644  
   645  	return &ast.TableLit{Lbrace: lbrace, Fields: fields, Rbrace: rbrace}
   646  }
   647  
   648  func (p *parser) parseFuncLit() *ast.FuncLit {
   649  	fn := p.expect(token.FUNCTION)
   650  
   651  	f, end := p.parseFuncBodyEnd()
   652  
   653  	return &ast.FuncLit{
   654  		Func:   fn,
   655  		Body:   f,
   656  		EndPos: end,
   657  	}
   658  }
   659  
   660  // checkExpr checks that x is an expression.
   661  func (p *parser) checkExpr(x ast.Expr) ast.Expr {
   662  	switch unparen(x).(type) {
   663  	case *ast.BadExpr:
   664  	case *ast.Name:
   665  	case *ast.Vararg:
   666  	case *ast.BasicLit:
   667  	case *ast.FuncLit:
   668  	case *ast.TableLit:
   669  	case *ast.ParenExpr:
   670  		panic("unreachable")
   671  	case *ast.SelectorExpr:
   672  	case *ast.IndexExpr:
   673  	case *ast.CallExpr:
   674  	case *ast.UnaryExpr:
   675  	case *ast.BinaryExpr:
   676  	default:
   677  		// all other nodes are not proper expressions
   678  		p.error(x.Pos(), fmt.Errorf("expected expression, found %T", x))
   679  
   680  		x = &ast.BadExpr{From: x.Pos(), To: x.End()}
   681  	}
   682  	return x
   683  }
   684  
   685  // checkLHS checks that x is an LHS expression.
   686  func (p *parser) checkLHS(x ast.Expr) ast.Expr {
   687  	// switch t := x.(type) {
   688  	switch x.(type) {
   689  	case *ast.Name:
   690  		// if !t.IsLHS {
   691  		// goto error
   692  		// }
   693  	case *ast.SelectorExpr:
   694  		// if !t.IsLHS {
   695  		// goto error
   696  		// }
   697  	case *ast.IndexExpr:
   698  		// if !t.IsLHS {
   699  		// goto error
   700  		// }
   701  	default:
   702  		goto error
   703  	}
   704  
   705  	return x
   706  
   707  error:
   708  	// all other nodes are not proper expressions
   709  	p.error(x.Pos(), fmt.Errorf("expected LHS, found %T", x))
   710  
   711  	x = &ast.BadExpr{From: x.Pos(), To: x.End()}
   712  
   713  	return x
   714  }
   715  
   716  // If x is of the form (T), unparen returns unparen(T), otherwise it returns x.
   717  func unparen(x ast.Expr) ast.Expr {
   718  	if p, isParen := x.(*ast.ParenExpr); isParen {
   719  		x = unparen(p.X)
   720  	}
   721  	return x
   722  }
   723  
   724  func (p *parser) parsePrimaryExpr() ast.Expr {
   725  	tok := p.tok
   726  
   727  	switch tok.Type {
   728  	case token.NAME:
   729  		x := p.parseName()
   730  		// x.IsLHS = false
   731  		return x
   732  	case token.LPAREN:
   733  		lparen := tok.Pos
   734  		p.next()
   735  		x := p.parseRHS()
   736  		rparen := p.expect(token.RPAREN)
   737  
   738  		return &ast.ParenExpr{Lparen: lparen, X: x, Rparen: rparen}
   739  	}
   740  
   741  	// we have an error
   742  	p.errorExpected(tok, "NAME or '('")
   743  
   744  	// syncStmt(p)
   745  
   746  	return &ast.BadExpr{From: tok.Pos, To: p.tok.Pos}
   747  }
   748  
   749  func (p *parser) parseSuffixedExpr(isLHS bool) ast.Expr {
   750  	x := p.parsePrimaryExpr()
   751  L:
   752  	for {
   753  		switch p.tok.Type {
   754  		case token.PERIOD:
   755  			x = p.parseSelector(p.checkExpr(x))
   756  		case token.LBRACK:
   757  			x = p.parseIndex(p.checkExpr(x))
   758  		case token.LPAREN, token.LBRACE, token.STRING:
   759  			x = p.parseCall(false, p.checkExpr(x))
   760  		case token.COLON:
   761  			x = p.parseCall(true, p.checkExpr(x))
   762  		default:
   763  			if isLHS {
   764  				// p.markLHS(x)
   765  			}
   766  
   767  			break L
   768  		}
   769  	}
   770  
   771  	return x
   772  }
   773  
   774  func (p *parser) parseSimpleExpr(isLHS bool) ast.Expr {
   775  	tok := p.tok
   776  
   777  	switch tok.Type {
   778  	case token.ELLIPSIS:
   779  		var x ast.Expr
   780  
   781  		if !p.allowEllipsis {
   782  			p.error(tok.Pos, errIllegalVararg)
   783  
   784  			p.next()
   785  
   786  			x = &ast.BadExpr{From: tok.Pos, To: p.tok.Pos}
   787  
   788  			return x
   789  		}
   790  
   791  		x = &ast.Vararg{Ellipsis: tok.Pos}
   792  
   793  		p.next()
   794  
   795  		return x
   796  
   797  	case token.INT, token.FLOAT, token.STRING:
   798  		x := &ast.BasicLit{Token: tok}
   799  		p.next()
   800  		return x
   801  
   802  	case token.FALSE, token.TRUE, token.NIL:
   803  		x := &ast.BasicLit{Token: tok}
   804  		p.next()
   805  		return x
   806  
   807  	case token.FUNCTION:
   808  		return p.parseFuncLit()
   809  
   810  	case token.LBRACE:
   811  		return p.parseTableLit()
   812  	default:
   813  		return p.parseSuffixedExpr(isLHS)
   814  	}
   815  }
   816  
   817  // If isLHS is set and the result is an name, it is not resolved.
   818  func (p *parser) parseUnaryExpr(isLHS bool) ast.Expr {
   819  	tok := p.tok
   820  
   821  	switch tok.Type {
   822  	case token.UNM, token.BNOT, token.NOT, token.LEN:
   823  		p.next()
   824  		x := p.parseBinaryExpr(false, token.UnaryPrec)
   825  		return &ast.UnaryExpr{OpPos: tok.Pos, Op: tok.Type, X: p.checkExpr(x)}
   826  	}
   827  
   828  	return p.parseSimpleExpr(isLHS)
   829  }
   830  
   831  func (p *parser) tokPrec() (token.Type, int, int) {
   832  	tok := p.tok.Type
   833  	l, r := tok.Precedence()
   834  	return tok, l, r
   835  }
   836  
   837  // If isLHS is set and the result is an name, it is not resolved.
   838  func (p *parser) parseBinaryExpr(isLHS bool, prec1 int) ast.Expr {
   839  	x := p.parseUnaryExpr(isLHS)
   840  
   841  	for {
   842  		op, lprec, rprec := p.tokPrec()
   843  
   844  		if lprec <= prec1 {
   845  			break
   846  		}
   847  
   848  		if isLHS {
   849  			// p.markRHS(x)
   850  
   851  			isLHS = false
   852  		}
   853  
   854  		olprec, orprec := lprec, rprec
   855  
   856  		for {
   857  			pos := p.expect(op)
   858  
   859  			y := p.parseBinaryExpr(false, orprec)
   860  
   861  			x = &ast.BinaryExpr{X: p.checkExpr(x), OpPos: pos, Op: op, Y: p.checkExpr(y)}
   862  
   863  			op, olprec, orprec = p.tokPrec()
   864  
   865  			if olprec < rprec {
   866  				break
   867  			}
   868  		}
   869  	}
   870  
   871  	return x
   872  }
   873  
   874  func (p *parser) parseLHS() ast.Expr {
   875  	return p.checkLHS(p.parseBinaryExpr(true, token.LowestPrec))
   876  }
   877  
   878  func (p *parser) parseRHS() ast.Expr {
   879  	return p.checkExpr(p.parseBinaryExpr(false, token.LowestPrec))
   880  }
   881  
   882  // ----------------------------------------------------------------------------
   883  // Statements
   884  
   885  func (p *parser) parseAssign(LHS []ast.Expr) ast.Stmt {
   886  	eq := p.skip()
   887  
   888  	rhs := p.parseRHSList()
   889  
   890  	assign := &ast.AssignStmt{
   891  		LHS:   LHS,
   892  		Equal: eq,
   893  		RHS:   rhs,
   894  	}
   895  
   896  	return assign
   897  }
   898  
   899  func (p *parser) parseLocalAssignStmt(local position.Position) ast.Stmt {
   900  	LHS := p.parseNameList()
   901  
   902  	var stmt ast.Stmt
   903  
   904  	if p.tok.Type == token.ASSIGN {
   905  		eq := p.tok.Pos
   906  		p.next()
   907  
   908  		rhs := p.parseRHSList()
   909  
   910  		stmt = &ast.LocalAssignStmt{
   911  			Local: local,
   912  			LHS:   LHS,
   913  			Equal: eq,
   914  			RHS:   rhs,
   915  		}
   916  	} else {
   917  		stmt = &ast.LocalAssignStmt{
   918  			Local: local,
   919  			LHS:   LHS,
   920  		}
   921  	}
   922  
   923  	return stmt
   924  }
   925  
   926  func (p *parser) parseLocalStmt() ast.Stmt {
   927  	local := p.skip()
   928  
   929  	if p.tok.Type == token.FUNCTION {
   930  		fn := p.skip()
   931  
   932  		name := p.parseName()
   933  
   934  		f, end := p.parseFuncBodyEnd()
   935  
   936  		return &ast.LocalFuncStmt{
   937  			Local:  local,
   938  			Func:   fn,
   939  			Name:   name,
   940  			Body:   f,
   941  			EndPos: end,
   942  		}
   943  	}
   944  
   945  	return p.parseLocalAssignStmt(local)
   946  }
   947  
   948  func (p *parser) parseFuncStmt() *ast.FuncStmt {
   949  	fn := p.skip()
   950  
   951  	var prefix []*ast.Name
   952  	var accessTok token.Type
   953  	var accessPos position.Position
   954  	var name *ast.Name
   955  
   956  	var list []*ast.Name
   957  	var periodPos position.Position
   958  
   959  	list = append(list, p.parseName())
   960  
   961  	for p.tok.Type == token.PERIOD {
   962  		periodPos = p.tok.Pos
   963  
   964  		p.next() // make progress
   965  
   966  		list = append(list, p.parseName())
   967  	}
   968  
   969  	if p.tok.Type == token.COLON {
   970  		accessTok = token.COLON
   971  		accessPos = p.tok.Pos
   972  
   973  		p.next()
   974  
   975  		name = p.parseName()
   976  		prefix = list
   977  	} else if len(list) == 1 {
   978  		name = list[0]
   979  		accessTok = token.ILLEGAL
   980  		accessPos = position.NoPos
   981  	} else {
   982  		name = list[len(list)-1]
   983  		prefix = list[:len(list)-1]
   984  		accessTok = token.PERIOD
   985  		accessPos = periodPos
   986  	}
   987  
   988  	f, end := p.parseFuncBodyEnd()
   989  
   990  	return &ast.FuncStmt{
   991  		Func:      fn,
   992  		PathList:  prefix,
   993  		AccessTok: accessTok,
   994  		AccessPos: accessPos,
   995  		Name:      name,
   996  		Body:      f,
   997  		EndPos:    end,
   998  	}
   999  }
  1000  
  1001  func (p *parser) parseExprOrAssignStmt() (stmt ast.Stmt) {
  1002  	tok := p.tok
  1003  
  1004  	expr, LHS := p.parseCallExprOrLHSList()
  1005  	if p.tok.Type == token.ASSIGN { // assign stmt
  1006  		if len(LHS) == 0 {
  1007  			p.errorExpected(tok, "LHS")
  1008  
  1009  			return &ast.BadStmt{From: tok.Pos, To: p.tok.Pos}
  1010  		}
  1011  
  1012  		stmt = p.parseAssign(LHS)
  1013  	} else { // expr stmt
  1014  		if expr == nil {
  1015  			p.errorExpected(tok, "callable")
  1016  
  1017  			return &ast.BadStmt{From: tok.Pos, To: p.tok.Pos}
  1018  		}
  1019  
  1020  		stmt = &ast.ExprStmt{expr}
  1021  	}
  1022  
  1023  	return
  1024  }
  1025  
  1026  func (p *parser) parseReturnStmt() *ast.ReturnStmt {
  1027  	ret := p.skip()
  1028  	semi := position.NoPos
  1029  
  1030  	if p.isEndOfBlock() {
  1031  		return &ast.ReturnStmt{
  1032  			Return:    ret,
  1033  			Semicolon: semi,
  1034  		}
  1035  	}
  1036  
  1037  	if p.tok.Type == token.SEMICOLON {
  1038  		semi = p.tok.Pos
  1039  
  1040  		p.next()
  1041  
  1042  		return &ast.ReturnStmt{
  1043  			Return:    ret,
  1044  			Semicolon: semi,
  1045  		}
  1046  	}
  1047  
  1048  	results := p.parseReturnList()
  1049  
  1050  	if p.tok.Type == token.SEMICOLON {
  1051  		semi = p.tok.Pos
  1052  
  1053  		p.next()
  1054  	}
  1055  
  1056  	return &ast.ReturnStmt{
  1057  		Return:    ret,
  1058  		Results:   results,
  1059  		Semicolon: semi,
  1060  	}
  1061  }
  1062  
  1063  func (p *parser) parseLabelStmt() *ast.LabelStmt {
  1064  	label := p.skip()
  1065  
  1066  	name := p.parseName()
  1067  
  1068  	end := p.expect(token.LABEL)
  1069  
  1070  	return &ast.LabelStmt{
  1071  		Label:    label,
  1072  		Name:     name,
  1073  		EndLabel: end,
  1074  	}
  1075  }
  1076  
  1077  func (p *parser) parseGotoStmt() *ast.GotoStmt {
  1078  	_goto := p.skip()
  1079  
  1080  	label := p.parseName()
  1081  
  1082  	return &ast.GotoStmt{Goto: _goto, Label: label}
  1083  }
  1084  
  1085  func (p *parser) parseBreak() ast.Stmt {
  1086  	if !p.allowBreak {
  1087  		from := p.tok.Pos
  1088  		p.error(from, errIllegalBreak)
  1089  
  1090  		// syncStmt(p)
  1091  
  1092  		return &ast.BadStmt{From: from, To: p.tok.Pos}
  1093  	}
  1094  
  1095  	brk := p.skip()
  1096  
  1097  	return &ast.BreakStmt{Break: brk}
  1098  }
  1099  
  1100  func (p *parser) parseDoStmt() *ast.DoStmt {
  1101  	do, body, end := p.parseDoBlockEnd()
  1102  
  1103  	return &ast.DoStmt{
  1104  		Do:     do,
  1105  		Body:   body,
  1106  		EndPos: end,
  1107  	}
  1108  }
  1109  
  1110  func (p *parser) parseRepeatStmt() *ast.RepeatStmt {
  1111  	old := p.allowBreak
  1112  
  1113  	p.allowBreak = true
  1114  
  1115  	repeat, body, until := p.parseRepeatBlockUntil()
  1116  
  1117  	p.allowBreak = old
  1118  
  1119  	cond := p.parseRHS()
  1120  
  1121  	return &ast.RepeatStmt{
  1122  		Repeat: repeat,
  1123  		Body:   body,
  1124  		Until:  until,
  1125  		Cond:   cond,
  1126  	}
  1127  }
  1128  
  1129  func (p *parser) parseWhileStmt() *ast.WhileStmt {
  1130  	while := p.skip()
  1131  
  1132  	cond := p.parseRHS()
  1133  
  1134  	old := p.allowBreak
  1135  
  1136  	p.allowBreak = true
  1137  
  1138  	do, body, end := p.parseDoBlockEnd()
  1139  
  1140  	p.allowBreak = old
  1141  
  1142  	return &ast.WhileStmt{
  1143  		While:  while,
  1144  		Cond:   cond,
  1145  		Do:     do,
  1146  		Body:   body,
  1147  		EndPos: end,
  1148  	}
  1149  }
  1150  
  1151  func (p *parser) parseIfStmt() *ast.IfStmt {
  1152  	_if := p.skip()
  1153  
  1154  	cond := p.parseRHS()
  1155  
  1156  	then, body := p.parseThenBlock()
  1157  
  1158  	stmt := &ast.IfStmt{
  1159  		If:   _if,
  1160  		Cond: cond,
  1161  		Then: then,
  1162  		Body: body,
  1163  	}
  1164  
  1165  	for {
  1166  		elseif := p.tok.Pos
  1167  		if !p.accept(token.ELSEIF) {
  1168  			break
  1169  		}
  1170  
  1171  		cond := p.parseRHS()
  1172  		then, body := p.parseThenBlock()
  1173  
  1174  		stmt.ElseIfList = append(stmt.ElseIfList, struct {
  1175  			If   position.Position
  1176  			Cond ast.Expr
  1177  			Then position.Position
  1178  			Body *ast.Block
  1179  		}{
  1180  			elseif,
  1181  			cond,
  1182  			then,
  1183  			body,
  1184  		})
  1185  	}
  1186  
  1187  	if p.tok.Type == token.ELSE {
  1188  		stmt.Else = p.skip()
  1189  		stmt.ElseBody = p.parseBody(stmt.Else.Offset("else"))
  1190  	}
  1191  
  1192  	stmt.EndPos = p.expect(token.END)
  1193  
  1194  	return stmt
  1195  }
  1196  
  1197  func (p *parser) parseForStmt() ast.Stmt {
  1198  	_for := p.skip()
  1199  
  1200  	names := p.parseNameList()
  1201  
  1202  	var in, eq position.Position
  1203  
  1204  	if len(names) > 1 {
  1205  		in = p.expect(token.IN)
  1206  		goto foreach
  1207  	}
  1208  
  1209  	switch p.tok.Type {
  1210  	case token.ASSIGN:
  1211  		eq = p.tok.Pos
  1212  		p.next()
  1213  	case token.IN:
  1214  		in = p.tok.Pos
  1215  		p.next()
  1216  		goto foreach
  1217  	default:
  1218  		tok := p.tok
  1219  
  1220  		p.errorExpected(tok, "'=' or 'in'")
  1221  
  1222  		// syncStmt(p)
  1223  
  1224  		return &ast.BadStmt{From: tok.Pos, To: p.tok.Pos}
  1225  	}
  1226  
  1227  	// fornum
  1228  	{
  1229  
  1230  		start := p.parseRHS()
  1231  
  1232  		p.expect(token.COMMA)
  1233  
  1234  		finish := p.parseRHS()
  1235  
  1236  		var step ast.Expr
  1237  
  1238  		if p.accept(token.COMMA) {
  1239  			step = p.parseRHS()
  1240  		}
  1241  
  1242  		old := p.allowBreak
  1243  
  1244  		p.allowBreak = true
  1245  
  1246  		do, body, end := p.parseDoBlockEnd()
  1247  
  1248  		p.allowBreak = old
  1249  
  1250  		return &ast.ForStmt{
  1251  			For:    _for,
  1252  			Name:   names[0],
  1253  			Equal:  eq,
  1254  			Start:  start,
  1255  			Finish: finish,
  1256  			Step:   step,
  1257  			Do:     do,
  1258  			Body:   body,
  1259  			EndPos: end,
  1260  		}
  1261  	}
  1262  
  1263  foreach:
  1264  	{
  1265  		exprs := p.parseRHSList()
  1266  
  1267  		old := p.allowBreak
  1268  
  1269  		p.allowBreak = true
  1270  
  1271  		do, body, end := p.parseDoBlockEnd()
  1272  
  1273  		p.allowBreak = old
  1274  
  1275  		return &ast.ForEachStmt{
  1276  			For:    _for,
  1277  			Names:  names,
  1278  			In:     in,
  1279  			Exprs:  exprs,
  1280  			Do:     do,
  1281  			Body:   body,
  1282  			EndPos: end,
  1283  		}
  1284  	}
  1285  }
  1286  
  1287  func (p *parser) parseStmt() (s ast.Stmt) {
  1288  	switch p.tok.Type {
  1289  	case token.IF:
  1290  		s = p.parseIfStmt()
  1291  	case token.WHILE:
  1292  		s = p.parseWhileStmt()
  1293  	case token.DO:
  1294  		s = p.parseDoStmt()
  1295  	case token.FOR:
  1296  		s = p.parseForStmt()
  1297  	case token.REPEAT:
  1298  		s = p.parseRepeatStmt()
  1299  	case token.FUNCTION:
  1300  		s = p.parseFuncStmt()
  1301  	case token.LOCAL:
  1302  		s = p.parseLocalStmt()
  1303  	case token.SEMICOLON:
  1304  		s = &ast.EmptyStmt{Semicolon: p.tok.Pos}
  1305  
  1306  		p.next()
  1307  	case token.LABEL:
  1308  		s = p.parseLabelStmt()
  1309  	case token.RETURN:
  1310  		s = p.parseReturnStmt()
  1311  	case token.GOTO:
  1312  		s = p.parseGotoStmt()
  1313  	case token.BREAK:
  1314  		s = p.parseBreak()
  1315  	default:
  1316  		s = p.parseExprOrAssignStmt()
  1317  	}
  1318  
  1319  	return
  1320  }
  1321  
  1322  // ----------------------------------------------------------------------------
  1323  // Source files
  1324  
  1325  func (p *parser) parseFile() *ast.File {
  1326  	chunk := p.parseChunk()
  1327  
  1328  	return &ast.File{
  1329  		Filename: p.scanState.SourceName(),
  1330  		Shebang:  p.scanState.Shebang(),
  1331  		Chunk:    chunk,
  1332  		Comments: p.comments,
  1333  	}
  1334  }