From 1a5acb4b3a9ae0d67536ecae5ad5420974efb0b2 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Fri, 3 Jun 2016 12:13:19 -0700 Subject: cmd/compile/internal/syntax: pragma support for new parser Change-Id: Id4d9b40900b97708d2b4586f5a745dcb8b0eb8bd --- src/cmd/compile/internal/syntax/nodes.go | 6 +++ src/cmd/compile/internal/syntax/parser.go | 1 + src/cmd/compile/internal/syntax/scanner.go | 70 +++++++++++++----------------- 3 files changed, 37 insertions(+), 40 deletions(-) diff --git a/src/cmd/compile/internal/syntax/nodes.go b/src/cmd/compile/internal/syntax/nodes.go index 0aeb3ddd60..f426a5ef47 100644 --- a/src/cmd/compile/internal/syntax/nodes.go +++ b/src/cmd/compile/internal/syntax/nodes.go @@ -30,10 +30,16 @@ func (n *node) init(p *parser) { type File struct { PkgName *Name DeclList []Decl + Pragmas []Pragma Lines int node } +type Pragma struct { + Line int + Text string +} + // ---------------------------------------------------------------------------- // Declarations diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go index 78df06f533..577d939496 100644 --- a/src/cmd/compile/internal/syntax/parser.go +++ b/src/cmd/compile/internal/syntax/parser.go @@ -241,6 +241,7 @@ func (p *parser) file() *File { // p.tok == _EOF f.Lines = p.source.line + f.Pragmas = p.pragmas return f } diff --git a/src/cmd/compile/internal/syntax/scanner.go b/src/cmd/compile/internal/syntax/scanner.go index 7df5e381ab..ac6baf7e58 100644 --- a/src/cmd/compile/internal/syntax/scanner.go +++ b/src/cmd/compile/internal/syntax/scanner.go @@ -7,6 +7,7 @@ package syntax import ( "fmt" "io" + "strings" "unicode" "unicode/utf8" ) @@ -21,6 +22,8 @@ type scanner struct { lit string // valid if tok is _Name or _Literal op Operator // valid if tok is _Operator prec int // valid if tok is _Operator + + pragmas []Pragma } func (s *scanner) init(src io.Reader) { @@ -486,55 +489,42 @@ func (s *scanner) rune() { s.lit = string(s.stopLit()) } -func (s *scanner) match(r rune, prefix string) rune { - for _, m := range prefix { - if r != m { - return r // no match - } - r = s.getr() - } - - // match: consume line - for r != '\n' && r >= 0 { - r = s.getr() - } - s.ungetr() - - return -1 -} - -var pragmas = map[string]bool{ - "noescape": true, - "noinline": true, - "nointerface": true, - "norace": true, - "nosplit": true, - "nowritebarrier": true, - "nowritebarrierrec": true, - "systemstack": true, -} - func (s *scanner) lineComment() { // recognize pragmas + var prefix string r := s.getr() switch r { case 'g': - r = s.match(r, "go:") - if r < 0 { - // m := string(s.buf[start+3 : s.source.pos()]) - // if pragmas[m] { - // // TODO(gri) record pragma - // //println(m) - // } - return - } + prefix = "go:" case 'l': - r = s.match(r, "line:") - if r < 0 { - return + prefix = "line " + default: + goto skip + } + + s.startLit() + for _, m := range prefix { + if r != m { + s.stopLit() + goto skip } + r = s.getr() + } + + for r >= 0 { + if r == '\n' { + s.ungetr() + break + } + r = s.getr() } + s.pragmas = append(s.pragmas, Pragma{ + Line: s.line, + Text: strings.TrimSuffix(string(s.stopLit()), "\r"), + }) + return +skip: // consume line for r != '\n' && r >= 0 { r = s.getr() -- cgit v1.2.3-54-g00ecf