// expectClosing is like expect but provides a better error message
// for the common case of a missing comma before a newline.
//
-func (p *parser) expectClosing(tok token.Token, construct string) token.Pos {
+func (p *parser) expectClosing(tok token.Token, context string) token.Pos {
if p.tok != tok && p.tok == token.SEMICOLON && p.lit == "\n" {
- p.error(p.pos, "missing ',' before newline in "+construct)
+ p.error(p.pos, "missing ',' before newline in "+context)
p.next()
}
return p.expect(tok)
}
}
+func (p *parser) seesComma(context string) bool {
+ if p.tok == token.COMMA {
+ return true
+ }
+ if p.tok == token.SEMICOLON && p.lit == "\n" {
+ p.error(p.pos, "missing ',' before newline in "+context)
+ return true // "insert" the comma and continue
+
+ }
+ return false
+}
+
func assert(cond bool, msg string) {
if !cond {
panic("go/parser internal error: " + msg)
// accept them all for more robust parsing and complain later
for typ := p.parseVarType(isParam); typ != nil; {
list = append(list, typ)
- if p.tok != token.COMMA {
+ if !p.seesComma("variable list") {
break
}
p.next()
// Go spec: The scope of an identifier denoting a function
// parameter or result variable is the function body.
p.declare(field, nil, scope, ast.Var, idents...)
- if p.tok != token.COMMA {
+ if !p.seesComma("parameter list") {
break
}
p.next()
ellipsis = p.pos
p.next()
}
- if p.tok != token.COMMA {
+ if !p.seesComma("argument list") {
break
}
p.next()
for p.tok != token.RBRACE && p.tok != token.EOF {
list = append(list, p.parseElement(true))
- if p.tok != token.COMMA {
+ if !p.seesComma("composite literal") {
break
}
p.next()