Commit 5408d799 authored by Robert Griesemer's avatar Robert Griesemer

go/parser: remove newly introduced TODO (cleanup)

R=go1.11

No semantic change.

For #23434.

Change-Id: Iafdb062b0ebe6cd6e51f9a98b62b1d10f1bacc5c
Reviewed-on: https://go-review.googlesource.com/87899Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent fc31d4e2
...@@ -48,11 +48,11 @@ type parser struct { ...@@ -48,11 +48,11 @@ type parser struct {
lit string // token literal lit string // token literal
// Error recovery // Error recovery
// (used to limit the number of calls to syncXXX functions // (used to limit the number of calls to parser.advance
// w/o making scanning progress - avoids potential endless // w/o making scanning progress - avoids potential endless
// loops across multiple parser functions during error recovery) // loops across multiple parser functions during error recovery)
syncPos token.Pos // last synchronization position syncPos token.Pos // last synchronization position
syncCnt int // number of calls to syncXXX without progress syncCnt int // number of parser.advance calls without progress
// Non-syntactic parser control // Non-syntactic parser control
exprLev int // < 0: in control clause, >= 0: in expression exprLev int // < 0: in control clause, >= 0: in expression
...@@ -419,7 +419,7 @@ func (p *parser) expectSemi() { ...@@ -419,7 +419,7 @@ func (p *parser) expectSemi() {
p.next() p.next()
default: default:
p.errorExpected(p.pos, "';'") p.errorExpected(p.pos, "';'")
p.syncStmt() p.advance(stmtStart)
} }
} }
} }
...@@ -445,23 +445,16 @@ func assert(cond bool, msg string) { ...@@ -445,23 +445,16 @@ func assert(cond bool, msg string) {
} }
} }
// TODO(gri) The syncX methods below all use the same pattern. Factor. // advance consumes tokens until the current token p.tok
// is in the 'to' set, or token.EOF. For error recovery.
// syncStmt advances to the next statement. func (p *parser) advance(to map[token.Token]bool) {
// Used for synchronization after an error. for ; p.tok != token.EOF; p.next() {
// if to[p.tok] {
func (p *parser) syncStmt() {
for {
switch p.tok {
case token.BREAK, token.CONST, token.CONTINUE, token.DEFER,
token.FALLTHROUGH, token.FOR, token.GO, token.GOTO,
token.IF, token.RETURN, token.SELECT, token.SWITCH,
token.TYPE, token.VAR:
// Return only if parser made some progress since last // Return only if parser made some progress since last
// sync or if it has not reached 10 sync calls without // sync or if it has not reached 10 advance calls without
// progress. Otherwise consume at least one token to // progress. Otherwise consume at least one token to
// avoid an endless parser loop (it is possible that // avoid an endless parser loop (it is possible that
// both parseOperand and parseStmt call syncStmt and // both parseOperand and parseStmt call advance and
// correctly do not advance, thus the need for the // correctly do not advance, thus the need for the
// invocation limit p.syncCnt). // invocation limit p.syncCnt).
if p.pos == p.syncPos && p.syncCnt < 10 { if p.pos == p.syncPos && p.syncCnt < 10 {
...@@ -478,59 +471,40 @@ func (p *parser) syncStmt() { ...@@ -478,59 +471,40 @@ func (p *parser) syncStmt() {
// leads to skipping of possibly correct code if a // leads to skipping of possibly correct code if a
// previous error is present, and thus is preferred // previous error is present, and thus is preferred
// over a non-terminating parse. // over a non-terminating parse.
case token.EOF:
return
} }
p.next()
} }
} }
// syncDecl advances to the next declaration. var stmtStart = map[token.Token]bool{
// Used for synchronization after an error. token.BREAK: true,
// token.CONST: true,
func (p *parser) syncDecl() { token.CONTINUE: true,
for { token.DEFER: true,
switch p.tok { token.FALLTHROUGH: true,
case token.CONST, token.TYPE, token.VAR: token.FOR: true,
// see comments in syncStmt token.GO: true,
if p.pos == p.syncPos && p.syncCnt < 10 { token.GOTO: true,
p.syncCnt++ token.IF: true,
return token.RETURN: true,
} token.SELECT: true,
if p.pos > p.syncPos { token.SWITCH: true,
p.syncPos = p.pos token.TYPE: true,
p.syncCnt = 0 token.VAR: true,
return
}
case token.EOF:
return
}
p.next()
}
} }
// syncExprEnd advances to the likely end of an expression. var declStart = map[token.Token]bool{
// Used for synchronization after an error. token.CONST: true,
// token.TYPE: true,
func (p *parser) syncExprEnd() { token.VAR: true,
for { }
switch p.tok {
case token.COMMA, token.COLON, token.SEMICOLON, token.RPAREN, token.RBRACK, token.RBRACE: var exprEnd = map[token.Token]bool{
// see comments in syncStmt token.COMMA: true,
if p.pos == p.syncPos && p.syncCnt < 10 { token.COLON: true,
p.syncCnt++ token.SEMICOLON: true,
return token.RPAREN: true,
} token.RBRACK: true,
if p.pos > p.syncPos { token.RBRACE: true,
p.syncPos = p.pos
p.syncCnt = 0
return
}
case token.EOF:
return
}
p.next()
}
} }
// safePos returns a valid file position for a given position: If pos // safePos returns a valid file position for a given position: If pos
...@@ -649,7 +623,7 @@ func (p *parser) parseType() ast.Expr { ...@@ -649,7 +623,7 @@ func (p *parser) parseType() ast.Expr {
if typ == nil { if typ == nil {
pos := p.pos pos := p.pos
p.errorExpected(pos, "type") p.errorExpected(pos, "type")
p.syncExprEnd() p.advance(exprEnd)
return &ast.BadExpr{From: pos, To: p.pos} return &ast.BadExpr{From: pos, To: p.pos}
} }
...@@ -1192,7 +1166,7 @@ func (p *parser) parseOperand(lhs bool) ast.Expr { ...@@ -1192,7 +1166,7 @@ func (p *parser) parseOperand(lhs bool) ast.Expr {
// we have an error // we have an error
pos := p.pos pos := p.pos
p.errorExpected(pos, "operand") p.errorExpected(pos, "operand")
p.syncStmt() p.advance(stmtStart)
return &ast.BadExpr{From: pos, To: p.pos} return &ast.BadExpr{From: pos, To: p.pos}
} }
...@@ -2228,7 +2202,7 @@ func (p *parser) parseStmt() (s ast.Stmt) { ...@@ -2228,7 +2202,7 @@ func (p *parser) parseStmt() (s ast.Stmt) {
switch p.tok { switch p.tok {
case token.CONST, token.TYPE, token.VAR: case token.CONST, token.TYPE, token.VAR:
s = &ast.DeclStmt{Decl: p.parseDecl((*parser).syncStmt)} s = &ast.DeclStmt{Decl: p.parseDecl(stmtStart)}
case case
// tokens that may start an expression // tokens that may start an expression
token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING, token.FUNC, token.LPAREN, // operands token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING, token.FUNC, token.LPAREN, // operands
...@@ -2273,7 +2247,7 @@ func (p *parser) parseStmt() (s ast.Stmt) { ...@@ -2273,7 +2247,7 @@ func (p *parser) parseStmt() (s ast.Stmt) {
// no statement found // no statement found
pos := p.pos pos := p.pos
p.errorExpected(pos, "statement") p.errorExpected(pos, "statement")
p.syncStmt() p.advance(stmtStart)
s = &ast.BadStmt{From: pos, To: p.pos} s = &ast.BadStmt{From: pos, To: p.pos}
} }
...@@ -2487,7 +2461,7 @@ func (p *parser) parseFuncDecl() *ast.FuncDecl { ...@@ -2487,7 +2461,7 @@ func (p *parser) parseFuncDecl() *ast.FuncDecl {
return decl return decl
} }
func (p *parser) parseDecl(sync func(*parser)) ast.Decl { func (p *parser) parseDecl(sync map[token.Token]bool) ast.Decl {
if p.trace { if p.trace {
defer un(trace(p, "Declaration")) defer un(trace(p, "Declaration"))
} }
...@@ -2506,7 +2480,7 @@ func (p *parser) parseDecl(sync func(*parser)) ast.Decl { ...@@ -2506,7 +2480,7 @@ func (p *parser) parseDecl(sync func(*parser)) ast.Decl {
default: default:
pos := p.pos pos := p.pos
p.errorExpected(pos, "declaration") p.errorExpected(pos, "declaration")
sync(p) p.advance(sync)
return &ast.BadDecl{From: pos, To: p.pos} return &ast.BadDecl{From: pos, To: p.pos}
} }
...@@ -2556,7 +2530,7 @@ func (p *parser) parseFile() *ast.File { ...@@ -2556,7 +2530,7 @@ func (p *parser) parseFile() *ast.File {
if p.mode&ImportsOnly == 0 { if p.mode&ImportsOnly == 0 {
// rest of package body // rest of package body
for p.tok != token.EOF { for p.tok != token.EOF {
decls = append(decls, p.parseDecl((*parser).syncDecl)) decls = append(decls, p.parseDecl(declStart))
} }
} }
} }
......
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