1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
package main
import (
"flag"
"io/ioutil"
"log"
"os"
"os/exec"
"strings"
)
var outFilename string
var nfadotFile, dfadotFile string
var autorun, standalone, customError bool
var prefix string
var prefixReplacer *strings.Replacer
func init() {
prefixReplacer = strings.NewReplacer()
}
func main() {
flag.StringVar(&prefix, "p", "yy", "name prefix to use in generated code")
flag.StringVar(&outFilename, "o", "", `output file`)
flag.BoolVar(&standalone, "s", false, `standalone code; NN_FUN macro substitution, no Lex() method`)
flag.BoolVar(&customError, "e", false, `custom error func; no Error() method`)
flag.BoolVar(&autorun, "r", false, `run generated program`)
flag.StringVar(&nfadotFile, "nfadot", "", `show NFA graph in DOT format`)
flag.StringVar(&dfadotFile, "dfadot", "", `show DFA graph in DOT format`)
flag.Parse()
if len(prefix) > 0 {
prefixReplacer = strings.NewReplacer("yy", prefix)
}
nfadot = createDotFile(nfadotFile)
dfadot = createDotFile(dfadotFile)
defer func() {
if nfadot != nil {
dieErr(nfadot.Close(), "Close")
}
if dfadot != nil {
dieErr(dfadot.Close(), "Close")
}
}()
infile, outfile := os.Stdin, os.Stdout
var err error
if flag.NArg() > 0 {
dieIf(flag.NArg() > 1, "nex: extraneous arguments after", flag.Arg(0))
dieIf(strings.HasSuffix(flag.Arg(0), ".go"), "nex: input filename ends with .go:", flag.Arg(0))
basename := flag.Arg(0)
n := strings.LastIndex(basename, ".")
if n >= 0 {
basename = basename[:n]
}
infile, err = os.Open(flag.Arg(0))
dieErr(err, "nex")
defer infile.Close()
if !autorun {
if outFilename == "" {
outFilename = basename + ".nn.go"
outfile, err = os.Create(outFilename)
} else {
outfile, err = os.Create(outFilename)
}
dieErr(err, "nex")
defer outfile.Close()
}
}
if autorun {
tmpdir, err := ioutil.TempDir("", "nex")
dieIf(err != nil, "tempdir:", err)
defer func() {
dieErr(os.RemoveAll(tmpdir), "RemoveAll")
}()
outfile, err = os.Create(tmpdir + "/lets.go")
dieErr(err, "nex")
defer outfile.Close()
}
err = process(outfile, infile)
if err != nil {
log.Fatal(err)
}
if autorun {
c := exec.Command("go", "run", outfile.Name())
c.Stdin, c.Stdout, c.Stderr = os.Stdin, os.Stdout, os.Stderr
dieErr(c.Run(), "go run")
}
}
|