]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: simplify parsing of possibly absent type
authorRobert Griesemer <gri@golang.org>
Sat, 21 Nov 2015 01:31:33 +0000 (17:31 -0800)
committerRobert Griesemer <gri@golang.org>
Mon, 23 Nov 2015 21:29:27 +0000 (21:29 +0000)
Introduce a try_ntype function which doesn't return an error upon
not finding a type. Use it instead of having separate repeated
token checks. Simpler, less code, and more efficient.

Change-Id: I81e482158b71901eb179470269349688636aa0ba
Reviewed-on: https://go-review.googlesource.com/17157
Reviewed-by: Chris Manghane <cmang@golang.org>
src/cmd/compile/internal/gc/parser.go

index 85abca11c80bfda6e42442ed3736fe75b53347c8..8cad440b357d9c660853b17909f3b6a0884d51f8 100644 (file)
@@ -574,9 +574,7 @@ func (p *parser) constdcl() *NodeList {
        var typ *Node
        var exprs *NodeList
        if p.tok != EOF && p.tok != ';' && p.tok != ')' {
-               if p.tok != '=' {
-                       typ = p.ntype()
-               }
+               typ = p.try_ntype()
                if p.got('=') {
                        exprs = p.expr_list()
                }
@@ -593,11 +591,9 @@ func (p *parser) typedcl() *NodeList {
 
        name := typedcl0(p.sym())
 
+       typ := p.try_ntype()
        // handle case where type is missing
-       var typ *Node
-       if p.tok != ';' {
-               typ = p.ntype()
-       } else {
+       if typ == nil {
                p.syntax_error("in type declaration")
                p.advance(';', ')')
        }
@@ -1754,9 +1750,8 @@ func (p *parser) dotdotdot() *Node {
        }
 
        p.want(LDDD)
-       switch p.tok {
-       case LCOMM, LFUNC, '[', LCHAN, LMAP, LSTRUCT, LINTERFACE, '*', LNAME, '@', '?', '(':
-               return Nod(ODDD, p.ntype(), nil)
+       if typ := p.try_ntype(); typ != nil {
+               return Nod(ODDD, typ, nil)
        }
 
        Yyerror("final argument in variadic function missing type")
@@ -1769,6 +1764,22 @@ func (p *parser) ntype() *Node {
                defer p.trace("ntype")()
        }
 
+       if typ := p.try_ntype(); typ != nil {
+               return typ
+       }
+
+       p.syntax_error("")
+       p.advance()
+       return nil
+}
+
+// try_ntype is like ntype but it returns nil if there was no type
+// instead of reporting an error.
+func (p *parser) try_ntype() *Node {
+       if trace && Debug['x'] != 0 {
+               defer p.trace("try_ntype")()
+       }
+
        switch p.tok {
        case LCOMM:
                // recvchantype
@@ -1848,8 +1859,6 @@ func (p *parser) ntype() *Node {
                return t
 
        default:
-               p.syntax_error("")
-               p.advance()
                return nil
        }
 }
@@ -1859,19 +1868,13 @@ func (p *parser) chan_elem() *Node {
                defer p.trace("chan_elem")()
        }
 
-       switch p.tok {
-       case LCOMM, LFUNC,
-               '[', LCHAN, LMAP, LSTRUCT, LINTERFACE,
-               '*',
-               LNAME, '@', '?',
-               '(':
-               return p.ntype()
-
-       default:
-               p.syntax_error("missing channel element type")
-               // assume element type is simply absent - don't advance
-               return nil
+       if typ := p.try_ntype(); typ != nil {
+               return typ
        }
+
+       p.syntax_error("missing channel element type")
+       // assume element type is simply absent - don't advance
+       return nil
 }
 
 // go.y:dotname (partial)
@@ -2158,18 +2161,16 @@ func (p *parser) fnres() *NodeList {
                defer p.trace("fnres")()
        }
 
-       switch p.tok {
-       default:
-               return nil
-
-       case LCOMM, LFUNC, '[', LCHAN, LMAP, LSTRUCT, LINTERFACE, '*', LNAME, '@', '?':
-               result := p.ntype()
-               return list1(Nod(ODCLFIELD, nil, result))
-
-       case '(':
+       if p.tok == '(' {
                result := p.param_list()
                return checkarglist(result, 0)
        }
+
+       if result := p.try_ntype(); result != nil {
+               return list1(Nod(ODCLFIELD, nil, result))
+       }
+
+       return nil
 }
 
 // go.y:xdcl_list