forked from blynn/nex
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
90 lines (83 loc) · 2.25 KB
/
main.go
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")
}
}