From fbb34936fa22a6117c774d9a3e9d91a41fd77180 Mon Sep 17 00:00:00 2001 From: shaoying Date: Fri, 13 Jul 2018 23:00:14 +0800 Subject: [PATCH] mac opt yac --- src/contexts/cli/cli.go | 100 ++++++++++--- src/contexts/ctx.go | 10 +- src/contexts/nfs/nfs.go | 99 ++++++------- src/contexts/yac/yac.go | 317 +++++++++++----------------------------- 4 files changed, 216 insertions(+), 310 deletions(-) diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index 1d35ca44..2b1cdcef 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -56,6 +56,17 @@ func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server // }}} func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ + cli.alias = map[string][]string{ + "~": []string{"context"}, + "!": []string{"message"}, + "@": []string{"config"}, + "$": []string{"cache"}, + } + + if len(arg) > 0 && arg[0] == "scan_file" { + return cli + } + cli.Caches["level"] = &ctx.Cache{Name: "嵌套层级", Value: "0", Help: "嵌套层级"} cli.Caches["skip"] = &ctx.Cache{Name: "跳过执行", Value: "0", Help: "命令只解析不执行"} cli.Caches["else"] = &ctx.Cache{Name: "解析选择语句", Value: "false", Help: "解析选择语句"} @@ -199,13 +210,6 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ // }}} }} - cli.alias = map[string][]string{ - "~": []string{"context"}, - "!": []string{"message"}, - "@": []string{"config"}, - "$": []string{"cache"}, - } - if cli.Context == Index { Pulse = m } @@ -216,20 +220,66 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ // }}} func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ if len(arg) > 0 && arg[0] == "scan_file" { - cli.Context.Exit = make(chan bool) - m.Find("yac").Call(func(cmd *ctx.Message) *ctx.Message { + yac := m.Find("yac") + if yac.Cap("status") != "start" { + yac.Target().Start(yac) + yac.Cmd("train", "void", "void", "[\t ]+") + + yac.Cmd("train", "key", "key", "[A-Za-z_][A-Za-z_0-9]*") + yac.Cmd("train", "num", "num", "mul{", "0", "-?[1-9][0-9]*", "0[0-9]+", "0x[0-9]+", "}") + yac.Cmd("train", "str", "str", "mul{", "\"[^\"]*\"", "'[^']*'", "}") + + yac.Cmd("train", "tran", "tran", "mul{", "@", "$", "}", "opt{", "[a-zA-Z0-9_]+", "}") + yac.Cmd("train", "word", "word", "mul{", "~", "!", "=", "tran", "str", "[a-zA-Z0-9_/\\-.:]+", "}") + + yac.Cmd("train", "op1", "op1", "mul{", "$", "@", "}") + yac.Cmd("train", "op1", "op1", "mul{", "-z", "-n", "}") + yac.Cmd("train", "op1", "op1", "mul{", "-e", "-f", "-d", "}") + yac.Cmd("train", "op1", "op1", "mul{", "-", "+", "}") + yac.Cmd("train", "op2", "op2", "mul{", "+", "-", "*", "/", "}") + yac.Cmd("train", "op2", "op2", "mul{", ">", ">=", "<", "<=", "=", "!=", "}") + + yac.Cmd("train", "val", "val", "opt{", "op1", "}", "mul{", "num", "key", "str", "tran", "}") + yac.Cmd("train", "exp", "exp", "val", "rep{", "op2", "val", "}") + yac.Cmd("train", "val", "val", "(", "exp", ")") + + yac.Cmd("train", "stm", "var", "var", "key", "opt{", "=", "exp", "}") + yac.Cmd("train", "stm", "let", "let", "key", "mul{", "=", "<-", "}", "exp") + yac.Cmd("train", "stm", "if", "if", "exp") + yac.Cmd("train", "stm", "elif", "elif", "exp") + yac.Cmd("train", "stm", "for", "for", "exp") + yac.Cmd("train", "stm", "else", "else") + yac.Cmd("train", "stm", "end", "end") + yac.Cmd("train", "stm", "function", "function", "rep{", "key", "}") + yac.Cmd("train", "stm", "return", "return", "rep{", "exp", "}") + + yac.Cmd("train", "cmd", "echo", "rep{", "exp", "}") + yac.Cmd("train", "cmd", "cmd", "cache", "rep{", "word", "}") + yac.Cmd("train", "cmd", "cmd", "cache", "key", "rep{", "word", "}") + yac.Cmd("train", "cmd", "cmd", "cache", "key", "opt{", "=", "exp", "}") + yac.Cmd("train", "cmd", "cmd", "rep{", "word", "}") + yac.Cmd("train", "tran", "tran", "$", "(", "cmd", ")") + + yac.Cmd("train", "line", "line", "opt{", "mul{", "stm", "cmd", "}", "}", "mul{", ";", "\n", "#[^\n]*\n", "}") + } + + m.Option("target", m.Target().Name) + yac = m.Find("yac") + yac.Call(func(cmd *ctx.Message) *ctx.Message { if cmd.Detail(0) == "scan_end" { - msg := m.Spawn() - cli.Exit <- true - m.Target().Close(msg) + m.Target().Close(m.Spawn()) return nil } - cmd.Source(m.Target()) - cmd.Target(m.Target()) cmd.Cmd() + m.Option("target", cli.target.Name) + if cmd.Has("return") { + m.Target().Close(m.Spawn()) + cmd.Append("scan_file", false) + } return nil - }, "scan_file", arg[1]) + }, "parse", arg[1]) + m.Cap("stream", yac.Target().Name) return false } @@ -339,10 +389,19 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", t := time.Now().Unix() return fmt.Sprintf("%d", t) }}, + "nshell": &ctx.Cache{Name: "nshell", Value: "0", Help: "模块数量"}, }, Configs: map[string]*ctx.Config{ "time_format": &ctx.Config{Name: "time_format", Value: "2006-01-02 15:04:05", Help: "时间格式"}, "time_interval": &ctx.Config{Name: "time_interval(open/close)", Value: "open", Help: "时间区间"}, + "cli_name": &ctx.Config{Name: "cli_name", Value: "shell", Help: "时间格式", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { + if len(arg) > 0 { // {{{ + return arg[0] + } + return fmt.Sprintf("%s%d", x.Value, m.Capi("nshell", 1)) + // }}} + }}, + "cli_help": &ctx.Config{Name: "cli_help", Value: "shell", Help: "时间区间"}, }, Commands: map[string]*ctx.Command{ "alias": &ctx.Command{Name: "alias [short [long]]|[delete short]", Help: "查看、定义或删除命令别名, short: 命令别名, long: 命令原名, delete: 删除别名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { @@ -870,10 +929,13 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", "echo": &ctx.Command{Name: "echo arg...", Help: "函数调用, name: 函数名, arg: 参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { m.Echo("%s", strings.Join(arg, "")) }}, - "scan_file": &ctx.Command{Name: "scan_file", Help: "函数调用, name: 函数名, arg: 参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - m.Start(arg[0], "cli", "scan_file", arg[0]) - <-m.Target().Exit - }}, + "scan_file": &ctx.Command{ + Name: "scan_file filename [cli_name [cli_help]]", + Help: "解析脚本, filename: 文件名, cli_name: 模块名, cli_help: 模块帮助", + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + m.Start(m.Confx("cli_name", arg, 1), m.Confx("cli_help", arg, 2), key, arg[0]) + <-m.Target().Exit + }}, }, Index: map[string]*ctx.Context{ "void": &ctx.Context{Name: "void", diff --git a/src/contexts/ctx.go b/src/contexts/ctx.go index b7dffd71..72d34a8b 100644 --- a/src/contexts/ctx.go +++ b/src/contexts/ctx.go @@ -156,6 +156,7 @@ func (c *Context) Start(m *Message) bool { // {{{ running := make(chan bool) go m.TryCatch(m, true, func(m *Message) { m.Log(m.Cap("status", "start"), nil, "%d server %v %v", m.root.Capi("nserver", 1), m.Meta["detail"], m.Meta["option"]) + c.Exit = make(chan bool, 1) if running <- true; c.Server != nil && c.Server.Start(m, m.Meta["detail"]...) { c.Close(m, m.Meta["detail"]...) @@ -1695,6 +1696,8 @@ func (m *Message) Cmd(arg ...interface{}) *Message { // {{{ m.Detail(0, arg...) } + m.Exec(m.Meta["detail"][0], m.Meta["detail"][1:]...) + return m if s, t := m.source.master, m.target.master; t != nil && s != t { m.Post(s) } else { @@ -3370,9 +3373,6 @@ func Start(args ...string) { Pulse.Options("terminal_color", true) Pulse.Sesss("log", "log").Conf("bench.log", Pulse.Conf("bench.log")) - for _, m := range Pulse.Search(Pulse.Conf("start")) { - m.Set("detail", Pulse.Conf("init.shy")).Set("option", "stdio").target.Start(m) - } - - <-Index.master.Exit + Pulse.Find("cli").Cmd("scan_file", "etc/init.shy") + Pulse.Find("cli").Cmd("scan_file", "stdio") } diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index cddea159..00904a32 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -2,18 +2,19 @@ package nfs // {{{ // }}} import ( // {{{ "contexts" - - "bufio" "encoding/json" - "fmt" "github.com/nsf/termbox-go" "github.com/skip2/go-qrcode" + + "bufio" + "fmt" "io" "net/url" "os" "os/exec" "strconv" "strings" + "time" "unicode" ) @@ -93,8 +94,7 @@ func (nfs *NFS) prompt(arg ...string) { // {{{ rest = arg[1] } - // if nfs.color(nfs.cli.Conf("PS1"), nfs.Confi("pscolor")).color(line).color(rest); len(rest) > 0 { - if fmt.Fprintf(nfs.out, "> %s%s", line, rest); len(rest) > 0 { + if nfs.color(fmt.Sprintf("[%s]%s> ", time.Now().Format("15:04:05"), nfs.Option("target")), nfs.Confi("pscolor")).color(line).color(rest); len(rest) > 0 { fmt.Fprintf(nfs.out, "\033[%dD", len(rest)) } } @@ -199,10 +199,8 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { // {{{ if nfs.Cap("stream") != "stdio" { return nfs.in.Read(p) } - nfs.Log("fuck", nil, "why") nfs.width, nfs.height = termbox.Size() - nfs.Log("fuck", nil, "why %d %d", nfs.width, nfs.height) buf := make([]rune, 0, 1024) rest := make([]rune, 0, 1024) @@ -391,8 +389,10 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { // {{{ func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ if len(arg) > 0 && arg[0] == "scan_file" { + nfs.Message = m c.Caches = map[string]*ctx.Cache{ - "nread": &ctx.Cache{Name: "nread", Value: "0", Help: "nread"}, + "nread": &ctx.Cache{Name: "nread", Value: "0", Help: "nread"}, + "nwrite": &ctx.Cache{Name: "nwrite", Value: "0", Help: "nwrite"}, } c.Configs = map[string]*ctx.Config{} } else { @@ -428,6 +428,7 @@ func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server // }}} func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ + nfs.Message = m nfs.Context.Master(nil) if nfs.Context == Index { Pulse = m @@ -438,48 +439,28 @@ func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ // }}} func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ if len(arg) > 0 && arg[0] == "scan_file" { - if arg[1] == "stdio" { - if in, ok := m.Data["in"]; ok { - nfs.in = in.(*os.File) - } - if out, ok := m.Data["out"]; ok { - nfs.out = out.(*os.File) - } - bio := bufio.NewScanner(nfs) - nfs.Message = m + nfs.Message = m + nfs.in = m.Optionv("in").(*os.File) + bio := bufio.NewScanner(nfs) + + if m.Options("stdout", m.Cap("stream", arg[1]) == "stdio") { termbox.Init() defer termbox.Close() - - m.Cap("stream", "stdio") - nfs.prompt() - for bio.Scan() { - text := bio.Text() + "; " - m.Result(0, 0, len(text)) - m.Put("append", "0", text) - m.Back(m) - nfs.prompt() - } - - return true + nfs.out = m.Optionv("out").(*os.File) } - in, ok := m.Optionv("in").(*os.File) - m.Assert(ok) + for nfs.prompt(); bio.Scan(); nfs.prompt() { + text := bio.Text() + m.Capi("nread", len(text)) - for !m.Options("scan_end") { - buf := make([]byte, m.Confi("buffer_size")) - n, e := in.Read(buf) - if e != nil && e != io.EOF { - m.Assert(e) + msg := m.Spawn(m.Source()).Set("detail", text) + if m.Back(msg); m.Options("scan_end") { + break } - buf = buf[0:n] - m.Result(0, m.Cap("nread"), n) - m.Put("append", m.Cap("nread"), buf) - m.Capi("nread", n) - m.Back(m) - if n == 0 { - break + for _, v := range msg.Meta["result"] { + m.Capi("nwrite", len(v)) + nfs.print(v) } } return true @@ -712,7 +693,6 @@ func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool { // {{{ switch nfs.Context { case m.Target(): if nfs.in != nil { - m.Log("info", nil, "%d close %s", Pulse.Capi("nfile", -1)+1, m.Cap("name")) nfs.in.Close() nfs.in = nil } @@ -744,27 +724,30 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", if len(arg) > 0 { // {{{ return arg[0] } - return x.Value + m.Cap("nfile") + return fmt.Sprintf("%s%d", x.Value, m.Capi("nfile", 1)) // }}} }}, "nfs_help": &ctx.Config{Name: "nfs_help", Value: "file", Help: "默认模块帮助"}, "buffer_size": &ctx.Config{Name: "buffer_size", Value: "1024", Help: "缓存区大小"}, }, Commands: map[string]*ctx.Command{ - "scan_file": &ctx.Command{Name: "scan_file filename", Help: "扫描文件, filename: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { // {{{ - if arg[0] == "stdio" { - m.Put("option", "in", os.Stdin) - m.Put("option", "out", os.Stdout) - } else { - f, e := os.Open(arg[0]) - m.Assert(e) - m.Put("option", "in", f) - } + "scan_file": &ctx.Command{ + Name: "scan_file filename [nfs_name [nfs_help]]", + Help: "扫描文件, filename: 文件名, nfs_name: 模块名, nfs_help: 模块帮助", + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { // {{{ + if arg[0] == "stdio" { + m.Put("option", "in", os.Stdin) + m.Put("option", "out", os.Stdout) + } else { + f, e := os.Open(arg[0]) + m.Assert(e) + m.Put("option", "in", f) + } - m.Start(m.Confx("nfs_name", arg, 0), m.Confx("nfs_help", arg, 1), "scan_file", arg[0]) - } // }}} - }}, + m.Start(m.Confx("nfs_name", arg, 1), m.Confx("nfs_help", arg, 2), key, arg[0]) + } // }}} + }}, "buffer": &ctx.Command{Name: "buffer [index string]", Help: "扫描文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.buf != nil { // {{{ for i, v := range nfs.buf { diff --git a/src/contexts/yac/yac.go b/src/contexts/yac/yac.go index 9fb3f556..52454126 100644 --- a/src/contexts/yac/yac.go +++ b/src/contexts/yac/yac.go @@ -3,9 +3,6 @@ package yac // {{{ import ( // {{{ "contexts" "fmt" - "io" - "strconv" - "strings" ) // }}} @@ -188,120 +185,25 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po } // }}} -func (yac *YAC) parse(m *ctx.Message, cli *ctx.Context, page, void int, line string) (*ctx.Context, string, []string) { // {{{ - - level := m.Capi("level", 1) - yac.Log("debug", nil, fmt.Sprintf("%s\\%d %s(%d):", m.Cap("label")[0:level], level, yac.word[page], page)) - - hash, word := 0, []string{} - for star, s := 0, page; s != 0 && len(line) > 0; { - - line = yac.Sess("lex").Cmd("parse", line, yac.name(void)).Result(1) - lex := yac.Sess("lex").Cmd("parse", line, yac.name(s)) - - c := byte(lex.Resulti(0)) - state := yac.mat[s][c] - - if state != nil { - if key := yac.Sess("lex").Cmd("parse", line, "key"); key.Resulti(0) == 0 || len(key.Result(2)) <= len(lex.Result(2)) { - m.Log("debug", nil, "%s|%d get(%d,%d): %v \033[31m(%s)\033[0m", m.Cap("label")[0:level], level, s, c, state, lex.Result(2)) - line, word = lex.Result(1), append(word, lex.Result(2)) - } else { - state = nil - } - } - - if state == nil { - for i := 0; i < yac.Capi("ncell"); i++ { - if x := yac.mat[s][byte(i)]; i < m.Capi("nlang") && x != nil { - m.Log("debug", nil, "%s|%d try(%d,%d): %v", m.Cap("label")[0:level], level, s, i, x) - - if c, l, w := yac.parse(m, cli, i, void, line); l != line { - m.Log("debug", nil, "%s|%d get(%d,%d): %v", m.Cap("label")[0:level], level, s, i, x) - line, word = l, append(word, w...) - - cli, state = c, x - break - } - } - } - } - - if state == nil { - s, star = star, 0 - continue - } - - if s, star, hash = state.next, state.star, state.hash; s == 0 { - s, star = star, 0 - } - } - - if hash == 0 { - word = word[:0] - } else { - if msg := m.Spawn(cli).Cmd(yac.hand[hash], word); msg.Hand { - m.Log("debug", nil, "%s>%d set(%d): \033[31m%v\033[0m->\033[32m%v\033[0m", - m.Cap("label")[0:level], level, hash, word, msg.Meta["result"]) - word = msg.Meta["result"] - - m.Copy(msg, "append", "back", "return") - if cli = msg.Target(); msg.Has("cli") { - cli = msg.Data["cli"].(*ctx.Context) - } - } - } - - m.Log("debug", nil, "%s/%d %s(%d):", m.Cap("label")[0:level], level, yac.hand[hash], hash) - m.Capi("level", -1) - return cli, line, word -} - -// }}} -func (yac *YAC) scan(m *ctx.Message, page int, void int, line string) (string, []string) { // {{{ - level := m.Optioni("level2") - m.Optioni("level2", level+1) - if line == "" { //加载数据 - if data, ok := m.Optionv("data").(chan []byte); ok { - if buf := <-data; len(buf) > 0 { - line = string(buf) - } - } - } - m.Assert(line != "") +func (yac *YAC) parse(m *ctx.Message, page int, void int, line string, level int) (string, []string) { // {{{ + m.Log("debug", nil, "%s\\%d %s(%d): %s", m.Conf("label")[0:level], level, yac.name(page), page, line) hash, word := 0, []string{} for star, s := 0, page; s != 0 && len(line) > 0; { + //解析空白 lex := m.Sesss("lex", "lex").Cmd("scan", line, yac.name(void)) - if lex.Result(0) == "-1" { //加载数据 - if next, ok := m.Optionv("next").(chan bool); ok { - next <- true - } - if data, ok := m.Optionv("data").(chan []byte); ok { - if buf := <-data; len(buf) > 0 { - line += string(buf) - continue - } - } - m.Assert(false) + if lex.Result(0) == "-1" { + break } + + //解析单词 line = lex.Result(1) - lex = m.Sesss("lex", "lex").Cmd("scan", line, yac.name(s)) - - if lex.Result(0) == "-1" { //加载数据 - if next, ok := m.Optionv("next").(chan bool); ok { - next <- true - } - if data, ok := m.Optionv("data").(chan []byte); ok { - if buf := <-data; len(buf) > 0 { - line += string(buf) - continue - } - } - m.Assert(false) + if lex.Result(0) == "-1" { + break } + //解析状态 c := byte(lex.Resulti(0)) state := yac.mat[s][c] @@ -316,7 +218,7 @@ func (yac *YAC) scan(m *ctx.Message, page int, void int, line string) (string, [ if state == nil { //嵌套语法递归解析 for i := 0; i < yac.Capi("ncell"); i++ { if x := yac.mat[s][byte(i)]; i < m.Capi("nlang") && x != nil { - if l, w := yac.scan(m, i, void, line); l != line { + if l, w := yac.parse(m, i, void, line, level+1); len(w) > 0 { line, word = l, append(word, w...) state = x break @@ -338,23 +240,29 @@ func (yac *YAC) scan(m *ctx.Message, page int, void int, line string) (string, [ if hash == 0 { word = word[:0] } else { - msg := m.Spawn().Add("detail", yac.hand[hash], word...) + msg := m.Spawn(m.Source()).Add("detail", yac.hand[hash], word...) if m.Back(msg); msg.Hand { - word = msg.Meta["result"] m.Assert(!msg.Has("return")) + word = msg.Meta["result"] } } - m.Optioni("level2", level) + m.Log("debug", nil, "%s/%d %s(%d): %v", m.Conf("label")[0:level], level, yac.name(page), page, word) return line, word } // }}} func (yac *YAC) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ + yac.Message = m + c.Caches = map[string]*ctx.Cache{} c.Configs = map[string]*ctx.Config{} + if len(arg) > 0 && arg[0] == "parse" { + return yac + } + s := new(YAC) s.Context = c return s @@ -362,10 +270,11 @@ func (yac *YAC) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server // }}} func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ - if yac.Message = m; yac.Context == Index { - Pulse = m + yac.Message = m + + if len(arg) > 0 && arg[0] == "parse" { + return yac } - yac.Context.Master(nil) yac.Caches["ncell"] = &ctx.Cache{Name: "词法上限", Value: "128", Help: "词法集合的最大数量"} yac.Caches["nlang"] = &ctx.Cache{Name: "语法上限", Value: "32", Help: "语法集合的最大数量"} @@ -378,16 +287,6 @@ func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ yac.Caches["nnode"] = &ctx.Cache{Name: "节点数量", Value: "0", Help: "状态机连接的逻辑数量"} yac.Caches["nreal"] = &ctx.Cache{Name: "实点数量", Value: "0", Help: "状态机连接的存储数量"} - yac.Caches["level"] = &ctx.Cache{Name: "嵌套层级", Value: "0", Help: "语法解析嵌套层级"} - yac.Caches["label"] = &ctx.Cache{Name: "嵌套标记", Value: "####################", Help: "嵌套层级日志的标记"} - - if len(arg) > 0 { - if _, e := strconv.Atoi(arg[0]); yac.Assert(e) { - yac.Cap("nlang", arg[0]) - yac.Cap("nline", arg[0]) - } - } - yac.page = map[string]int{"nil": 0} yac.word = map[int]string{0: "nil"} yac.hash = map[string]int{"nil": 0} @@ -402,6 +301,45 @@ func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ // }}} func (yac *YAC) Start(m *ctx.Message, arg ...string) bool { // {{{ yac.Message = m + + if len(arg) > 0 && arg[0] == "parse" { + + var out *ctx.Message + data := make(chan string, 1) + next := make(chan bool, 1) + + //加载文件 + m.Options("scan_end", false) + nfs := m.Find("nfs").Call(func(buf *ctx.Message) *ctx.Message { + out = buf + data <- buf.Detail(0) + "; " + <-next + return nil + }, "scan_file", arg[1]) + + go func() { + defer func() { + m.Target().Close(m.Spawn()) + if e := recover(); e != nil { + m.Option("scan_end", true) + next <- true + } + }() + + //解析循环 + for m.Cap("stream", nfs.Target().Name); !m.Options("scan_end"); next <- true { + _, word := yac.parse(m, m.Optioni("page"), m.Optioni("void"), <-data, 1) + if len(word) > 0 { + word = word[:len(word)-1] + if last := len(word) - 1; last > 0 && len(word[last]) > 0 && word[last][len(word[last])-1] != '\n' { + word = append(word, "\n") + } + } + out.Result(0, word) + } + }() + } + return false } @@ -416,10 +354,23 @@ func (yac *YAC) Close(m *ctx.Message, arg ...string) bool { // {{{ // }}} -var Pulse *ctx.Message var Index = &ctx.Context{Name: "yac", Help: "语法中心", - Caches: map[string]*ctx.Cache{}, - Configs: map[string]*ctx.Config{}, + Caches: map[string]*ctx.Cache{ + "nparse": &ctx.Cache{Name: "nparse", Value: "0", Help: "解析器数量"}, + }, + Configs: map[string]*ctx.Config{ + "name": &ctx.Config{Name: "name", Value: "parse", Help: "模块名", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { + if len(arg) > 0 { // {{{ + return arg[0] + } + return fmt.Sprintf("%s%d", x.Value, m.Capi("nparse", 1)) + // }}} + }}, + "help": &ctx.Config{Name: "help", Value: "解析模块", Help: "模块帮助"}, + "line": &ctx.Config{Name: "line", Value: "line", Help: "默认语法"}, + "void": &ctx.Config{Name: "void", Value: "void", Help: "默认空白"}, + "label": &ctx.Config{Name: "嵌套标记", Value: "####################", Help: "嵌套层级日志的标记"}, + }, Commands: map[string]*ctx.Command{ "train": &ctx.Command{Name: "train page hash word...", Help: "添加语法规则, page: 语法集合, hash: 语句类型, word: 语法模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) { // {{{ @@ -458,21 +409,6 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", } // }}} }}, - "parse": &ctx.Command{Name: "parse page void word...", Help: "解析语句, page: 语法集合, void: 空白语法集合, word: 语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if yac, ok := m.Target().Server.(*YAC); m.Assert(ok, "模块类型错误") { // {{{ - page, ok := yac.page[arg[0]] - m.Assert(ok, "语法集合错误") - void, ok := yac.page[arg[1]] - m.Assert(ok, "词法集合错误") - - if cli, ok := m.Data["cli"].(*ctx.Context); m.Assert(ok, "执行模块错误") { - cli, rest, word := yac.parse(m, cli, page, void, strings.Join(arg[2:], " ")) - m.Data["cli"] = cli - m.Result(0, rest, word) - } - } - // }}} - }}, "info": &ctx.Command{Name: "info", Help: "显示缓存", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) { // {{{ for i, v := range yac.seed { @@ -497,92 +433,17 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", } // }}} }}, - "check": &ctx.Command{Name: "check page void word...", Help: "解析语句, page: 语法集合, void: 空白语法集合, word: 语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) { // {{{ - set := map[*State]bool{} - nreal := 0 - for _, v := range yac.state { - nreal++ - set[v] = true + "parse": &ctx.Command{ + Name: "parse filename [name [help]] [line line] [void void]", + Help: "解析文件, filename: name:模块名, help:模块帮助, 文件名, line: 默认语法, void: 默认空白", + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) { // {{{ + m.Optioni("page", yac.page[m.Confx("line")]) + m.Optioni("void", yac.page[m.Confx("void")]) + m.Start(m.Confx("name", arg, 1), m.Confx("help", arg, 2), key, arg[0]) } - - nnode := 0 - for i, v := range yac.mat { - for j, x := range v { - if x == nil && int(j) < m.Capi("nlang") { - continue - } - nnode++ - - if _, ok := set[x]; !ok { - m.Log("fuck", nil, "not in %d %d %v %p", i, j, x, x) - } - } - } - m.Log("fuck", nil, "node: %d real: %d", nnode, nreal) - } - // }}} - }}, - "scan_file": &ctx.Command{Name: "scan_file filename", Help: "解析语句, page: 语法集合, void: 空白语法集合, word: 语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) { // {{{ - m.Optioni("page", yac.page["line"]) - m.Optioni("void", yac.page["void"]) - m.Options("scan_end", false) - m.Option("level2", "1") - - data := make(chan []byte) - next := make(chan bool, 1) - m.Optionv("next", next) - end := make(chan bool, 1) - var out io.Writer - m.Find("nfs").Call(func(nfs *ctx.Message) *ctx.Message { - o := nfs.Optionv("out") - if o != nil { - out = o.(io.Writer) - } - - buf := []byte{} - switch v := nfs.Appendv(nfs.Result(0)).(type) { - case []byte: - buf = v - case string: - buf = []byte(v) - } - select { - case data <- buf: - <-next - case <-end: - } - return nil - }, "scan_file", arg[0], "脚本解析") - - go func() { - defer func() { - if e := recover(); e != nil { - end <- true - m.Option("scan_end", true) - m.Back(m.Spawn().Add("detail", "scan_end")) - } - }() - m.Optionv("data", data) - m.Optionv("next", next) - line := "" - word := []string{} - for { - line, word = yac.scan(m, m.Optioni("page"), m.Optioni("void"), line) - if out != nil { - for i, v := range word { - if i == len(word)-1 { - break - } - fmt.Fprintf(out, "%s", v) - } - } - } - }() - } - // }}} - }}, + // }}} + }}, }, Index: map[string]*ctx.Context{ "void": &ctx.Context{Name: "void", Help: "void",