Commit aad18b84 authored by Robert Griesemer's avatar Robert Griesemer

cmd/compile: address several more 1.6 TODOs in parser

- fix/check location of popdcl calls where questioned
- remove unnecessary handling of ... (LDDD) in ntype (couldn't be reached)
- inlined and fnret_type and simplified fnres as a consequence
- leave handling of ... (LDDD) in arg_list alone (remove TODO)
- verify that parser requires a ';' after last statement in a case/default
  (added test case)

Fixes #13243.

Change-Id: Iad94b498591a5e85f4cb15bbc01e8e101415560d
Reviewed-on: https://go-review.googlesource.com/17155
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarChris Manghane <cmang@golang.org>
parent 0383bb47
...@@ -225,11 +225,9 @@ func tokstring(tok int32) string { ...@@ -225,11 +225,9 @@ func tokstring(tok int32) string {
return s return s
} }
// catchall // catchall
return yyTokname(int(tok)) return fmt.Sprintf("tok-%v", tok)
} }
// TODO(gri) figure out why yyTokname doesn't work for us as expected
// (issue 13243)
var tokstrings = map[int32]string{ var tokstrings = map[int32]string{
LLITERAL: "LLITERAL", LLITERAL: "LLITERAL",
LASOP: "op=", LASOP: "op=",
...@@ -439,7 +437,7 @@ func (p *parser) import_here() int { ...@@ -439,7 +437,7 @@ func (p *parser) import_here() int {
p.advance(';', ')') p.advance(';', ')')
} }
line := parserline() // TODO(gri) check correct placement of this (issue 13243) line := parserline()
importfile(&path, line) importfile(&path, line)
return line return line
} }
...@@ -899,6 +897,7 @@ func (p *parser) compound_stmt(else_clause bool) *Node { ...@@ -899,6 +897,7 @@ func (p *parser) compound_stmt(else_clause bool) *Node {
} }
l := p.stmt_list() l := p.stmt_list()
p.want('}')
var stmt *Node var stmt *Node
if l == nil { if l == nil {
...@@ -908,8 +907,6 @@ func (p *parser) compound_stmt(else_clause bool) *Node { ...@@ -908,8 +907,6 @@ func (p *parser) compound_stmt(else_clause bool) *Node {
} }
popdcl() popdcl()
p.want('}') // TODO(gri) is this correct location w/ respect to popdcl()? (issue 13243)
return stmt return stmt
} }
...@@ -920,32 +917,9 @@ func (p *parser) caseblock(tswitch *Node) *Node { ...@@ -920,32 +917,9 @@ func (p *parser) caseblock(tswitch *Node) *Node {
} }
stmt := p.case_(tswitch) // does markdcl stmt := p.case_(tswitch) // does markdcl
// If the last token read by the lexer was consumed
// as part of the case, clear it (parser has cleared yychar).
// If the last token read by the lexer was the lookahead
// leave it alone (parser has it cached in yychar).
// This is so that the stmt_list action doesn't look at
// the case tokens if the stmt_list is empty.
//yylast = yychar;
stmt.Xoffset = int64(block) stmt.Xoffset = int64(block)
stmt.Nbody = p.stmt_list() stmt.Nbody = p.stmt_list()
// TODO(gri) what do we need to do here? (issue 13243)
// // This is the only place in the language where a statement
// // list is not allowed to drop the final semicolon, because
// // it's the only place where a statement list is not followed
// // by a closing brace. Handle the error for pedantry.
// // Find the final token of the statement list.
// // yylast is lookahead; yyprev is last of stmt_list
// last := yyprev;
// if last > 0 && last != ';' && yychar != '}' {
// Yyerror("missing statement after label");
// }
popdcl() popdcl()
return stmt return stmt
...@@ -1873,14 +1847,6 @@ func (p *parser) ntype() *Node { ...@@ -1873,14 +1847,6 @@ func (p *parser) ntype() *Node {
p.want(')') p.want(')')
return t return t
case LDDD:
// permit ...T but complain
// TODO(gri) introduced for test/fixedbugs/bug228.go - maybe adjust bug or find better solution
// (issue 13243)
p.syntax_error("")
p.advance()
return p.ntype()
default: default:
p.syntax_error("") p.syntax_error("")
p.advance() p.advance()
...@@ -1898,8 +1864,7 @@ func (p *parser) chan_elem() *Node { ...@@ -1898,8 +1864,7 @@ func (p *parser) chan_elem() *Node {
'[', LCHAN, LMAP, LSTRUCT, LINTERFACE, '[', LCHAN, LMAP, LSTRUCT, LINTERFACE,
'*', '*',
LNAME, '@', '?', LNAME, '@', '?',
'(', '(':
LDDD:
return p.ntype() return p.ntype()
default: default:
...@@ -1909,26 +1874,6 @@ func (p *parser) chan_elem() *Node { ...@@ -1909,26 +1874,6 @@ func (p *parser) chan_elem() *Node {
} }
} }
// go.y:fnret_type
// TODO(gri) only called from fnres - inline and remove this one
// (issue 13243)
func (p *parser) fnret_type() *Node {
if trace && Debug['x'] != 0 {
defer p.trace("fnret_type")()
}
switch p.tok {
case LFUNC, // fntype
LCOMM, // recvchantype
'[', LCHAN, LMAP, LSTRUCT, LINTERFACE, // othertype
'*': // ptrtype
return p.ntype()
default:
return p.dotname()
}
}
// go.y:dotname (partial) // go.y:dotname (partial)
func (p *parser) new_dotname(pkg *Node) *Node { func (p *parser) new_dotname(pkg *Node) *Node {
if trace && Debug['x'] != 0 { if trace && Debug['x'] != 0 {
...@@ -2218,7 +2163,7 @@ func (p *parser) fnres() *NodeList { ...@@ -2218,7 +2163,7 @@ func (p *parser) fnres() *NodeList {
return nil return nil
case LCOMM, LFUNC, '[', LCHAN, LMAP, LSTRUCT, LINTERFACE, '*', LNAME, '@', '?': case LCOMM, LFUNC, '[', LCHAN, LMAP, LSTRUCT, LINTERFACE, '*', LNAME, '@', '?':
result := p.fnret_type() result := p.ntype()
return list1(Nod(ODCLFIELD, nil, result)) return list1(Nod(ODCLFIELD, nil, result))
case '(': case '(':
...@@ -2754,9 +2699,6 @@ func (p *parser) arg_list() (l *NodeList, ddd bool) { ...@@ -2754,9 +2699,6 @@ func (p *parser) arg_list() (l *NodeList, ddd bool) {
defer p.trace("arg_list")() defer p.trace("arg_list")()
} }
// TODO(gri) make this more tolerant in the presence of LDDD
// that is not at the end (issue 13243).
p.want('(') p.want('(')
p.xnest++ p.xnest++
......
...@@ -4,11 +4,12 @@ ...@@ -4,11 +4,12 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Check various syntax errors with switches. // Verify that erroneous switch statements are detected by the compiler.
// Does not compile.
package main package main
func _() { func f() {
switch { switch {
case 0; // ERROR "expecting := or = or : or comma" case 0; // ERROR "expecting := or = or : or comma"
} }
...@@ -18,6 +19,20 @@ func _() { ...@@ -18,6 +19,20 @@ func _() {
default: default:
} }
switch {
case 0: case 0: default:
}
switch {
case 0: f(); case 0:
case 0: f() case 0: // ERROR "unexpected case at end of statement"
}
switch {
case 0: f(); default:
case 0: f() default: // ERROR "unexpected default at end of statement"
}
switch { switch {
if x: // ERROR "expecting case or default or }" if x: // ERROR "expecting case or default or }"
} }
......
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