github.com/blynn/nex@v0.0.0-20210330102341-1a3320dab988/main.go (about)

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