whatcanGOwrong

This commit is contained in:
2024-09-19 21:38:24 -04:00
commit d0ae4d841d
17908 changed files with 4096831 additions and 0 deletions
@@ -0,0 +1,21 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
Ebnflint verifies that EBNF productions are consistent and grammatically correct.
It reads them from an HTML document such as the Go specification.
Grammar productions are grouped in boxes demarcated by the HTML elements
<pre class="ebnf">
</pre>
Usage:
go tool ebnflint [--start production] [file]
The --start flag specifies the name of the start production for
the grammar; it defaults to "Start".
*/
package main // import "golang.org/x/exp/ebnflint"
@@ -0,0 +1,122 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"bytes"
"flag"
"fmt"
"go/scanner"
"go/token"
"io"
"os"
"path/filepath"
"golang.org/x/exp/ebnf"
)
var fset = token.NewFileSet()
var start = flag.String("start", "Start", "name of start production")
func usage() {
fmt.Fprintf(os.Stderr, "usage: go tool ebnflint [flags] [filename]\n")
flag.PrintDefaults()
os.Exit(1)
}
// Markers around EBNF sections in .html files
var (
open = []byte(`<pre class="ebnf">`)
close = []byte(`</pre>`)
)
func report(err error) {
scanner.PrintError(os.Stderr, err)
os.Exit(1)
}
func extractEBNF(src []byte) []byte {
var buf bytes.Buffer
for {
// i = beginning of EBNF text
i := bytes.Index(src, open)
if i < 0 {
break // no EBNF found - we are done
}
i += len(open)
// write as many newlines as found in the excluded text
// to maintain correct line numbers in error messages
for _, ch := range src[0:i] {
if ch == '\n' {
buf.WriteByte('\n')
}
}
// j = end of EBNF text (or end of source)
j := bytes.Index(src[i:], close) // close marker
if j < 0 {
j = len(src) - i
}
j += i
// copy EBNF text
buf.Write(src[i:j])
// advance
src = src[j:]
}
return buf.Bytes()
}
func main() {
flag.Parse()
var (
name string
r io.Reader
)
switch flag.NArg() {
case 0:
name, r = "<stdin>", os.Stdin
case 1:
name = flag.Arg(0)
default:
usage()
}
if err := verify(name, *start, r); err != nil {
report(err)
}
}
func verify(name, start string, r io.Reader) error {
if r == nil {
f, err := os.Open(name)
if err != nil {
return err
}
defer f.Close()
r = f
}
src, err := io.ReadAll(r)
if err != nil {
return err
}
if filepath.Ext(name) == ".html" || bytes.Index(src, open) >= 0 {
src = extractEBNF(src)
}
grammar, err := ebnf.Parse(name, bytes.NewBuffer(src))
if err != nil {
return err
}
return ebnf.Verify(grammar, start)
}
@@ -0,0 +1,22 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"os"
"runtime"
"testing"
)
func TestSpec(t *testing.T) {
if err := verify(runtime.GOROOT()+"/doc/go_spec.html", "SourceFile", nil); err != nil {
if os.IsNotExist(err) {
// Couldn't find/open the file - skip test rather than
// complain since not all builders copy the spec.
t.Skip("spec file not found")
}
t.Fatal(err)
}
}