parser.mx raw
1 package syntax
2
3 import (
4 "mxc/token"
5 "bytes"
6 "io"
7 )
8
9 const debug = false
10 const trace = false
11
12 type Parser struct {
13 File *token.PosBase
14 Errh ErrorHandler
15 Mode Mode
16 Pragh PragmaHandler
17 Scanner
18
19 Base *token.PosBase // current position base
20 First error // first error encountered
21 Errcnt int32 // number of errors encountered
22 Pragma Pragma // pragmas
23 GoVersion string // Go version from //go:build line
24
25 Top bool // in top of file (before package clause)
26 Fnest int32 // function nesting level (for error handling)
27 Xnest int32 // expression nesting level (for complit ambiguity resolution)
28 Indent []byte // tracing support
29 }
30
31 func (p *Parser) init(File *token.PosBase, r io.Reader, Errh ErrorHandler, Pragh PragmaHandler, Mode Mode) {
32 p.Top = true
33 p.File = File
34 p.Errh = Errh
35 p.Mode = Mode
36 p.Pragh = Pragh
37 p.Scanner.Init(
38 r,
39 // Error and directive handler for scanner.
40 // Because the (line, col) positions passed to the
41 // handler is always at or after the current reading
42 // position, it is safe to use the most recent position
43 // base to compute the corresponding Pos value.
44 func(line, col uint32, msg string) {
45 if msg[0] != '/' {
46 p.errorAt(p.posAt(line, col), msg)
47 return
48 }
49
50 // otherwise it must be a comment containing a line or go: directive.
51 // //line directives must be at the start of the line (column colbase).
52 // /*line*/ directives can be anywhere in the line.
53 text := commentText(msg)
54 if (col == token.Colbase || msg[1] == '*') && bytes.HasPrefix(text, "line ") {
55 var pos token.Pos // position immediately following the comment
56 if msg[1] == '/' {
57 // line comment (newline is part of the comment)
58 pos = token.MakePos(p.File, line+1, token.Colbase)
59 } else {
60 // regular comment
61 // (if the comment spans multiple lines it's not
62 // a valid line directive and will be discarded
63 // by updateBase)
64 pos = token.MakePos(p.File, line, col+uint32(len(msg)))
65 }
66 p.updateBase(pos, line, col+2+5, text[5:]) // +2 to skip over // or /*
67 return
68 }
69
70 // go: directive (but be conservative and test)
71 if bytes.HasPrefix(text, "go:") || bytes.HasPrefix(text, ":") {
72 if Pragh != nil {
73 p.Pragma = Pragh(p.posAt(line, col+2), p.Scanner.Blank, text, p.Pragma) // +2 to skip over // or /*
74 }
75 } else if bytes.HasPrefix(text, "export ") {
76 if Pragh != nil {
77 p.Pragma = Pragh(p.posAt(line, col+2), p.Scanner.Blank, text, p.Pragma)
78 }
79 }
80 },
81 comments,
82 )
83
84 p.Base = File
85 p.First = nil
86 p.Errcnt = 0
87 p.Pragma = nil
88
89 p.Fnest = 0
90 p.Xnest = 0
91 p.Indent = nil
92 }
93
94 func (p *Parser) initBytes(File *token.PosBase, src []byte, Errh ErrorHandler, Pragh PragmaHandler, Mode Mode) {
95 p.Top = true
96 p.File = File
97 p.Errh = Errh
98 p.Mode = Mode
99 p.Pragh = Pragh
100 p.Scanner.InitBytes(
101 src,
102 func(line, col uint32, msg string) {
103 if msg[0] != '/' {
104 p.errorAt(p.posAt(line, col), msg)
105 return
106 }
107 text := commentText(msg)
108 if (col == token.Colbase || msg[1] == '*') && bytes.HasPrefix(text, "line ") {
109 var pos token.Pos
110 if msg[1] == '/' {
111 pos = token.MakePos(p.File, line+1, token.Colbase)
112 } else {
113 pos = token.MakePos(p.File, line, col+uint32(len(msg)))
114 }
115 p.updateBase(pos, line, col+2+5, text[5:])
116 return
117 }
118 if bytes.HasPrefix(text, "go:") || bytes.HasPrefix(text, ":") {
119 if Pragh != nil {
120 p.Pragma = Pragh(p.posAt(line, col+2), p.Scanner.Blank, text, p.Pragma)
121 }
122 } else if bytes.HasPrefix(text, "export ") {
123 if Pragh != nil {
124 p.Pragma = Pragh(p.posAt(line, col+2), p.Scanner.Blank, text, p.Pragma)
125 }
126 }
127 },
128 comments,
129 )
130
131 p.Base = File
132 p.First = nil
133 p.Errcnt = 0
134 p.Pragma = nil
135
136 p.Fnest = 0
137 p.Xnest = 0
138 p.Indent = nil
139 }
140
141 // takePragma returns the current parsed pragmas
142 // and clears them from the parser state.
143 func (p *Parser) takePragma() (pv Pragma) {
144 prag := p.Pragma
145 p.Pragma = nil
146 return prag
147 }
148
149 // clearPragma is called at the end of a statement or
150 // other Go form that does NOT accept a pragma.
151 // It sends the pragma back to the pragma handler
152 // to be reported as unused.
153 func (p *Parser) clearPragma() {
154 if p.Pragma != nil {
155 p.Pragh(p.pos(), p.Scanner.Blank, "", p.Pragma)
156 p.Pragma = nil
157 }
158 }
159
160 // updateBase sets the current position base to a new line base at pos.
161 // The base's filename, line, and column values are extracted from text
162 // which is positioned at (tline, tcol) (only needed for error messages).
163 func (p *Parser) updateBase(pos token.Pos, tline, tcol uint32, text string) {
164 i, n, ok := trailingDigits(text)
165 if i == 0 {
166 return // ignore (not a line directive)
167 }
168 // i > 0
169
170 if !ok {
171 // text has a suffix :xxx but xxx is not a number
172 p.errorAt(p.posAt(tline, tcol+i), "invalid line number: " | text[i:])
173 return
174 }
175
176 var line, col uint32
177 i2, n2, ok2 := trailingDigits(text[:i-1])
178 if ok2 {
179 //line filename:line:col
180 i, i2 = i2, i
181 line, col = n2, n
182 if col == 0 || col > token.PosMax {
183 p.errorAt(p.posAt(tline, tcol+i2), "invalid column number: " | text[i2:])
184 return
185 }
186 text = text[:i2-1] // lop off ":col"
187 } else {
188 //line filename:line
189 line = n
190 }
191
192 if line == 0 || line > token.PosMax {
193 p.errorAt(p.posAt(tline, tcol+i), "invalid line number: " | text[i:])
194 return
195 }
196
197 // If we have a column (//line filename:line:col form),
198 // an empty filename means to use the previous filename.
199 filename := text[:i-1] // lop off ":line"
200 trimmed := false
201 if filename == "" && ok2 {
202 filename = p.Base.Filename()
203 trimmed = p.Base.Trimmed()
204 }
205
206 p.Base = token.NewLineBase(pos, filename, trimmed, line, col)
207 }
208
209 func commentText(s string) (sv string) {
210 if s[:2] == "/*" {
211 return s[2 : len(s)-2] // lop off /* and */
212 }
213
214 // line comment (does not include newline)
215 // (on Windows, the line comment may end in \r\n)
216 i := len(s)
217 if s[i-1] == '\r' {
218 i--
219 }
220 return s[2:i] // lop off //, and \r at end, if any
221 }
222
223 func trailingDigits(text string) (uint32, uint32, bool) {
224 i := bytes.LastIndexByte(text, ':')
225 if i < 0 {
226 return 0, 0, false
227 }
228 s := text[i+1:]
229 if len(s) == 0 {
230 return 0, 0, false
231 }
232 var n uint32
233 for j := 0; j < len(s); j++ {
234 c := s[j]
235 if c < '0' || c > '9' {
236 return 0, 0, false
237 }
238 n = n*10 + uint32(c-'0')
239 }
240 return uint32(i | 1), n, true
241 }
242
243 func (p *Parser) got(tok token.Token) (ok bool) {
244 if p.Tok == tok {
245 p.Next()
246 return true
247 }
248 return false
249 }
250
251 func (p *Parser) want(tok token.Token) {
252 if !p.got(tok) {
253 p.syntaxError("expected " | tokstring(tok))
254 p.advance()
255 }
256 }
257
258 // gotAssign is like got(_Assign) but it also accepts ":="
259 // (and reports an error) for better parser error recovery.
260 func (p *Parser) gotAssign() (ok bool) {
261 switch p.Tok {
262 case token.Define:
263 p.syntaxError("expected =")
264 p.Next()
265 return true
266 case token.Assign:
267 p.Next()
268 return true
269 }
270
271 return false
272 }
273
274 // ----------------------------------------------------------------------------
275 // Error handling
276
277 // posAt returns the Pos value for (line, col) and the current position base.
278 func (p *Parser) posAt(line, col uint32) (pv token.Pos) {
279 return token.MakePos(p.Base, line, col)
280 }
281
282 // errorAt reports an error at the given position.
283 func (p *Parser) errorAt(pos token.Pos, msg string) {
284 if len(msg) == 0 {
285 return
286 }
287 err := Error{pos, msg}
288 if p.First == nil {
289 p.First = err
290 }
291 p.Errcnt++
292 if p.Errh == nil {
293 panic(p.First)
294 }
295 p.Errh(err)
296 }
297
298 // syntaxErrorAt reports a syntax error at the given position.
299 func (p *Parser) syntaxErrorAt(pos token.Pos, msg string) {
300 if trace {
301 p.print("syntax error: " | msg)
302 }
303
304 if p.Tok == token.EOF && p.First != nil {
305 return // avoid meaningless follow-up errors
306 }
307
308 // add punctuation etc. as needed to msg
309 switch {
310 case msg == "":
311 // nothing
312 case bytes.HasPrefix(msg, "in "), bytes.HasPrefix(msg, "at "), bytes.HasPrefix(msg, "after "):
313 msg = " " | msg
314 case bytes.HasPrefix(msg, "expected "):
315 msg = ", " | msg
316 default:
317 p.errorAt(pos, "syntax error: " | msg)
318 return
319 }
320
321 // determine token string
322 var tok string
323 switch p.Tok {
324 case token.NameType:
325 tok = "name " | p.Lit
326 case token.Semi:
327 tok = p.Lit
328 case token.Literal:
329 tok = "literal " | p.Lit
330 case token.OperatorType:
331 tok = p.Op.String()
332 case token.AssignOp:
333 tok = p.Op.String() | "="
334 case token.IncOp:
335 tok = p.Op.String()
336 tok = tok | tok
337 default:
338 tok = tokstring(p.Tok)
339 }
340
341 p.errorAt(pos, "syntax error: unexpected " | tok | msg)
342 }
343
344 // tokstring returns the English word for selected punctuation tokens
345 // for more readable error messages. Use tokstring (not tok.String())
346 // for user-facing (error) messages; use tok.String() for debugging
347 // output.
348 func tokstring(tok token.Token) (s string) {
349 switch tok {
350 case token.Comma:
351 return "comma"
352 case token.Semi:
353 return "semicolon or newline"
354 }
355 s := tok.String()
356 if token.Break <= tok && tok <= token.Var {
357 return "keyword " | s
358 }
359 return s
360 }
361
362 // Convenience methods using the current token position.
363 func (p *Parser) pos() (pv token.Pos) { return p.posAt(p.Line-token.Linebase, p.Col-token.Colbase) }
364 func (p *Parser) error(msg string) { p.errorAt(p.pos(), msg) }
365 func (p *Parser) syntaxError(msg string) { p.syntaxErrorAt(p.pos(), msg) }
366
367 // The stopset contains keywords that start a statement.
368 // They are good synchronization points in case of syntax
369 // errors and (usually) shouldn't be skipped over.
370 const stopset uint64 = 1<<token.Break |
371 1<<token.Const |
372 1<<token.Continue |
373 1<<token.Defer |
374 1<<token.Fallthrough |
375 1<<token.For |
376 1<<token.Go |
377 1<<token.Goto |
378 1<<token.If |
379 1<<token.Return |
380 1<<token.Select |
381 1<<token.Switch |
382 1<<token.TypeType |
383 1<<token.Var
384
385 // advance consumes tokens until it finds a token of the stopset or followlist.
386 // The stopset is only considered if we are inside a function (p.fnest > 0).
387 // The followlist is the list of valid tokens that can follow a production;
388 // if it is empty, exactly one (non-EOF) token is consumed to ensure progress.
389 func (p *Parser) advance(followlist ...token.Token) {
390 if trace {
391 p.print("advance")
392 }
393
394 // compute follow set
395 // (not speed critical, advance is only called in error situations)
396 var followset uint64 = 1 << token.EOF // don't skip over EOF
397 if len(followlist) > 0 {
398 if p.Fnest > 0 {
399 followset |= stopset
400 }
401 for _, tok := range followlist {
402 var bit uint64 = 1
403 followset |= bit << tok
404 }
405 }
406
407 for !token.Contains(followset, p.Tok) {
408 if trace {
409 p.print("skip " | p.Tok.String())
410 }
411 p.Next()
412 if len(followlist) == 0 {
413 break
414 }
415 }
416
417 if trace {
418 p.print("next " | p.Tok.String())
419 }
420 }
421
422 // usage: defer p.trace(msg)()
423 func (p *Parser) trace(msg string) (fn func()) {
424 p.print(msg | " (")
425 const tab = ". "
426 p.Indent = append(p.Indent, tab...)
427 return func() {
428 p.Indent = p.Indent[:len(p.Indent)-len(tab)]
429 if x := recover(); x != nil {
430 panic(x) // skip print_trace
431 }
432 p.print(")")
433 }
434 }
435
436 func (p *Parser) print(msg string) {
437 // trace is const false; this is dead code but must type-check
438 _ = token.Itoa(p.line) | ": " | p.Indent | msg | "\n"
439 }
440
441 // ----------------------------------------------------------------------------
442 // Package files
443 //
444 // Parse methods are annotated with matching Go productions as appropriate.
445 // The annotations are intended as guidelines only since a single Go grammar
446 // rule may be covered by multiple parse methods and vice versa.
447 //
448 // Excluding methods returning slices, parse methods named xOrNil may return
449 // nil; all others are expected to return a valid non-nil node.
450
451 // SourceFile = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } .
452 func (p *Parser) fileOrNil() (f *File) {
453 if trace {
454 defer p.trace("file")()
455 }
456
457 f := &File{}
458 f.pos = p.pos()
459
460 // PackageClause
461 f.GoVersion = p.GoVersion
462 p.Top = false
463 if !p.got(token.Package) {
464 p.syntaxError("package statement must be first")
465 return nil
466 }
467 f.Pragma = p.takePragma()
468 f.PkgName = p.name()
469 p.want(token.Semi)
470
471 // don't bother continuing if package clause has errors
472 if p.First != nil {
473 return nil
474 }
475
476 // Accept import declarations anywhere for error tolerance, but complain.
477 // { ( ImportDecl | TopLevelDecl ) ";" }
478 prev := token.Import
479 for p.Tok != token.EOF {
480 if p.Tok == token.Import && prev != token.Import {
481 p.syntaxError("imports must appear before other declarations")
482 }
483 prev = p.Tok
484
485 switch p.Tok {
486 case token.Import:
487 p.Next()
488 f.DeclList = p.appendGroup(f.DeclList, p.importDecl)
489
490 case token.Const:
491 p.Next()
492 f.DeclList = p.appendGroup(f.DeclList, p.constDecl)
493
494 case token.TypeType:
495 p.Next()
496 f.DeclList = p.appendGroup(f.DeclList, p.typeDecl)
497
498 case token.Var:
499 p.Next()
500 f.DeclList = p.appendGroup(f.DeclList, p.varDecl)
501
502 case token.Func:
503 p.Next()
504 if d := p.funcDeclOrNil(); d != nil {
505 f.DeclList = append(f.DeclList, d)
506 }
507
508 default:
509 if p.Tok == token.Lbrace && len(f.DeclList) > 0 && isEmptyFuncDecl(f.DeclList[len(f.DeclList)-1]) {
510 // opening { of function declaration on next line
511 p.syntaxError("unexpected semicolon or newline before {")
512 } else {
513 p.syntaxError("non-declaration statement outside function body")
514 }
515 p.advance(token.Import, token.Const, token.TypeType, token.Var, token.Func)
516 continue
517 }
518
519 // Reset p.pragma BEFORE advancing to the next token (consuming ';')
520 // since comments before may set pragmas for the next function decl.
521 p.clearPragma()
522
523 if p.Tok != token.EOF && !p.got(token.Semi) {
524 p.syntaxError("after top level declaration")
525 p.advance(token.Import, token.Const, token.TypeType, token.Var, token.Func)
526 }
527 }
528 // p.tok == _EOF
529
530 p.clearPragma()
531 f.EOF = p.pos()
532
533 return f
534 }
535
536 func isEmptyFuncDecl(dcl Decl) (ok bool) {
537 f, ok := dcl.(*FuncDecl)
538 return ok && f.Body == nil
539 }
540
541 // ----------------------------------------------------------------------------
542 // Declarations
543
544 // list parses a possibly empty, sep-separated list of elements, optionally
545 // followed by sep, and closed by close (or EOF). sep must be one of _Comma
546 // or _Semi, and close must be one of _Rparen, _Rbrace, or _Rbrack.
547 //
548 // For each list element, f is called. Specifically, unless we're at close
549 // (or EOF), f is called at least once. After f returns true, no more list
550 // elements are accepted. list returns the position of the closing token.
551 //
552 // list = [ f { sep f } [sep] ] close .
553 func (p *Parser) list(context string, sep, close token.Token, f func() bool) (pv token.Pos) {
554 if debug && (sep != token.Comma && sep != token.Semi || close != token.Rparen && close != token.Rbrace && close != token.Rbrack) {
555 panic("invalid sep or close argument for list")
556 }
557
558 done := false
559 for p.Tok != token.EOF && p.Tok != close && !done {
560 done = f()
561 // sep is optional before close
562 if !p.got(sep) && p.Tok != close {
563 p.syntaxError("in " | context | "; possibly missing " | tokstring(sep) | " or " | tokstring(close))
564 p.advance(token.Rparen, token.Rbrack, token.Rbrace)
565 if p.Tok != close {
566 // position could be better but we had an error so we don't care
567 return p.pos()
568 }
569 }
570 }
571
572 pos := p.pos()
573 p.want(close)
574 return pos
575 }
576
577 // appendGroup(f) = f + "(" { f ";" } ")" . // ";" is optional before ")"
578 func (p *Parser) appendGroup(list []Decl, f func(*Group) Decl) (ds []Decl) {
579 if p.Tok == token.Lparen {
580 g := &Group{}
581 p.clearPragma()
582 p.Next() // must consume "(" after calling clearPragma!
583 p.list("grouped declaration", token.Semi, token.Rparen, func() bool {
584 if x := f(g); x != nil {
585 list = append(list, x)
586 }
587 return false
588 })
589 } else {
590 if x := f(nil); x != nil {
591 list = append(list, x)
592 }
593 }
594 return list
595 }
596
597 // ImportSpec = [ "." + PackageName ] ImportPath .
598 // ImportPath = string_lit .
599 func (p *Parser) importDecl(group *Group) (d Decl) {
600 if trace {
601 defer p.trace("importDecl")()
602 }
603
604 d := &ImportDecl{}
605 d.pos = p.pos()
606 d.Group = group
607 d.Pragma = p.takePragma()
608
609 switch p.Tok {
610 case token.NameType:
611 n := p.name()
612 if n.Value == "_" {
613 p.syntaxErrorAt(n.Pos(), "blank imports are not allowed in Moxie")
614 }
615 d.LocalPkgName = n
616 case token.Dot:
617 d.LocalPkgName = NewName(p.pos(), ".")
618 p.Next()
619 }
620 d.Path = p.oliteral()
621 if d.Path == nil {
622 p.syntaxError("missing import path")
623 p.advance(token.Semi, token.Rparen)
624 return d
625 }
626 if !d.Path.Bad && d.Path.Kind != token.StringLit {
627 p.syntaxErrorAt(d.Path.Pos(), "import path must be a string")
628 d.Path.Bad = true
629 }
630 // d.Path.Bad || d.Path.Kind == token.StringLit
631
632 return d
633 }
634
635 // ConstSpec = IdentifierList [ [ Type ] "=" ExpressionList ] .
636 func (p *Parser) constDecl(group *Group) (d Decl) {
637 if trace {
638 defer p.trace("constDecl")()
639 }
640
641 d := &ConstDecl{}
642 d.pos = p.pos()
643 d.Group = group
644 d.Pragma = p.takePragma()
645
646 d.NameList = p.nameList(p.name())
647 if p.Tok != token.EOF && p.Tok != token.Semi && p.Tok != token.Rparen {
648 d.Type = p.typeOrNil()
649 if p.gotAssign() {
650 d.Values = p.exprList()
651 }
652 }
653
654 return d
655 }
656
657 // TypeSpec = identifier [ TypeParams ] [ "=" ] Type .
658 func (p *Parser) typeDecl(group *Group) (d Decl) {
659 if trace {
660 defer p.trace("typeDecl")()
661 }
662
663 d := &TypeDecl{}
664 d.pos = p.pos()
665 d.Group = group
666 d.Pragma = p.takePragma()
667
668 d.Name = p.name()
669 if p.Tok == token.Lbrack {
670 // d.Name "[" ...
671 // array/slice type or type parameter list
672 pos := p.pos()
673 p.Next()
674 switch p.Tok {
675 case token.NameType:
676 // We may have an array type or a type parameter list.
677 // In either case we expect an expression x (which may
678 // just be a name, or a more complex expression) which
679 // we can analyze further.
680 //
681 // A type parameter list may have a type bound starting
682 // with a "[" as in: P []E. In that case, simply parsing
683 // an expression would lead to an error: P[] is invalid.
684 // But since index or slice expressions are never constant
685 // and thus invalid array length expressions, if the name
686 // is followed by "[" it must be the start of an array or
687 // slice constraint. Only if we don't see a "[" do we
688 // need to parse a full expression. Notably, name <- x
689 // is not a concern because name <- x is a statement and
690 // not an expression.
691 var x Expr = p.name()
692 if p.Tok != token.Lbrack {
693 // To parse the expression starting with name, expand
694 // the call sequence we would get by passing in name
695 // to parser.expr, and pass in name to parser.pexpr.
696 p.Xnest++
697 x = p.binaryExpr(p.pexpr(x, false), 0)
698 p.Xnest--
699 }
700 // Analyze expression x. If we can split x into a type parameter
701 // name, possibly followed by a type parameter type, we consider
702 // this the start of a type parameter list, with some caveats:
703 // a single name followed by "]" tilts the decision towards an
704 // array declaration; a type parameter type that could also be
705 // an ordinary expression but which is followed by a comma tilts
706 // the decision towards a type parameter list.
707 if pname, ptype := extractName(x, p.Tok == token.Comma); pname != nil && (ptype != nil || p.Tok != token.Rbrack) {
708 // d.Name "[" pname ...
709 // d.Name "[" pname ptype ...
710 // d.Name "[" pname ptype "," ...
711 d.TParamList = p.paramList(pname, ptype, token.Rbrack, true, false) // ptype may be nil
712 d.Alias = p.gotAssign()
713 d.Type = p.typeOrNil()
714 } else {
715 // d.Name "[" pname "]" ...
716 // d.Name "[" x ...
717 d.Type = p.arrayType(pos, x)
718 }
719 case token.Rbrack:
720 // d.Name "[" "]" ...
721 p.Next()
722 d.Type = p.sliceType(pos)
723 default:
724 // d.Name "[" ...
725 d.Type = p.arrayType(pos, nil)
726 }
727 } else {
728 d.Alias = p.gotAssign()
729 d.Type = p.typeOrNil()
730 }
731
732 if d.Type == nil {
733 d.Type = p.badExpr()
734 p.syntaxError("in type declaration")
735 p.advance(token.Semi, token.Rparen)
736 }
737
738 return d
739 }
740
741 // extractName splits the expression x into (name, expr) if syntactically
742 // x can be written as name expr. The split only happens if expr is a type
743 // element (per the isTypeElem predicate) or if force is set.
744 // If x is just a name, the result is (name, nil). If the split succeeds,
745 // the result is (name, expr). Otherwise the result is (nil, x).
746 // Examples:
747 //
748 // x force name expr
749 // ------------------------------------
750 // P*[]int32 T/F P *[]int32
751 // P*E T P *E
752 // P*E F nil P*E
753 // P([]int32) T/F P []int32
754 // P(E) T P E
755 // P(E) F nil P(E)
756 // P*E|F|~G T/F P *E|F|~G
757 // P*E|F|G T P *E|F|G
758 // P*E|F|G F nil P*E|F|G
759 func extractName(x Expr, force bool) (*Name, Expr) {
760 switch x := x.(type) {
761 case *Name:
762 return x, nil
763 case *Operation:
764 if x.Y == nil {
765 break // unary expr
766 }
767 switch x.Op {
768 case token.Mul:
769 if name, _ := x.X.(*Name); name != nil && (force || isTypeElem(x.Y)) {
770 // x = name *x.Y
771 op := *x
772 op.X, op.Y = op.Y, nil // change op into unary *op.Y
773 return name, &op
774 }
775 case token.Or:
776 if name, lhs := extractName(x.X, force || isTypeElem(x.Y)); name != nil && lhs != nil {
777 // x = name lhs|x.Y
778 op := *x
779 op.X = lhs
780 return name, &op
781 }
782 }
783 case *CallExpr:
784 if name, _ := x.Fun.(*Name); name != nil {
785 if len(x.ArgList) == 1 && !x.HasDots && (force || isTypeElem(x.ArgList[0])) {
786 // The parser doesn't keep unnecessary parentheses.
787 // Set the flag below to keep them, for testing
788 // (see go.dev/issues/69206).
789 const keep_parens = false
790 if keep_parens {
791 // x = name (x.ArgList[0])
792 px := &ParenExpr{}
793 px.pos = x.pos // position of "(" in call
794 px.X = x.ArgList[0]
795 return name, px
796 } else {
797 // x = name x.ArgList[0]
798 return name, Unparen(x.ArgList[0])
799 }
800 }
801 }
802 }
803 return nil, x
804 }
805
806 // isTypeElem reports whether x is a (possibly parenthesized) type element expression.
807 // The result is false if x could be a type element OR an ordinary (value) expression.
808 func isTypeElem(x Expr) (ok bool) {
809 switch x := x.(type) {
810 case *ArrayType, *StructType, *FuncType, *InterfaceType, *SliceType, *MapType, *ChanType:
811 return true
812 case *Operation:
813 return isTypeElem(x.X) || (x.Y != nil && isTypeElem(x.Y)) || x.Op == token.Tilde
814 case *ParenExpr:
815 return isTypeElem(x.X)
816 }
817 return false
818 }
819
820 // VarSpec = IdentifierList ( Type [ "=" ExpressionList ] + "=" ExpressionList ) .
821 func (p *Parser) varDecl(group *Group) (d Decl) {
822 if trace {
823 defer p.trace("varDecl")()
824 }
825
826 d := &VarDecl{}
827 d.pos = p.pos()
828 d.Group = group
829 d.Pragma = p.takePragma()
830
831 d.NameList = p.nameList(p.name())
832 if p.gotAssign() {
833 d.Values = p.exprList()
834 } else {
835 d.Type = p.type_()
836 if p.gotAssign() {
837 d.Values = p.exprList()
838 }
839 }
840
841 return d
842 }
843
844 // FunctionDecl = "func" FunctionName [ TypeParams ] ( Function | Signature ) .
845 // FunctionName = identifier .
846 // Function = Signature FunctionBody .
847 // MethodDecl = "func" Receiver MethodName ( Function | Signature ) .
848 // Receiver = Parameters .
849 func (p *Parser) funcDeclOrNil() (ret Decl) {
850 if trace {
851 defer p.trace("funcDecl")()
852 }
853
854 f := &FuncDecl{}
855 f.pos = p.pos()
856 f.Pragma = p.takePragma()
857
858 var context string
859 if p.got(token.Lparen) {
860 context = "method"
861 rcvr := p.paramList(nil, nil, token.Rparen, false, false)
862 switch len(rcvr) {
863 case 0:
864 p.error("method has no receiver")
865 default:
866 p.error("method has multiple receivers")
867 f.Recv = rcvr[0]
868 case 1:
869 f.Recv = rcvr[0]
870 }
871 }
872
873 if p.Tok == token.NameType {
874 f.Name = p.name()
875 f.TParamList, f.Type = p.funcType(context)
876 } else {
877 f.Name = NewName(p.pos(), "_")
878 f.Type = &FuncType{}
879 f.Type.pos = p.pos()
880 msg := "expected name or ("
881 if context != "" {
882 msg = "expected name"
883 }
884 p.syntaxError(msg)
885 p.advance(token.Lbrace, token.Semi)
886 }
887
888 if p.Tok == token.Lbrace {
889 f.Body = p.funcBody()
890 }
891
892 return f
893 }
894
895 func (p *Parser) funcBody() (b *BlockStmt) {
896 p.Fnest++
897 body := p.blockStmt("")
898 p.Fnest--
899
900 return body
901 }
902
903 // ----------------------------------------------------------------------------
904 // Expressions
905
906 func (p *Parser) expr() (e Expr) {
907 if trace {
908 defer p.trace("expr")()
909 }
910
911 return p.binaryExpr(nil, 0)
912 }
913
914 // Expression = UnaryExpr | Expression binary_op Expression .
915 func (p *Parser) binaryExpr(x Expr, prec int32) (e Expr) {
916 // don't trace binaryExpr - only leads to overly nested trace output
917
918 if x == nil {
919 x = p.unaryExpr()
920 }
921 for (p.Tok == token.OperatorType || p.Tok == token.Star) && p.Prec > prec {
922 t := &Operation{}
923 t.pos = p.pos()
924 t.Op = p.Op
925 tprec := p.Prec
926 p.Next()
927 t.X = x
928 t.Y = p.binaryExpr(nil, tprec)
929 x = t
930 }
931 return x
932 }
933
934 // UnaryExpr = PrimaryExpr | unary_op UnaryExpr .
935 func (p *Parser) unaryExpr() (e Expr) {
936 if trace {
937 defer p.trace("unaryExpr")()
938 }
939
940 switch p.Tok {
941 case token.OperatorType, token.Star:
942 switch p.Op {
943 case token.Mul, token.Add, token.Sub, token.Not, token.Xor, token.Tilde:
944 x := &Operation{}
945 x.pos = p.pos()
946 x.Op = p.Op
947 p.Next()
948 x.X = p.unaryExpr()
949 return x
950
951 case token.And:
952 x := &Operation{}
953 x.pos = p.pos()
954 x.Op = token.And
955 p.Next()
956 // unaryExpr may have returned a parenthesized composite literal
957 // (see comment in operand) - remove parentheses if any
958 x.X = Unparen(p.unaryExpr())
959 return x
960 }
961
962 case token.Arrow:
963 // receive op (<-x) or receive-only channel (<-chan E)
964 pos := p.pos()
965 p.Next()
966
967 // If the next token is _Chan we still don't know if it is
968 // a channel (<-chan int32) or a receive op (<-chan int32(ch)).
969 // We only know once we have found the end of the unaryExpr.
970
971 x := p.unaryExpr()
972
973 // There are two cases:
974 //
975 // <-chan... => <-x is a channel type
976 // <-x => <-x is a receive operation
977 //
978 // In the first case, <- must be re-associated with
979 // the channel type parsed already:
980 //
981 // <-(chan E) => (<-chan E)
982 // <-(chan<-E) => (<-chan (<-E))
983
984 if _, ok := x.(*ChanType); ok {
985 // x is a channel type => re-associate <-
986 dir := SendOnly
987 t := x
988 for dir == SendOnly {
989 c, ok := t.(*ChanType)
990 if !ok {
991 break
992 }
993 dir = c.Dir
994 if dir == RecvOnly {
995 // t is type <-chan E but <-<-chan E is not permitted
996 // (report same error as for "type _ <-<-chan E")
997 p.syntaxError("unexpected <-, expected chan")
998 // already progressed, no need to advance
999 }
1000 c.Dir = RecvOnly
1001 t = c.Elem
1002 }
1003 if dir == SendOnly {
1004 // channel dir is <- but channel element E is not a channel
1005 // (report same error as for "type _ <-chan<-E")
1006 p.syntaxError("unexpected " | String(t) | ", expected chan")
1007 // already progressed, no need to advance
1008 }
1009 return x
1010 }
1011
1012 // x is not a channel type => we have a receive op
1013 o := &Operation{}
1014 o.pos = pos
1015 o.Op = token.Recv
1016 o.X = x
1017 return o
1018 }
1019
1020 // TODO(mdempsky): We need parens here so we can report an
1021 // error for "(x) := true". It should be possible to detect
1022 // and reject that more efficiently though.
1023 return p.pexpr(nil, true)
1024 }
1025
1026 // callStmt parses call-like statements that can be preceded by 'defer' and 'go'.
1027 func (p *Parser) callStmt() (c *CallStmt) {
1028 if trace {
1029 defer p.trace("callStmt")()
1030 }
1031
1032 s := &CallStmt{}
1033 s.pos = p.pos()
1034 s.Tok = p.Tok // _Defer or _Go
1035 p.Next()
1036
1037 x := p.pexpr(nil, p.Tok == token.Lparen) // keep_parens so we can report error below
1038 if t := Unparen(x); t != x {
1039 p.errorAt(x.Pos(), "expression in " | s.Tok.String() | " must not be parenthesized")
1040 // already progressed, no need to advance
1041 x = t
1042 }
1043
1044 s.Call = x
1045 return s
1046 }
1047
1048 // Operand = Literal | OperandName | MethodExpr + "(" Expression ")" .
1049 // Literal = BasicLit | CompositeLit | FunctionLit .
1050 // BasicLit = int_lit | float_lit | imaginary_lit | rune_lit | string_lit .
1051 // OperandName = identifier | QualifiedIdent.
1052 func (p *Parser) operand(keep_parens bool) (e Expr) {
1053 if trace {
1054 defer p.trace("operand " | p.Tok.String())()
1055 }
1056
1057 switch p.Tok {
1058 case token.NameType:
1059 return p.name()
1060
1061 case token.Literal:
1062 return p.oliteral()
1063
1064 case token.Lparen:
1065 pos := p.pos()
1066 p.Next()
1067 p.Xnest++
1068 x := p.expr()
1069 p.Xnest--
1070 p.want(token.Rparen)
1071
1072 // Optimization: Record presence of ()'s only where needed
1073 // for error reporting. Don't bother in other cases; it is
1074 // just a waste of memory and time.
1075 //
1076 // Parentheses are not permitted around T in a composite
1077 // literal T{}. If the next token is a {, assume x is a
1078 // composite literal type T (it may not be, { could be
1079 // the opening brace of a block, but we don't know yet).
1080 if p.Tok == token.Lbrace {
1081 keep_parens = true
1082 }
1083
1084 // Parentheses are also not permitted around the expression
1085 // in a go/defer statement. In that case, operand is called
1086 // with keep_parens set.
1087 if keep_parens {
1088 px := &ParenExpr{}
1089 px.pos = pos
1090 px.X = x
1091 x = px
1092 }
1093 return x
1094
1095 case token.Func:
1096 pos := p.pos()
1097 p.Next()
1098 _, ftyp := p.funcType("function type")
1099 if p.Tok == token.Lbrace {
1100 p.Xnest++
1101
1102 f := &FuncLit{}
1103 f.pos = pos
1104 f.Type = ftyp
1105 f.Body = p.funcBody()
1106
1107 p.Xnest--
1108 return f
1109 }
1110 return ftyp
1111
1112 case token.Lbrack, token.Chan, token.Map, token.Struct, token.Interface:
1113 return p.type_() // othertype
1114
1115 default:
1116 x := p.badExpr()
1117 p.syntaxError("expected expression")
1118 p.advance(token.Rparen, token.Rbrack, token.Rbrace)
1119 return x
1120 }
1121
1122 // Syntactically, composite literals are operands. Because a complit
1123 // type may be a qualified identifier which is handled by pexpr
1124 // (together with selector expressions), complits are parsed there
1125 // as well (operand is only called from pexpr).
1126 }
1127
1128 // pexpr parses a PrimaryExpr.
1129 //
1130 // PrimaryExpr =
1131 // Operand |
1132 // Conversion |
1133 // PrimaryExpr Selector |
1134 // PrimaryExpr Index |
1135 // PrimaryExpr Slice |
1136 // PrimaryExpr TypeAssertion |
1137 // PrimaryExpr Arguments .
1138 //
1139 // Selector = "." identifier .
1140 // Index = "[" Expression "]" .
1141 // Slice = "[" ( [ Expression ] ":" [ Expression ] ) |
1142 // ( [ Expression ] ":" Expression ":" Expression )
1143 // "]" .
1144 // TypeAssertion = "." "(" Type ")" .
1145 // Arguments = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" .
1146 func (p *Parser) pexpr(x Expr, keep_parens bool) (e Expr) {
1147 if trace {
1148 defer p.trace("pexpr")()
1149 }
1150
1151 if x == nil {
1152 x = p.operand(keep_parens)
1153 }
1154
1155 loop:
1156 for {
1157 pos := p.pos()
1158 switch p.Tok {
1159 case token.Dot:
1160 p.Next()
1161 switch p.Tok {
1162 case token.NameType:
1163 // pexpr '.' sym
1164 t := &SelectorExpr{}
1165 t.pos = pos
1166 t.X = x
1167 t.Sel = p.name()
1168 x = t
1169
1170 case token.Lparen:
1171 p.Next()
1172 if p.got(token.TypeType) {
1173 t := &TypeSwitchGuard{}
1174 // t.Lhs is filled in by parser.simpleStmt
1175 t.pos = pos
1176 t.X = x
1177 x = t
1178 } else {
1179 t := &AssertExpr{}
1180 t.pos = pos
1181 t.X = x
1182 t.Type = p.type_()
1183 x = t
1184 }
1185 p.want(token.Rparen)
1186
1187 default:
1188 p.syntaxError("expected name or (")
1189 p.advance(token.Semi, token.Rparen)
1190 }
1191
1192 case token.Lbrack:
1193 p.Next()
1194
1195 var i Expr
1196 if p.Tok != token.Colon {
1197 var comma bool
1198 if p.Tok == token.Rbrack {
1199 // invalid empty instance, slice or index expression; accept but complain
1200 p.syntaxError("expected operand")
1201 i = p.badExpr()
1202 } else {
1203 i, comma = p.typeList(false)
1204 }
1205 if comma || p.Tok == token.Rbrack {
1206 p.want(token.Rbrack)
1207 // x[], x[i,] or x[i, j, ...]
1208 t := &IndexExpr{}
1209 t.pos = pos
1210 t.X = x
1211 t.Index = i
1212 x = t
1213 break
1214 }
1215 }
1216
1217 // x[i:...
1218 // For better error message, don't simply use p.want(_Colon) here (go.dev/issue/47704).
1219 if !p.got(token.Colon) {
1220 p.syntaxError("expected comma, : or ]")
1221 p.advance(token.Comma, token.Colon, token.Rbrack)
1222 }
1223 p.Xnest++
1224 t := &SliceExpr{}
1225 t.pos = pos
1226 t.X = x
1227 t.Index[0] = i
1228 if p.Tok != token.Colon && p.Tok != token.Rbrack {
1229 // x[i:j...
1230 t.Index[1] = p.expr()
1231 }
1232 if p.Tok == token.Colon {
1233 t.Full = true
1234 // x[i:j:...]
1235 if t.Index[1] == nil {
1236 p.error("middle index required in 3-index slice")
1237 t.Index[1] = p.badExpr()
1238 }
1239 p.Next()
1240 if p.Tok != token.Rbrack {
1241 // x[i:j:k...
1242 t.Index[2] = p.expr()
1243 } else {
1244 p.error("final index required in 3-index slice")
1245 t.Index[2] = p.badExpr()
1246 }
1247 }
1248 p.Xnest--
1249 p.want(token.Rbrack)
1250 x = t
1251
1252 case token.Lparen:
1253 t := &CallExpr{}
1254 t.pos = pos
1255 p.Next()
1256 t.Fun = x
1257 t.ArgList, t.HasDots = p.argList()
1258 x = t
1259
1260 case token.Lbrace:
1261 // operand may have returned a parenthesized complit
1262 // type; accept it but complain if we have a complit
1263 t := Unparen(x)
1264 // determine if '{' belongs to a composite literal or a block statement
1265 complit_ok := false
1266 switch t.(type) {
1267 case *Name, *SelectorExpr:
1268 if p.Xnest >= 0 {
1269 // x is possibly a composite literal type
1270 complit_ok = true
1271 }
1272 case *IndexExpr:
1273 if p.Xnest >= 0 && !isValue(t) {
1274 // x is possibly a composite literal type
1275 complit_ok = true
1276 }
1277 case *ArrayType, *SliceType, *StructType, *MapType:
1278 // x is a comptype
1279 complit_ok = true
1280 }
1281 if !complit_ok {
1282 break loop
1283 }
1284 if t != x {
1285 p.syntaxError("cannot parenthesize type in composite literal")
1286 // already progressed, no need to advance
1287 }
1288 n := p.complitexpr()
1289 n.Type = x
1290 x = n
1291
1292 default:
1293 break loop
1294 }
1295 }
1296
1297 return x
1298 }
1299
1300 // isValue reports whether x syntactically must be a value (and not a type) expression.
1301 func isValue(x Expr) (ok bool) {
1302 switch x := x.(type) {
1303 case *BasicLit, *CompositeLit, *FuncLit, *SliceExpr, *AssertExpr, *TypeSwitchGuard, *CallExpr:
1304 return true
1305 case *Operation:
1306 return x.Op != token.Mul || x.Y != nil // *T may be a type
1307 case *ParenExpr:
1308 return isValue(x.X)
1309 case *IndexExpr:
1310 return isValue(x.X) || isValue(x.Index)
1311 }
1312 return false
1313 }
1314
1315 // Element = Expression | LiteralValue .
1316 func (p *Parser) bare_complitexpr() (e Expr) {
1317 if trace {
1318 defer p.trace("bare_complitexpr")()
1319 }
1320
1321 if p.Tok == token.Lbrace {
1322 // '{' start_complit braced_keyval_list '}'
1323 return p.complitexpr()
1324 }
1325
1326 return p.expr()
1327 }
1328
1329 // LiteralValue = "{" [ ElementList [ "," ] ] "}" .
1330 func (p *Parser) complitexpr() (c *CompositeLit) {
1331 if trace {
1332 defer p.trace("complitexpr")()
1333 }
1334
1335 x := &CompositeLit{}
1336 x.pos = p.pos()
1337
1338 p.Xnest++
1339 p.want(token.Lbrace)
1340 x.Rbrace = p.list("composite literal", token.Comma, token.Rbrace, func() bool {
1341 // value
1342 e := p.bare_complitexpr()
1343 if p.Tok == token.Colon {
1344 // key ':' value
1345 l := &KeyValueExpr{}
1346 l.pos = p.pos()
1347 p.Next()
1348 l.Key = e
1349 l.Value = p.bare_complitexpr()
1350 e = l
1351 x.NKeys++
1352 }
1353 x.ElemList = append(x.ElemList, e)
1354 return false
1355 })
1356 p.Xnest--
1357
1358 return x
1359 }
1360
1361 // ----------------------------------------------------------------------------
1362 // Types
1363
1364 func (p *Parser) type_() (e Expr) {
1365 if trace {
1366 defer p.trace("type_")()
1367 }
1368
1369 typ := p.typeOrNil()
1370 if typ == nil {
1371 typ = p.badExpr()
1372 p.syntaxError("expected type")
1373 p.advance(token.Comma, token.Colon, token.Semi, token.Rparen, token.Rbrack, token.Rbrace)
1374 }
1375
1376 return typ
1377 }
1378
1379 func newIndirect(pos token.Pos, typ Expr) (e Expr) {
1380 o := &Operation{}
1381 o.pos = pos
1382 o.Op = token.Mul
1383 o.X = typ
1384 return o
1385 }
1386
1387 // typeOrNil is like type_ but it returns nil if there was no type
1388 // instead of reporting an error.
1389 //
1390 // Type = TypeName | TypeLit + "(" Type ")" .
1391 // TypeName = identifier | QualifiedIdent .
1392 // TypeLit = ArrayType | StructType | PointerType | FunctionType | InterfaceType |
1393 // SliceType | MapType | Channel_Type .
1394 func (p *Parser) typeOrNil() (e Expr) {
1395 if trace {
1396 defer p.trace("typeOrNil")()
1397 }
1398
1399 pos := p.pos()
1400 switch p.Tok {
1401 case token.Star:
1402 // ptrtype
1403 p.Next()
1404 return newIndirect(pos, p.type_())
1405
1406 case token.Arrow:
1407 // recvchantype
1408 p.Next()
1409 p.want(token.Chan)
1410 t := &ChanType{}
1411 t.pos = pos
1412 t.Dir = RecvOnly
1413 t.Elem = p.chanElem()
1414 return t
1415
1416 case token.Func:
1417 // fntype
1418 p.Next()
1419 _, t := p.funcType("function type")
1420 return t
1421
1422 case token.Lbrack:
1423 // '[' oexpr ']' ntype
1424 // '[' _DotDotDot ']' ntype
1425 p.Next()
1426 if p.got(token.Rbrack) {
1427 return p.sliceType(pos)
1428 }
1429 return p.arrayType(pos, nil)
1430
1431 case token.Chan:
1432 // _Chan non_recvchantype
1433 // _Chan _Comm ntype
1434 p.Next()
1435 t := &ChanType{}
1436 t.pos = pos
1437 if p.got(token.Arrow) {
1438 t.Dir = SendOnly
1439 }
1440 t.Elem = p.chanElem()
1441 return t
1442
1443 case token.Map:
1444 // _Map '[' ntype ']' ntype
1445 p.Next()
1446 p.want(token.Lbrack)
1447 t := &MapType{}
1448 t.pos = pos
1449 t.Key = p.type_()
1450 p.want(token.Rbrack)
1451 t.Value = p.type_()
1452 return t
1453
1454 case token.Struct:
1455 return p.structType()
1456
1457 case token.Interface:
1458 return p.interfaceType()
1459
1460 case token.NameType:
1461 return p.qualifiedName(nil)
1462
1463 case token.Lparen:
1464 p.Next()
1465 t := p.type_()
1466 p.want(token.Rparen)
1467 // The parser doesn't keep unnecessary parentheses.
1468 // Set the flag below to keep them, for testing
1469 // (see e.g. tests for go.dev/issue/68639).
1470 const keep_parens = false
1471 if keep_parens {
1472 px := &ParenExpr{}
1473 px.pos = pos
1474 px.X = t
1475 t = px
1476 }
1477 return t
1478 }
1479
1480 return nil
1481 }
1482
1483 func (p *Parser) typeInstance(typ Expr) (e Expr) {
1484 if trace {
1485 defer p.trace("typeInstance")()
1486 }
1487
1488 pos := p.pos()
1489 p.want(token.Lbrack)
1490 x := &IndexExpr{}
1491 x.pos = pos
1492 x.X = typ
1493 if p.Tok == token.Rbrack {
1494 p.syntaxError("expected type argument list")
1495 x.Index = p.badExpr()
1496 } else {
1497 x.Index, _ = p.typeList(true)
1498 }
1499 p.want(token.Rbrack)
1500 return x
1501 }
1502
1503 // If context != "", type parameters are not permitted.
1504 func (p *Parser) funcType(context string) ([]*Field, *FuncType) {
1505 if trace {
1506 defer p.trace("funcType")()
1507 }
1508
1509 typ := &FuncType{}
1510 typ.pos = p.pos()
1511
1512 var tparamList []*Field
1513 if p.got(token.Lbrack) {
1514 if context != "" {
1515 // accept but complain
1516 p.syntaxErrorAt(typ.pos, context | " must have no type parameters")
1517 }
1518 if p.Tok == token.Rbrack {
1519 p.syntaxError("empty type parameter list")
1520 p.Next()
1521 } else {
1522 tparamList = p.paramList(nil, nil, token.Rbrack, true, false)
1523 }
1524 }
1525
1526 p.want(token.Lparen)
1527 typ.ParamList = p.paramList(nil, nil, token.Rparen, false, true)
1528 typ.ResultList = p.funcResult()
1529
1530 return tparamList, typ
1531 }
1532
1533 // "[" has already been consumed, and pos is its position.
1534 // If len != nil it is the already consumed array length.
1535 func (p *Parser) arrayType(pos token.Pos, len Expr) (e Expr) {
1536 if trace {
1537 defer p.trace("arrayType")()
1538 }
1539
1540 if len == nil && !p.got(token.DotDotDot) {
1541 p.Xnest++
1542 len = p.expr()
1543 p.Xnest--
1544 }
1545 if p.Tok == token.Comma {
1546 // Trailing commas are accepted in type parameter
1547 // lists but not in array type declarations.
1548 // Accept for better error handling but complain.
1549 p.syntaxError("unexpected comma; expected ]")
1550 p.Next()
1551 }
1552 p.want(token.Rbrack)
1553 t := &ArrayType{}
1554 t.pos = pos
1555 t.Len = len
1556 t.Elem = p.type_()
1557 return t
1558 }
1559
1560 // "[" and "]" have already been consumed, and pos is the position of "[".
1561 func (p *Parser) sliceType(pos token.Pos) (e Expr) {
1562 t := &SliceType{}
1563 t.pos = pos
1564 t.Elem = p.type_()
1565 return t
1566 }
1567
1568 func (p *Parser) chanElem() (e Expr) {
1569 if trace {
1570 defer p.trace("chanElem")()
1571 }
1572
1573 typ := p.typeOrNil()
1574 if typ == nil {
1575 typ = p.badExpr()
1576 p.syntaxError("missing channel element type")
1577 // assume element type is simply absent - don't advance
1578 }
1579
1580 return typ
1581 }
1582
1583 // StructType = "struct" "{" { FieldDecl ";" } "}" .
1584 func (p *Parser) structType() (s *StructType) {
1585 if trace {
1586 defer p.trace("structType")()
1587 }
1588
1589 typ := &StructType{}
1590 typ.pos = p.pos()
1591
1592 p.want(token.Struct)
1593 p.want(token.Lbrace)
1594 p.list("struct type", token.Semi, token.Rbrace, func() bool {
1595 p.fieldDecl(typ)
1596 return false
1597 })
1598
1599 return typ
1600 }
1601
1602 // InterfaceType = "interface" "{" { ( MethodDecl | EmbeddedElem ) ";" } "}" .
1603 func (p *Parser) interfaceType() (i *InterfaceType) {
1604 if trace {
1605 defer p.trace("interfaceType")()
1606 }
1607
1608 typ := &InterfaceType{}
1609 typ.pos = p.pos()
1610
1611 p.want(token.Interface)
1612 p.want(token.Lbrace)
1613 p.list("interface type", token.Semi, token.Rbrace, func() bool {
1614 var f *Field
1615 if p.Tok == token.NameType {
1616 f = p.methodDecl()
1617 }
1618 if f == nil || f.Name == nil {
1619 f = p.embeddedElem(f)
1620 }
1621 typ.MethodList = append(typ.MethodList, f)
1622 return false
1623 })
1624
1625 return typ
1626 }
1627
1628 // Result = Parameters | Type .
1629 func (p *Parser) funcResult() (fs []*Field) {
1630 if trace {
1631 defer p.trace("funcResult")()
1632 }
1633
1634 if p.got(token.Lparen) {
1635 return p.paramList(nil, nil, token.Rparen, false, false)
1636 }
1637
1638 pos := p.pos()
1639 if typ := p.typeOrNil(); typ != nil {
1640 f := &Field{}
1641 f.pos = pos
1642 f.Type = typ
1643 return []*Field{f}
1644 }
1645
1646 return nil
1647 }
1648
1649 func (p *Parser) addField(styp *StructType, pos token.Pos, name *Name, typ Expr, tag *BasicLit) {
1650 if tag != nil {
1651 for i := len(styp.FieldList) - len(styp.TagList); i > 0; i-- {
1652 styp.TagList = append(styp.TagList, nil)
1653 }
1654 styp.TagList = append(styp.TagList, tag)
1655 }
1656
1657 f := &Field{}
1658 f.pos = pos
1659 f.Name = name
1660 f.Type = typ
1661 styp.FieldList = append(styp.FieldList, f)
1662
1663 if debug && tag != nil && len(styp.FieldList) != len(styp.TagList) {
1664 panic("inconsistent struct field list")
1665 }
1666 }
1667
1668 // FieldDecl = (IdentifierList Type | AnonymousField) [ Tag ] .
1669 // AnonymousField = [ "*" ] TypeName .
1670 // Tag = string_lit .
1671 func (p *Parser) fieldDecl(styp *StructType) {
1672 if trace {
1673 defer p.trace("fieldDecl")()
1674 }
1675
1676 pos := p.pos()
1677 switch p.Tok {
1678 case token.NameType:
1679 name := p.name()
1680 if p.Tok == token.Dot || p.Tok == token.Literal || p.Tok == token.Semi || p.Tok == token.Rbrace {
1681 // embedded type
1682 typ := p.qualifiedName(name)
1683 tag := p.oliteral()
1684 p.addField(styp, pos, nil, typ, tag)
1685 break
1686 }
1687
1688 // name1, name2, ... Type [ tag ]
1689 names := p.nameList(name)
1690 var typ Expr
1691
1692 // Careful dance: We don't know if we have an embedded instantiated
1693 // type T[P1, P2, ...] or a field T of array/slice type [P]E or []E.
1694 if len(names) == 1 && p.Tok == token.Lbrack {
1695 typ = p.arrayOrTArgs()
1696 if typ, ok := typ.(*IndexExpr); ok {
1697 // embedded type T[P1, P2, ...]
1698 typ.X = name // name == names[0]
1699 tag := p.oliteral()
1700 p.addField(styp, pos, nil, typ, tag)
1701 break
1702 }
1703 } else {
1704 // T P
1705 typ = p.type_()
1706 }
1707
1708 tag := p.oliteral()
1709
1710 for _, name := range names {
1711 p.addField(styp, name.Pos(), name, typ, tag)
1712 }
1713
1714 case token.Star:
1715 p.Next()
1716 var typ Expr
1717 if p.Tok == token.Lparen {
1718 // *(T)
1719 p.syntaxError("cannot parenthesize embedded type")
1720 p.Next()
1721 typ = p.qualifiedName(nil)
1722 p.got(token.Rparen) // no need to complain if missing
1723 } else {
1724 // *T
1725 typ = p.qualifiedName(nil)
1726 }
1727 tag := p.oliteral()
1728 p.addField(styp, pos, nil, newIndirect(pos, typ), tag)
1729
1730 case token.Lparen:
1731 p.syntaxError("cannot parenthesize embedded type")
1732 p.Next()
1733 var typ Expr
1734 if p.Tok == token.Star {
1735 // (*T)
1736 pos := p.pos()
1737 p.Next()
1738 typ = newIndirect(pos, p.qualifiedName(nil))
1739 } else {
1740 // (T)
1741 typ = p.qualifiedName(nil)
1742 }
1743 p.got(token.Rparen) // no need to complain if missing
1744 tag := p.oliteral()
1745 p.addField(styp, pos, nil, typ, tag)
1746
1747 default:
1748 p.syntaxError("expected field name or embedded type")
1749 p.advance(token.Semi, token.Rbrace)
1750 }
1751 }
1752
1753 func (p *Parser) arrayOrTArgs() (e Expr) {
1754 if trace {
1755 defer p.trace("arrayOrTArgs")()
1756 }
1757
1758 pos := p.pos()
1759 p.want(token.Lbrack)
1760 if p.got(token.Rbrack) {
1761 return p.sliceType(pos)
1762 }
1763
1764 // x [n]E or x[n,], x[n1, n2], ...
1765 n, comma := p.typeList(false)
1766 p.want(token.Rbrack)
1767 if !comma {
1768 if elem := p.typeOrNil(); elem != nil {
1769 // x [n]E
1770 t := &ArrayType{}
1771 t.pos = pos
1772 t.Len = n
1773 t.Elem = elem
1774 return t
1775 }
1776 }
1777
1778 // x[n,], x[n1, n2], ...
1779 t := &IndexExpr{}
1780 t.pos = pos
1781 // t.X will be filled in by caller
1782 t.Index = n
1783 return t
1784 }
1785
1786 func (p *Parser) oliteral() (b *BasicLit) {
1787 if p.Tok == token.Literal {
1788 b := &BasicLit{}
1789 b.pos = p.pos()
1790 b.Value = p.Lit
1791 b.Kind = p.Kind
1792 b.Bad = p.Bad
1793 p.Next()
1794 return b
1795 }
1796 return nil
1797 }
1798
1799 // MethodSpec = MethodName Signature | InterfaceTypeName .
1800 // MethodName = identifier .
1801 // InterfaceTypeName = TypeName .
1802 func (p *Parser) methodDecl() (f *Field) {
1803 if trace {
1804 defer p.trace("methodDecl")()
1805 }
1806
1807 f := &Field{}
1808 f.pos = p.pos()
1809 name := p.name()
1810
1811 const context = "interface method"
1812
1813 switch p.Tok {
1814 case token.Lparen:
1815 // method
1816 f.Name = name
1817 _, f.Type = p.funcType(context)
1818
1819 case token.Lbrack:
1820 // Careful dance: We don't know if we have a generic method m[T C](x T)
1821 // or an embedded instantiated type T[P1, P2] (we accept generic methods
1822 // for generality and robustness of parsing but complain with an error).
1823 pos := p.pos()
1824 p.Next()
1825
1826 // Empty type parameter or argument lists are not permitted.
1827 // Treat as if [] were absent.
1828 if p.Tok == token.Rbrack {
1829 // name[]
1830 pos := p.pos()
1831 p.Next()
1832 if p.Tok == token.Lparen {
1833 // name[](
1834 p.errorAt(pos, "empty type parameter list")
1835 f.Name = name
1836 _, f.Type = p.funcType(context)
1837 } else {
1838 p.errorAt(pos, "empty type argument list")
1839 f.Type = name
1840 }
1841 break
1842 }
1843
1844 // A type argument list looks like a parameter list with only
1845 // types. Parse a parameter list and decide afterwards.
1846 list := p.paramList(nil, nil, token.Rbrack, false, false)
1847 if len(list) == 0 {
1848 // The type parameter list is not [] but we got nothing
1849 // due to other errors (reported by paramList). Treat
1850 // as if [] were absent.
1851 if p.Tok == token.Lparen {
1852 f.Name = name
1853 _, f.Type = p.funcType(context)
1854 } else {
1855 f.Type = name
1856 }
1857 break
1858 }
1859
1860 // len(list) > 0
1861 if list[0].Name != nil {
1862 // generic method
1863 f.Name = name
1864 _, f.Type = p.funcType(context)
1865 p.errorAt(pos, "interface method must have no type parameters")
1866 break
1867 }
1868
1869 // embedded instantiated type
1870 t := &IndexExpr{}
1871 t.pos = pos
1872 t.X = name
1873 if len(list) == 1 {
1874 t.Index = list[0].Type
1875 } else {
1876 // len(list) > 1
1877 l := &ListExpr{}
1878 l.pos = list[0].Pos()
1879 l.ElemList = []Expr{:len(list)}
1880 for i := range list {
1881 l.ElemList[i] = list[i].Type
1882 }
1883 t.Index = l
1884 }
1885 f.Type = t
1886
1887 default:
1888 // embedded type
1889 f.Type = p.qualifiedName(name)
1890 }
1891
1892 return f
1893 }
1894
1895 // EmbeddedElem = MethodSpec | EmbeddedTerm { "|" EmbeddedTerm } .
1896 func (p *Parser) embeddedElem(f *Field) (fv *Field) {
1897 if trace {
1898 defer p.trace("embeddedElem")()
1899 }
1900
1901 if f == nil {
1902 f = &Field{}
1903 f.pos = p.pos()
1904 f.Type = p.embeddedTerm()
1905 }
1906
1907 for p.Tok == token.OperatorType && p.Op == token.Or {
1908 t := &Operation{}
1909 t.pos = p.pos()
1910 t.Op = token.Or
1911 p.Next()
1912 t.X = f.Type
1913 t.Y = p.embeddedTerm()
1914 f.Type = t
1915 }
1916
1917 return f
1918 }
1919
1920 // EmbeddedTerm = [ "~" ] Type .
1921 func (p *Parser) embeddedTerm() (e Expr) {
1922 if trace {
1923 defer p.trace("embeddedTerm")()
1924 }
1925
1926 if p.Tok == token.OperatorType && p.Op == token.Tilde {
1927 t := &Operation{}
1928 t.pos = p.pos()
1929 t.Op = token.Tilde
1930 p.Next()
1931 t.X = p.type_()
1932 return t
1933 }
1934
1935 t := p.typeOrNil()
1936 if t == nil {
1937 t = p.badExpr()
1938 p.syntaxError("expected ~ term or type")
1939 p.advance(token.OperatorType, token.Semi, token.Rparen, token.Rbrack, token.Rbrace)
1940 }
1941
1942 return t
1943 }
1944
1945 // ParameterDecl = [ IdentifierList ] [ "..." ] Type .
1946 func (p *Parser) paramDeclOrNil(name *Name, follow token.Token) (f *Field) {
1947 if trace {
1948 defer p.trace("paramDeclOrNil")()
1949 }
1950
1951 // type set notation is ok in type parameter lists
1952 typeSetsOk := follow == token.Rbrack
1953
1954 pos := p.pos()
1955 if name != nil {
1956 pos = name.pos
1957 } else if typeSetsOk && p.Tok == token.OperatorType && p.Op == token.Tilde {
1958 // "~" ...
1959 return p.embeddedElem(nil)
1960 }
1961
1962 f := &Field{}
1963 f.pos = pos
1964
1965 if p.Tok == token.NameType || name != nil {
1966 // name
1967 if name == nil {
1968 name = p.name()
1969 }
1970
1971 if p.Tok == token.Lbrack {
1972 // name "[" ...
1973 f.Type = p.arrayOrTArgs()
1974 if typ, ok := f.Type.(*IndexExpr); ok {
1975 // name "[" ... "]"
1976 typ.X = name
1977 } else {
1978 // name "[" n "]" E
1979 f.Name = name
1980 }
1981 if typeSetsOk && p.Tok == token.OperatorType && p.Op == token.Or {
1982 // name "[" ... "]" "|" ...
1983 // name "[" n "]" E "|" ...
1984 f = p.embeddedElem(f)
1985 }
1986 return f
1987 }
1988
1989 if p.Tok == token.Dot {
1990 // name "." ...
1991 f.Type = p.qualifiedName(name)
1992 if typeSetsOk && p.Tok == token.OperatorType && p.Op == token.Or {
1993 // name "." name "|" ...
1994 f = p.embeddedElem(f)
1995 }
1996 return f
1997 }
1998
1999 if typeSetsOk && p.Tok == token.OperatorType && p.Op == token.Or {
2000 // name "|" ...
2001 f.Type = name
2002 return p.embeddedElem(f)
2003 }
2004
2005 f.Name = name
2006 }
2007
2008 if p.Tok == token.DotDotDot {
2009 // [name] "..." ...
2010 t := &DotsType{}
2011 t.pos = p.pos()
2012 p.Next()
2013 t.Elem = p.typeOrNil()
2014 if t.Elem == nil {
2015 f.Type = p.badExpr()
2016 p.syntaxError("... is missing type")
2017 } else {
2018 f.Type = t
2019 }
2020 return f
2021 }
2022
2023 if typeSetsOk && p.Tok == token.OperatorType && p.Op == token.Tilde {
2024 // [name] "~" ...
2025 f.Type = p.embeddedElem(nil).Type
2026 return f
2027 }
2028
2029 f.Type = p.typeOrNil()
2030 if typeSetsOk && p.Tok == token.OperatorType && p.Op == token.Or && f.Type != nil {
2031 // [name] type "|"
2032 f = p.embeddedElem(f)
2033 }
2034 if f.Name != nil || f.Type != nil {
2035 return f
2036 }
2037
2038 p.syntaxError("expected " | tokstring(follow))
2039 p.advance(token.Comma, follow)
2040 return nil
2041 }
2042
2043 // Parameters = "(" [ ParameterList [ "," ] ] ")" .
2044 // ParameterList = ParameterDecl { "," ParameterDecl } .
2045 // "(" or "[" has already been consumed.
2046 // If name != nil, it is the first name after "(" or "[".
2047 // If typ != nil, name must be != nil, and (name, typ) is the first field in the list.
2048 // In the result list, either all fields have a name, or no field has a name.
2049 func (p *Parser) paramList(name *Name, typ Expr, close token.Token, requireNames, dddok bool) (list []*Field) {
2050 if trace {
2051 defer p.trace("paramList")()
2052 }
2053
2054 // p.list won't invoke its function argument if we're at the end of the
2055 // parameter list. If we have a complete field, handle this case here.
2056 if name != nil && typ != nil && p.Tok == close {
2057 p.Next()
2058 par := &Field{}
2059 par.pos = name.pos
2060 par.Name = name
2061 par.Type = typ
2062 return []*Field{par}
2063 }
2064
2065 var named int32 // number of parameters that have an explicit name and type
2066 var typed int32 // number of parameters that have an explicit type
2067 end := p.list("parameter list", token.Comma, close, func() bool {
2068 var par *Field
2069 if typ != nil {
2070 if debug && name == nil {
2071 panic("initial type provided without name")
2072 }
2073 par = &Field{}
2074 par.pos = name.pos
2075 par.Name = name
2076 par.Type = typ
2077 } else {
2078 par = p.paramDeclOrNil(name, close)
2079 }
2080 name = nil // 1st name was consumed if present
2081 typ = nil // 1st type was consumed if present
2082 if par != nil {
2083 if debug && par.Name == nil && par.Type == nil {
2084 panic("parameter without name or type")
2085 }
2086 if par.Name != nil && par.Type != nil {
2087 named++
2088 }
2089 if par.Type != nil {
2090 typed++
2091 }
2092 list = append(list, par)
2093 }
2094 return false
2095 })
2096
2097 if len(list) == 0 {
2098 return
2099 }
2100
2101 // distribute parameter types (len(list) > 0)
2102 if named == 0 && !requireNames {
2103 // all unnamed and we're not in a type parameter list => found names are named types
2104 for _, par := range list {
2105 if typ := par.Name; typ != nil {
2106 par.Type = typ
2107 par.Name = nil
2108 }
2109 }
2110 } else if named != len(list) {
2111 // some named or we're in a type parameter list => all must be named
2112 var errPos token.Pos // left-most error position (or unknown)
2113 var typ Expr // current type (from right to left)
2114 for i := len(list) - 1; i >= 0; i-- {
2115 par := list[i]
2116 if par.Type != nil {
2117 typ = par.Type
2118 if par.Name == nil {
2119 errPos = StartPos(typ)
2120 par.Name = NewName(errPos, "_")
2121 }
2122 } else if typ != nil {
2123 par.Type = typ
2124 } else {
2125 // par.Type == nil && typ == nil => we only have a par.Name
2126 errPos = par.Name.Pos()
2127 t := p.badExpr()
2128 t.pos = errPos // correct position
2129 par.Type = t
2130 }
2131 }
2132 if errPos.IsKnown() {
2133 // Not all parameters are named because named != len(list).
2134 // If named == typed, there must be parameters that have no types.
2135 // They must be at the end of the parameter list, otherwise types
2136 // would have been filled in by the right-to-left sweep above and
2137 // there would be no error.
2138 // If requireNames is set, the parameter list is a type parameter
2139 // list.
2140 var msg string
2141 if named == typed {
2142 errPos = end // position error at closing token ) or ]
2143 if requireNames {
2144 msg = "missing type constraint"
2145 } else {
2146 msg = "missing parameter type"
2147 }
2148 } else {
2149 if requireNames {
2150 msg = "missing type parameter name"
2151 // go.dev/issue/60812
2152 if len(list) == 1 {
2153 msg = msg | " or invalid array length"
2154 }
2155 } else {
2156 msg = "missing parameter name"
2157 }
2158 }
2159 p.syntaxErrorAt(errPos, msg)
2160 }
2161 }
2162
2163 // check use of ... - DISABLED for gen1 debugging
2164
2165 return
2166 }
2167
2168 func (p *Parser) badExpr() (b *BadExpr) {
2169 b := &BadExpr{}
2170 b.pos = p.pos()
2171 return b
2172 }
2173
2174 // ----------------------------------------------------------------------------
2175 // Statements
2176
2177 // SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .
2178 func (p *Parser) simpleStmt(lhs Expr, keyword token.Token) (s SimpleStmt) {
2179 if trace {
2180 defer p.trace("simpleStmt")()
2181 }
2182
2183 if keyword == token.For && p.Tok == token.Range {
2184 // _Range expr
2185 if debug && lhs != nil {
2186 panic("invalid call of simpleStmt")
2187 }
2188 return p.newRangeClause(nil, false)
2189 }
2190
2191 if lhs == nil {
2192 lhs = p.exprList()
2193 }
2194
2195 if _, ok := lhs.(*ListExpr); !ok && p.Tok != token.Assign && p.Tok != token.Define {
2196 // expr
2197 pos := p.pos()
2198 switch p.Tok {
2199 case token.AssignOp:
2200 // lhs op= rhs
2201 op := p.Op
2202 p.Next()
2203 return p.newAssignStmt(pos, op, lhs, p.expr())
2204
2205 case token.IncOp:
2206 // lhs++ or lhs--
2207 op := p.Op
2208 p.Next()
2209 return p.newAssignStmt(pos, op, lhs, nil)
2210
2211 case token.Arrow:
2212 // lhs <- rhs
2213 s := &SendStmt{}
2214 s.pos = pos
2215 p.Next()
2216 s.Chan = lhs
2217 s.Value = p.expr()
2218 return s
2219
2220 default:
2221 // expr
2222 s := &ExprStmt{}
2223 s.pos = lhs.Pos()
2224 s.X = lhs
2225 return s
2226 }
2227 }
2228
2229 // expr_list
2230 switch p.Tok {
2231 case token.Assign, token.Define:
2232 pos := p.pos()
2233 var op token.Operator
2234 if p.Tok == token.Define {
2235 op = token.Def
2236 }
2237 p.Next()
2238
2239 if keyword == token.For && p.Tok == token.Range {
2240 // expr_list op= _Range expr
2241 return p.newRangeClause(lhs, op == token.Def)
2242 }
2243
2244 // expr_list op= expr_list
2245 rhs := p.exprList()
2246
2247 if x, ok := rhs.(*TypeSwitchGuard); ok && keyword == token.Switch && op == token.Def {
2248 if lhs, ok := lhs.(*Name); ok {
2249 // switch … lhs := rhs.(type)
2250 x.Lhs = lhs
2251 s := &ExprStmt{}
2252 s.pos = x.Pos()
2253 s.X = x
2254 return s
2255 }
2256 }
2257
2258 return p.newAssignStmt(pos, op, lhs, rhs)
2259
2260 default:
2261 p.syntaxError("expected := or = or comma")
2262 p.advance(token.Semi, token.Rbrace)
2263 // make the best of what we have
2264 if x, ok := lhs.(*ListExpr); ok {
2265 lhs = x.ElemList[0]
2266 }
2267 s := &ExprStmt{}
2268 s.pos = lhs.Pos()
2269 s.X = lhs
2270 return s
2271 }
2272 }
2273
2274 func (p *Parser) newRangeClause(lhs Expr, def bool) (r *RangeClause) {
2275 r := &RangeClause{}
2276 r.pos = p.pos()
2277 p.Next() // consume _Range
2278 r.Lhs = lhs
2279 r.Def = def
2280 r.X = p.expr()
2281 return r
2282 }
2283
2284 func (p *Parser) newAssignStmt(pos token.Pos, op token.Operator, lhs, rhs Expr) (a *AssignStmt) {
2285 a := &AssignStmt{}
2286 a.pos = pos
2287 a.Op = op
2288 a.Lhs = lhs
2289 a.Rhs = rhs
2290 return a
2291 }
2292
2293 func (p *Parser) labeledStmtOrNil(label *Name) (s Stmt) {
2294 if trace {
2295 defer p.trace("labeledStmt")()
2296 }
2297
2298 s := &LabeledStmt{}
2299 s.pos = p.pos()
2300 s.Label = label
2301
2302 p.want(token.Colon)
2303
2304 if p.Tok == token.Rbrace {
2305 // We expect a statement (incl. an empty statement), which must be
2306 // terminated by a semicolon. Because semicolons may be omitted before
2307 // an _Rbrace, seeing an _Rbrace implies an empty statement.
2308 e := &EmptyStmt{}
2309 e.pos = p.pos()
2310 s.Stmt = e
2311 return s
2312 }
2313
2314 s.Stmt = p.stmtOrNil()
2315 if s.Stmt != nil {
2316 return s
2317 }
2318
2319 // report error at line of ':' token
2320 p.syntaxErrorAt(s.pos, "missing statement after label")
2321 // we are already at the end of the labeled statement - no need to advance
2322 return nil // avoids follow-on errors (see e.g., fixedbugs/bug274.go)
2323 }
2324
2325 // context must be a non-empty string unless we know that p.tok == _Lbrace.
2326 func (p *Parser) blockStmt(context string) (b *BlockStmt) {
2327 if trace {
2328 defer p.trace("blockStmt")()
2329 }
2330
2331 s := &BlockStmt{}
2332 s.pos = p.pos()
2333
2334 // people coming from C may forget that braces are mandatory in Go
2335 if !p.got(token.Lbrace) {
2336 p.syntaxError("expected { after " | context)
2337 p.advance(token.NameType, token.Rbrace)
2338 s.Rbrace = p.pos() // in case we found "}"
2339 if p.got(token.Rbrace) {
2340 return s
2341 }
2342 }
2343
2344 s.List = p.stmtList()
2345 s.Rbrace = p.pos()
2346 p.want(token.Rbrace)
2347
2348 return s
2349 }
2350
2351 func (p *Parser) declStmt(f func(*Group) Decl) (d *DeclStmt) {
2352 if trace {
2353 defer p.trace("declStmt")()
2354 }
2355
2356 s := &DeclStmt{}
2357 s.pos = p.pos()
2358
2359 p.Next() // _Const, _Type, or _Var
2360 s.DeclList = p.appendGroup(nil, f)
2361
2362 return s
2363 }
2364
2365 func (p *Parser) forStmt() (s Stmt) {
2366 if trace {
2367 defer p.trace("forStmt")()
2368 }
2369
2370 s := &ForStmt{}
2371 s.pos = p.pos()
2372
2373 s.Init, s.Cond, s.Post = p.header(token.For)
2374 s.Body = p.blockStmt("for clause")
2375
2376 return s
2377 }
2378
2379 func (p *Parser) header(keyword token.Token) (init SimpleStmt, cond Expr, post SimpleStmt) {
2380 p.want(keyword)
2381
2382 if p.Tok == token.Lbrace {
2383 if keyword == token.If {
2384 p.syntaxError("missing condition in if statement")
2385 cond = p.badExpr()
2386 }
2387 return
2388 }
2389 // p.tok != _Lbrace
2390
2391 outer := p.Xnest
2392 p.Xnest = -1
2393
2394 if p.Tok != token.Semi {
2395 // accept potential varDecl but complain
2396 if p.got(token.Var) {
2397 p.syntaxError("var declaration not allowed in " | keyword.String() | " initializer")
2398 }
2399 init = p.simpleStmt(nil, keyword)
2400 // If we have a range clause, we are done (can only happen for keyword == _For).
2401 if _, ok := init.(*RangeClause); ok {
2402 p.Xnest = outer
2403 return
2404 }
2405 }
2406
2407 var condStmt SimpleStmt
2408 var semi struct {
2409 pos token.Pos
2410 lit string // valid if pos.IsKnown()
2411 }
2412 if p.Tok != token.Lbrace {
2413 if p.Tok == token.Semi {
2414 semi.pos = p.pos()
2415 semi.lit = p.Lit
2416 p.Next()
2417 } else {
2418 // asking for a '{' rather than a ';' here leads to a better error message
2419 p.want(token.Lbrace)
2420 if p.Tok != token.Lbrace {
2421 p.advance(token.Lbrace, token.Rbrace) // for better synchronization (e.g., go.dev/issue/22581)
2422 }
2423 }
2424 if keyword == token.For {
2425 if p.Tok != token.Semi {
2426 if p.Tok == token.Lbrace {
2427 p.syntaxError("expected for loop condition")
2428 goto done
2429 }
2430 condStmt = p.simpleStmt(nil, 0 /* range not permitted */)
2431 }
2432 p.want(token.Semi)
2433 if p.Tok != token.Lbrace {
2434 post = p.simpleStmt(nil, 0 /* range not permitted */)
2435 if a, _ := post.(*AssignStmt); a != nil && a.Op == token.Def {
2436 p.syntaxErrorAt(a.Pos(), "cannot declare in post statement of for loop")
2437 }
2438 }
2439 } else if p.Tok != token.Lbrace {
2440 condStmt = p.simpleStmt(nil, keyword)
2441 }
2442 } else {
2443 condStmt = init
2444 init = nil
2445 }
2446
2447 done:
2448 // unpack condStmt
2449 switch s := condStmt.(type) {
2450 case nil:
2451 if keyword == token.If && semi.pos.IsKnown() {
2452 if semi.lit != "semicolon" {
2453 p.syntaxErrorAt(semi.pos, "unexpected " | semi.lit | ", expected { after if clause")
2454 } else {
2455 p.syntaxErrorAt(semi.pos, "missing condition in if statement")
2456 }
2457 b := &BadExpr{}
2458 b.pos = semi.pos
2459 cond = b
2460 }
2461 case *ExprStmt:
2462 cond = s.X
2463 default:
2464 // A common syntax error is to write '=' instead of '==',
2465 // which turns an expression into an assignment. Provide
2466 // a more explicit error message in that case to prevent
2467 // further confusion.
2468 var str string
2469 if as, ok := s.(*AssignStmt); ok && as.Op == 0 {
2470 // Emphasize complex Lhs and Rhs of assignment with parentheses to highlight '='.
2471 str = "assignment " | emphasize(as.Lhs) | " = " | emphasize(as.Rhs)
2472 } else {
2473 str = String(s)
2474 }
2475 p.syntaxErrorAt(s.Pos(), "cannot use " | str | " as value")
2476 }
2477
2478 p.Xnest = outer
2479 return
2480 }
2481
2482 // emphasize returns a string representation of x, with (top-level)
2483 // binary expressions emphasized by enclosing them in parentheses.
2484 func emphasize(x Expr) (s string) {
2485 s := String(x)
2486 if op, _ := x.(*Operation); op != nil && op.Y != nil {
2487 // binary expression
2488 return "(" | s | ")"
2489 }
2490 return s
2491 }
2492
2493 func (p *Parser) ifStmt() (i *IfStmt) {
2494 if trace {
2495 defer p.trace("ifStmt")()
2496 }
2497
2498 s := &IfStmt{}
2499 s.pos = p.pos()
2500
2501 s.Init, s.Cond, _ = p.header(token.If)
2502 s.Then = p.blockStmt("if clause")
2503
2504 if p.got(token.Else) {
2505 switch p.Tok {
2506 case token.If:
2507 s.Else = p.ifStmt()
2508 case token.Lbrace:
2509 s.Else = p.blockStmt("")
2510 default:
2511 p.syntaxError("else must be followed by if or statement block")
2512 p.advance(token.NameType, token.Rbrace)
2513 }
2514 }
2515
2516 return s
2517 }
2518
2519 func (p *Parser) switchStmt() (s *SwitchStmt) {
2520 if trace {
2521 defer p.trace("switchStmt")()
2522 }
2523
2524 s := &SwitchStmt{}
2525 s.pos = p.pos()
2526
2527 s.Init, s.Tag, _ = p.header(token.Switch)
2528
2529 if !p.got(token.Lbrace) {
2530 p.syntaxError("missing { after switch clause")
2531 p.advance(token.Case, token.Default, token.Rbrace)
2532 }
2533 for p.Tok != token.EOF && p.Tok != token.Rbrace {
2534 s.Body = append(s.Body, p.caseClause())
2535 }
2536 s.Rbrace = p.pos()
2537 p.want(token.Rbrace)
2538
2539 return s
2540 }
2541
2542 func (p *Parser) selectStmt() (s *SelectStmt) {
2543 if trace {
2544 defer p.trace("selectStmt")()
2545 }
2546
2547 s := &SelectStmt{}
2548 s.pos = p.pos()
2549
2550 p.want(token.Select)
2551 if !p.got(token.Lbrace) {
2552 p.syntaxError("missing { after select clause")
2553 p.advance(token.Case, token.Default, token.Rbrace)
2554 }
2555 for p.Tok != token.EOF && p.Tok != token.Rbrace {
2556 s.Body = append(s.Body, p.commClause())
2557 }
2558 s.Rbrace = p.pos()
2559 p.want(token.Rbrace)
2560
2561 return s
2562 }
2563
2564 func (p *Parser) caseClause() (c *CaseClause) {
2565 if trace {
2566 defer p.trace("caseClause")()
2567 }
2568
2569 c := &CaseClause{}
2570 c.pos = p.pos()
2571
2572 switch p.Tok {
2573 case token.Case:
2574 p.Next()
2575 c.Cases = p.exprList()
2576
2577 case token.Default:
2578 p.Next()
2579
2580 default:
2581 p.syntaxError("expected case or default or }")
2582 p.advance(token.Colon, token.Case, token.Default, token.Rbrace)
2583 }
2584
2585 c.Colon = p.pos()
2586 p.want(token.Colon)
2587 c.Body = p.stmtList()
2588
2589 return c
2590 }
2591
2592 func (p *Parser) commClause() (c *CommClause) {
2593 if trace {
2594 defer p.trace("commClause")()
2595 }
2596
2597 c := &CommClause{}
2598 c.pos = p.pos()
2599
2600 switch p.Tok {
2601 case token.Case:
2602 p.Next()
2603 c.Comm = p.simpleStmt(nil, 0)
2604
2605 // The syntax restricts the possible simple statements here to:
2606 //
2607 // lhs <- x (send statement)
2608 // <-x
2609 // lhs = <-x
2610 // lhs := <-x
2611 //
2612 // All these (and more) are recognized by simpleStmt and invalid
2613 // syntax trees are flagged later, during type checking.
2614
2615 case token.Default:
2616 p.Next()
2617
2618 default:
2619 p.syntaxError("expected case or default or }")
2620 p.advance(token.Colon, token.Case, token.Default, token.Rbrace)
2621 }
2622
2623 c.Colon = p.pos()
2624 p.want(token.Colon)
2625 c.Body = p.stmtList()
2626
2627 return c
2628 }
2629
2630 // stmtOrNil parses a statement if one is present, or else returns nil.
2631 //
2632 // Statement =
2633 // Declaration | LabeledStmt | SimpleStmt |
2634 // GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt |
2635 // FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt |
2636 // DeferStmt .
2637 func (p *Parser) stmtOrNil() (s Stmt) {
2638 if trace {
2639 defer p.trace("stmt " | p.Tok.String())()
2640 }
2641
2642 // Most statements (assignments) start with an identifier;
2643 // look for it first before doing anything more expensive.
2644 if p.Tok == token.NameType {
2645 p.clearPragma()
2646 lhs := p.exprList()
2647 if label, ok := lhs.(*Name); ok && p.Tok == token.Colon {
2648 return p.labeledStmtOrNil(label)
2649 }
2650 return p.simpleStmt(lhs, 0)
2651 }
2652
2653 switch p.Tok {
2654 case token.Var:
2655 return p.declStmt(p.varDecl)
2656
2657 case token.Const:
2658 return p.declStmt(p.constDecl)
2659
2660 case token.TypeType:
2661 return p.declStmt(p.typeDecl)
2662 }
2663
2664 p.clearPragma()
2665
2666 switch p.Tok {
2667 case token.Lbrace:
2668 return p.blockStmt("")
2669
2670 case token.OperatorType, token.Star:
2671 switch p.Op {
2672 case token.Add, token.Sub, token.Mul, token.And, token.Xor, token.Not:
2673 return p.simpleStmt(nil, 0) // unary operators
2674 }
2675
2676 case token.Literal, token.Func, token.Lparen, // operands
2677 token.Lbrack, token.Struct, token.Map, token.Chan, token.Interface, // composite types
2678 token.Arrow: // receive operator
2679 return p.simpleStmt(nil, 0)
2680
2681 case token.For:
2682 return p.forStmt()
2683
2684 case token.Switch:
2685 return p.switchStmt()
2686
2687 case token.Select:
2688 return p.selectStmt()
2689
2690 case token.If:
2691 return p.ifStmt()
2692
2693 case token.Fallthrough:
2694 s := &BranchStmt{}
2695 s.pos = p.pos()
2696 p.Next()
2697 s.Tok = token.Fallthrough
2698 return s
2699
2700 case token.Break, token.Continue:
2701 s := &BranchStmt{}
2702 s.pos = p.pos()
2703 s.Tok = p.Tok
2704 p.Next()
2705 if p.Tok == token.NameType {
2706 s.Label = p.name()
2707 }
2708 return s
2709
2710 case token.Go, token.Defer:
2711 return p.callStmt()
2712
2713 case token.Goto:
2714 s := &BranchStmt{}
2715 s.pos = p.pos()
2716 s.Tok = token.Goto
2717 p.Next()
2718 s.Label = p.name()
2719 return s
2720
2721 case token.Return:
2722 s := &ReturnStmt{}
2723 s.pos = p.pos()
2724 p.Next()
2725 if p.Tok != token.Semi && p.Tok != token.Rbrace {
2726 s.Results = p.exprList()
2727 }
2728 return s
2729
2730 case token.Semi:
2731 s := &EmptyStmt{}
2732 s.pos = p.pos()
2733 return s
2734 }
2735
2736 return nil
2737 }
2738
2739 // StatementList = { Statement ";" } .
2740 func (p *Parser) stmtList() (l []Stmt) {
2741 if trace {
2742 defer p.trace("stmtList")()
2743 }
2744
2745 for p.Tok != token.EOF && p.Tok != token.Rbrace && p.Tok != token.Case && p.Tok != token.Default {
2746 s := p.stmtOrNil()
2747 p.clearPragma()
2748 if s == nil {
2749 break
2750 }
2751 l = append(l, s)
2752 // ";" is optional before "}"
2753 if !p.got(token.Semi) && p.Tok != token.Rbrace {
2754 p.syntaxError("at end of statement")
2755 p.advance(token.Semi, token.Rbrace, token.Case, token.Default)
2756 p.got(token.Semi) // avoid spurious empty statement
2757 }
2758 }
2759 return
2760 }
2761
2762 // argList parses a possibly empty, comma-separated list of arguments,
2763 // optionally followed by a comma (if not empty), and closed by ")".
2764 // The last argument may be followed by "...".
2765 //
2766 // argList = [ arg { "," arg } [ "..." ] [ "," ] ] ")" .
2767 func (p *Parser) argList() (list []Expr, hasDots bool) {
2768 if trace {
2769 defer p.trace("argList")()
2770 }
2771
2772 p.Xnest++
2773 p.list("argument list", token.Comma, token.Rparen, func() bool {
2774 list = append(list, p.expr())
2775 hasDots = p.got(token.DotDotDot)
2776 return hasDots
2777 })
2778 p.Xnest--
2779
2780 return
2781 }
2782
2783 // ----------------------------------------------------------------------------
2784 // Common productions
2785
2786 func (p *Parser) name() (n *Name) {
2787 // no tracing to avoid overly verbose output
2788
2789 if p.Tok == token.NameType {
2790 n := NewName(p.pos(), p.Lit)
2791 p.Next()
2792 return n
2793 }
2794
2795 n := NewName(p.pos(), "_")
2796 p.syntaxError("expected name")
2797 p.advance()
2798 return n
2799 }
2800
2801 // IdentifierList = identifier { "," identifier } .
2802 // The first name must be provided.
2803 func (p *Parser) nameList(First *Name) (ns []*Name) {
2804 if trace {
2805 defer p.trace("nameList")()
2806 }
2807
2808 if debug && First == nil {
2809 panic("first name not provided")
2810 }
2811
2812 l := []*Name{First}
2813 for p.got(token.Comma) {
2814 l = append(l, p.name())
2815 }
2816
2817 return l
2818 }
2819
2820 // The first name may be provided, or nil.
2821 func (p *Parser) qualifiedName(name *Name) (e Expr) {
2822 if trace {
2823 defer p.trace("qualifiedName")()
2824 }
2825
2826 var x Expr
2827 switch {
2828 case name != nil:
2829 x = name
2830 case p.Tok == token.NameType:
2831 x = p.name()
2832 default:
2833 x = NewName(p.pos(), "_")
2834 p.syntaxError("expected name")
2835 p.advance(token.Dot, token.Semi, token.Rbrace)
2836 }
2837
2838 if p.Tok == token.Dot {
2839 s := &SelectorExpr{}
2840 s.pos = p.pos()
2841 p.Next()
2842 s.X = x
2843 s.Sel = p.name()
2844 x = s
2845 }
2846
2847 if p.Tok == token.Lbrack {
2848 x = p.typeInstance(x)
2849 }
2850
2851 return x
2852 }
2853
2854 // ExpressionList = Expression { "," Expression } .
2855 func (p *Parser) exprList() (e Expr) {
2856 if trace {
2857 defer p.trace("exprList")()
2858 }
2859
2860 x := p.expr()
2861 if p.got(token.Comma) {
2862 list := []Expr{x, p.expr()}
2863 for p.got(token.Comma) {
2864 list = append(list, p.expr())
2865 }
2866 t := &ListExpr{}
2867 t.pos = x.Pos()
2868 t.ElemList = list
2869 x = t
2870 }
2871 return x
2872 }
2873
2874 // typeList parses a non-empty, comma-separated list of types,
2875 // optionally followed by a comma. If strict is set to false,
2876 // the first element may also be a (non-type) expression.
2877 // If there is more than one argument, the result is a *ListExpr.
2878 // The comma result indicates whether there was a (separating or
2879 // trailing) comma.
2880 //
2881 // typeList = arg { "," arg } [ "," ] .
2882 func (p *Parser) typeList(strict bool) (x Expr, comma bool) {
2883 if trace {
2884 defer p.trace("typeList")()
2885 }
2886
2887 p.Xnest++
2888 if strict {
2889 x = p.type_()
2890 } else {
2891 x = p.expr()
2892 }
2893 if p.got(token.Comma) {
2894 comma = true
2895 if t := p.typeOrNil(); t != nil {
2896 list := []Expr{x, t}
2897 for p.got(token.Comma) {
2898 if t = p.typeOrNil(); t == nil {
2899 break
2900 }
2901 list = append(list, t)
2902 }
2903 l := &ListExpr{}
2904 l.pos = x.Pos() // == list[0].Pos()
2905 l.ElemList = list
2906 x = l
2907 }
2908 }
2909 p.Xnest--
2910 return
2911 }
2912
2913 // Unparen returns e with any enclosing parentheses stripped.
2914 func Unparen(x Expr) (e Expr) {
2915 for {
2916 p, ok := x.(*ParenExpr)
2917 if !ok {
2918 break
2919 }
2920 x = p.X
2921 }
2922 return x
2923 }
2924
2925 // UnpackListExpr unpacks a *ListExpr into a []Expr.
2926 func UnpackListExpr(x Expr) (es []Expr) {
2927 switch x := x.(type) {
2928 case nil:
2929 return nil
2930 case *ListExpr:
2931 return x.ElemList
2932 default:
2933 return []Expr{x}
2934 }
2935 }
2936