summaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/syntax/parser.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/syntax/parser.go')
-rw-r--r--src/cmd/compile/internal/syntax/parser.go60
1 files changed, 22 insertions, 38 deletions
diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go
index 8232be64ff..39532689e2 100644
--- a/src/cmd/compile/internal/syntax/parser.go
+++ b/src/cmd/compile/internal/syntax/parser.go
@@ -480,11 +480,8 @@ func (p *parser) funcDecl() *FuncDecl {
f.Name = p.name()
f.Type = p.funcType()
- if lbrace := p.pos(); p.got(_Lbrace) {
- f.Lbrace = lbrace
- f.Body = p.funcBody()
- f.Rbrace = p.pos()
- p.want(_Rbrace)
+ if p.tok == _Lbrace {
+ f.Body = p.blockStmt("")
}
f.Pragma = p.pragma
@@ -704,16 +701,13 @@ func (p *parser) operand(keep_parens bool) Expr {
pos := p.pos()
p.next()
t := p.funcType()
- if lbrace := p.pos(); p.got(_Lbrace) {
+ if p.tok == _Lbrace {
p.xnest++
f := new(FuncLit)
f.pos = pos
- f.Lbrace = lbrace
f.Type = t
- f.Body = p.funcBody()
- f.Rbrace = p.pos()
- p.want(_Rbrace)
+ f.Body = p.blockStmt("")
p.xnest--
return f
@@ -902,7 +896,6 @@ func (p *parser) complitexpr() *CompositeLit {
x := new(CompositeLit)
x.pos = p.pos()
- x.Lbrace = p.pos()
p.want(_Lbrace)
p.xnest++
@@ -1619,15 +1612,21 @@ func (p *parser) labeledStmt(label *Name) Stmt {
return s
}
-func (p *parser) blockStmt() *BlockStmt {
+func (p *parser) blockStmt(context string) *BlockStmt {
if trace {
defer p.trace("blockStmt")()
}
s := new(BlockStmt)
s.pos = p.pos()
- p.want(_Lbrace)
- s.Body = p.stmtList()
+
+ if !p.got(_Lbrace) {
+ p.syntax_error("expecting { after " + context)
+ p.advance(_Name, _Rbrace)
+ // TODO(gri) may be better to return here than to continue (#19663)
+ }
+
+ s.List = p.stmtList()
s.Rbrace = p.pos()
p.want(_Rbrace)
@@ -1657,29 +1656,14 @@ func (p *parser) forStmt() Stmt {
s.pos = p.pos()
s.Init, s.Cond, s.Post = p.header(_For)
- s.Body, s.Lbrace, s.Rbrace = p.stmtBody("for clause")
+ s.Body = p.blockStmt("for clause")
return s
}
-// stmtBody parses if and for statement bodies.
-func (p *parser) stmtBody(context string) (body []Stmt, lbrace, rbrace src.Pos) {
- if trace {
- defer p.trace("stmtBody")()
- }
-
- lbrace = p.pos()
- if !p.got(_Lbrace) {
- p.syntax_error("expecting { after " + context)
- p.advance(_Name, _Rbrace)
- }
- body = p.stmtList()
- rbrace = p.pos()
- p.want(_Rbrace)
-
- return
-}
-
+// TODO(gri) This function is now so heavily influenced by the keyword that
+// it may not make sense anymore to combine all three cases. It
+// may be simpler to just split it up for each statement kind.
func (p *parser) header(keyword token) (init SimpleStmt, cond Expr, post SimpleStmt) {
p.want(keyword)
@@ -1769,14 +1753,14 @@ func (p *parser) ifStmt() *IfStmt {
s.pos = p.pos()
s.Init, s.Cond, _ = p.header(_If)
- s.Then, s.Lbrace, s.Rbrace = p.stmtBody("if clause")
+ s.Then = p.blockStmt("if clause")
if p.got(_Else) {
switch p.tok {
case _If:
s.Else = p.ifStmt()
case _Lbrace:
- s.Else = p.blockStmt()
+ s.Else = p.blockStmt("")
default:
p.syntax_error("else must be followed by if or statement block")
p.advance(_Name, _Rbrace)
@@ -1849,7 +1833,7 @@ func (p *parser) caseClause() *CaseClause {
default:
p.syntax_error("expecting case or default or }")
- p.advance(_Case, _Default, _Rbrace)
+ p.advance(_Colon, _Case, _Default, _Rbrace)
}
c.Colon = p.pos()
@@ -1889,7 +1873,7 @@ func (p *parser) commClause() *CommClause {
default:
p.syntax_error("expecting case or default or }")
- p.advance(_Case, _Default, _Rbrace)
+ p.advance(_Colon, _Case, _Default, _Rbrace)
}
c.Colon = p.pos()
@@ -1926,7 +1910,7 @@ func (p *parser) stmt() Stmt {
switch p.tok {
case _Lbrace:
- return p.blockStmt()
+ return p.blockStmt("")
case _Var:
return p.declStmt(p.varDecl)