Commit 783f166e authored by Robert Griesemer's avatar Robert Griesemer

cmd/compile/internal/syntax: remove need for missing_statement (fixed TODO)

Now that we have consistent use of xOrNil parse methods, we don't
need a special missing_statement singleton to distinguish between
missing actually statements and other errors (which have returned
nil before).

For #19663.

Change-Id: I8364f1441bdf8dd966bcd6d8219b2a42d6b88abd
Reviewed-on: https://go-review.googlesource.com/38656
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent d1f5e5f4
...@@ -1494,8 +1494,6 @@ func (p *parser) bad() *BadExpr { ...@@ -1494,8 +1494,6 @@ func (p *parser) bad() *BadExpr {
var ImplicitOne = &BasicLit{Value: "1"} var ImplicitOne = &BasicLit{Value: "1"}
// SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl . // SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .
//
// simpleStmt may return missing_stmt if labelOk is set.
func (p *parser) simpleStmt(lhs Expr, rangeOk bool) SimpleStmt { func (p *parser) simpleStmt(lhs Expr, rangeOk bool) SimpleStmt {
if trace { if trace {
defer p.trace("simpleStmt")() defer p.trace("simpleStmt")()
...@@ -1627,7 +1625,7 @@ func (p *parser) newAssignStmt(pos src.Pos, op Operator, lhs, rhs Expr) *AssignS ...@@ -1627,7 +1625,7 @@ func (p *parser) newAssignStmt(pos src.Pos, op Operator, lhs, rhs Expr) *AssignS
return a return a
} }
func (p *parser) labeledStmt(label *Name) Stmt { func (p *parser) labeledStmtOrNil(label *Name) Stmt {
if trace { if trace {
defer p.trace("labeledStmt")() defer p.trace("labeledStmt")()
} }
...@@ -1638,17 +1636,25 @@ func (p *parser) labeledStmt(label *Name) Stmt { ...@@ -1638,17 +1636,25 @@ func (p *parser) labeledStmt(label *Name) Stmt {
p.want(_Colon) p.want(_Colon)
if p.tok != _Rbrace && p.tok != _EOF { if p.tok == _Rbrace {
s.Stmt = p.stmt() // We expect a statement (incl. an empty statement), which must be
if s.Stmt == missing_stmt { // terminated by a semicolon. Because semicolons may be omitted before
// report error at line of ':' token // an _Rbrace, seeing an _Rbrace implies an empty statement.
p.syntax_error_at(label.Pos(), "missing statement after label") e := new(EmptyStmt)
// we are already at the end of the labeled statement - no need to advance e.pos = p.pos()
return missing_stmt s.Stmt = e
} return s
} }
return s s.Stmt = p.stmtOrNil()
if s.Stmt != nil {
return s
}
// report error at line of ':' token
p.syntax_error_at(s.pos, "missing statement after label")
// we are already at the end of the labeled statement - no need to advance
return nil // avoids follow-on errors (see e.g., fixedbugs/bug274.go)
} }
func (p *parser) blockStmt(context string) *BlockStmt { func (p *parser) blockStmt(context string) *BlockStmt {
...@@ -1922,17 +1928,12 @@ func (p *parser) commClause() *CommClause { ...@@ -1922,17 +1928,12 @@ func (p *parser) commClause() *CommClause {
return c return c
} }
// TODO(gri) find a better solution
var missing_stmt Stmt = new(EmptyStmt) // = nod(OXXX, nil, nil)
// Statement = // Statement =
// Declaration | LabeledStmt | SimpleStmt | // Declaration | LabeledStmt | SimpleStmt |
// GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt | // GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt |
// FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt | // FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt |
// DeferStmt . // DeferStmt .
// func (p *parser) stmtOrNil() Stmt {
// stmt may return missing_stmt.
func (p *parser) stmt() Stmt {
if trace { if trace {
defer p.trace("stmt " + p.tok.String())() defer p.trace("stmt " + p.tok.String())()
} }
...@@ -1942,7 +1943,7 @@ func (p *parser) stmt() Stmt { ...@@ -1942,7 +1943,7 @@ func (p *parser) stmt() Stmt {
if p.tok == _Name { if p.tok == _Name {
lhs := p.exprList() lhs := p.exprList()
if label, ok := lhs.(*Name); ok && p.tok == _Colon { if label, ok := lhs.(*Name); ok && p.tok == _Colon {
return p.labeledStmt(label) return p.labeledStmtOrNil(label)
} }
return p.simpleStmt(lhs, false) return p.simpleStmt(lhs, false)
} }
...@@ -2026,7 +2027,7 @@ func (p *parser) stmt() Stmt { ...@@ -2026,7 +2027,7 @@ func (p *parser) stmt() Stmt {
return s return s
} }
return missing_stmt return nil
} }
// StatementList = { Statement ";" } . // StatementList = { Statement ";" } .
...@@ -2036,8 +2037,8 @@ func (p *parser) stmtList() (l []Stmt) { ...@@ -2036,8 +2037,8 @@ func (p *parser) stmtList() (l []Stmt) {
} }
for p.tok != _EOF && p.tok != _Rbrace && p.tok != _Case && p.tok != _Default { for p.tok != _EOF && p.tok != _Rbrace && p.tok != _Case && p.tok != _Default {
s := p.stmt() s := p.stmtOrNil()
if s == missing_stmt { if s == nil {
break break
} }
l = append(l, s) l = append(l, s)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment