aboutsummaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorRyo Nihei <nihei.dev@gmail.com>2021-02-16 01:24:27 +0900
committerRyo Nihei <nihei.dev@gmail.com>2021-02-16 01:43:13 +0900
commit01f1d86b8237755565a1e7fd3e555f557af2114e (patch)
treee962f58692efd7d4388f37db982a021930d094e8 /cli
parentAdd types of lexical specifications (diff)
downloadtre-01f1d86b8237755565a1e7fd3e555f557af2114e.tar.gz
tre-01f1d86b8237755565a1e7fd3e555f557af2114e.tar.xz
Add CLI
Diffstat (limited to 'cli')
-rw-r--r--cli/cmd/compile.go49
-rw-r--r--cli/cmd/lex.go65
-rw-r--r--cli/cmd/root.go17
-rw-r--r--cli/main.go14
4 files changed, 145 insertions, 0 deletions
diff --git a/cli/cmd/compile.go b/cli/cmd/compile.go
new file mode 100644
index 0000000..23aa120
--- /dev/null
+++ b/cli/cmd/compile.go
@@ -0,0 +1,49 @@
+package cmd
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "os"
+
+ "github.com/nihei9/maleeni/compiler"
+ "github.com/nihei9/maleeni/spec"
+ "github.com/spf13/cobra"
+)
+
+func init() {
+ cmd := &cobra.Command{
+ Use: "compile",
+ Short: "Compile a lexical specification into a DFA",
+ Long: `compile takes a lexical specification and generates a DFA accepting the tokens described in the specification.`,
+ Example: ` cat lexspec.json | maleeni compile > clexspec.json`,
+ RunE: runCompile,
+ }
+ rootCmd.AddCommand(cmd)
+}
+
+func runCompile(cmd *cobra.Command, args []string) error {
+ var lspec *spec.LexSpec
+ {
+ data, err := ioutil.ReadAll(os.Stdin)
+ if err != nil {
+ return err
+ }
+ lspec = &spec.LexSpec{}
+ err = json.Unmarshal(data, lspec)
+ if err != nil {
+ return err
+ }
+ }
+ clspec, err := compiler.Compile(lspec)
+ if err != nil {
+ return err
+ }
+ out, err := json.Marshal(clspec)
+ if err != nil {
+ return err
+ }
+ fmt.Fprintf(os.Stdout, "%v\n", string(out))
+
+ return nil
+}
diff --git a/cli/cmd/lex.go b/cli/cmd/lex.go
new file mode 100644
index 0000000..b16ae14
--- /dev/null
+++ b/cli/cmd/lex.go
@@ -0,0 +1,65 @@
+package cmd
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "os"
+
+ "github.com/nihei9/maleeni/driver"
+ "github.com/nihei9/maleeni/spec"
+ "github.com/spf13/cobra"
+)
+
+func init() {
+ cmd := &cobra.Command{
+ Use: "lex clexspec",
+ Short: "Tokenize a text stream",
+ Long: `lex takes a text stream and tokenizes it according to a compiled lexical specification.
+As use ` + "`maleeni compile`" + `, you can generate the specification.`,
+ Example: ` cat src | maleeni lex clexspec.json`,
+ Args: cobra.ExactArgs(1),
+ RunE: runLex,
+ }
+ rootCmd.AddCommand(cmd)
+}
+
+func runLex(cmd *cobra.Command, args []string) error {
+ var clspec *spec.CompiledLexSpec
+ {
+ clspecPath := args[0]
+ f, err := os.Open(clspecPath)
+ if err != nil {
+ return err
+ }
+ data, err := ioutil.ReadAll(f)
+ if err != nil {
+ return err
+ }
+ clspec = &spec.CompiledLexSpec{}
+ err = json.Unmarshal(data, clspec)
+ if err != nil {
+ return err
+ }
+ }
+ lex, err := driver.NewLexer(clspec, os.Stdin)
+ if err != nil {
+ return err
+ }
+ for {
+ tok, err := lex.Next()
+ if err != nil {
+ return err
+ }
+ if tok.EOF {
+ break
+ }
+ if tok.Invalid {
+ fmt.Fprintf(os.Stdout, "-: -: ")
+ } else {
+ fmt.Fprintf(os.Stdout, "%v: %v: ", tok.ID, clspec.Kinds[tok.ID])
+ }
+ fmt.Fprintf(os.Stdout, "\"%v\"\n", string(tok.Match))
+ }
+ return nil
+}
diff --git a/cli/cmd/root.go b/cli/cmd/root.go
new file mode 100644
index 0000000..03579d8
--- /dev/null
+++ b/cli/cmd/root.go
@@ -0,0 +1,17 @@
+package cmd
+
+import "github.com/spf13/cobra"
+
+var rootCmd = &cobra.Command{
+ Use: "maleeni",
+ Short: "Generate a portable DFA from a lexical specification",
+ Long: `maleeni provides two features:
+* Generates a portable DFA from a lexical specification.
+* Tokenizes a text stream according to the lexical specification.
+ This feature is primarily aimed at debugging the lexical specification.`,
+ SilenceUsage: true,
+}
+
+func Execute() error {
+ return rootCmd.Execute()
+}
diff --git a/cli/main.go b/cli/main.go
new file mode 100644
index 0000000..24973e7
--- /dev/null
+++ b/cli/main.go
@@ -0,0 +1,14 @@
+package main
+
+import (
+ "os"
+
+ "github.com/nihei9/maleeni/cli/cmd"
+)
+
+func main() {
+ err := cmd.Execute()
+ if err != nil {
+ os.Exit(1)
+ }
+}