From 87c8d7a002697e6ff394c1cc3e69a2981444a76a Mon Sep 17 00:00:00 2001 From: shaoying Date: Wed, 11 Jul 2018 09:38:51 +0800 Subject: [PATCH] mac add nfs.scan_file --- Makefile | 8 ++- etc/init.shy | 3 + src/contexts/lex/lex.go | 117 +++++++++++++++++++++++++++++------- src/contexts/nfs/nfs.go | 80 +++++++++++++++++++------ src/contexts/yac/yac.go | 129 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 293 insertions(+), 44 deletions(-) diff --git a/Makefile b/Makefile index 5b9a8035..e55e9db7 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,12 @@ BENCH=src/example/bench.go install: + @cp etc/go.snippets ~/.vim/snippets/ + @cp etc/shy.vim ~/.vim/syntax/ + @touch etc/local.shy go install $(BENCH) - touch etc/local.shy - cp etc/shy.vim ~/.vim/syntax/ - cp etc/go.snippets ~/.vim/snippets/ + @md5 `which bench` + @date build: go build $(BENCH) diff --git a/etc/init.shy b/etc/init.shy index cf4cf382..82425932 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -4,3 +4,6 @@ source etc/local.shy login root root ~web command add get "https://chat.shylinux.com" + +~yac + scan_file etc/demo.shy demo_file diff --git a/src/contexts/lex/lex.go b/src/contexts/lex/lex.go index 608f8017..10d2a3fc 100644 --- a/src/contexts/lex/lex.go +++ b/src/contexts/lex/lex.go @@ -1,11 +1,13 @@ -package lex - -import ( +package lex // {{{ +// }}} +import ( // {{{ "contexts" "fmt" "strconv" ) +// }}} + type Seed struct { page int hash int @@ -35,7 +37,7 @@ type LEX struct { *ctx.Context } -func (lex *LEX) index(hash string, h string) int { +func (lex *LEX) index(hash string, h string) int { // {{{ which := lex.page if hash == "nhash" { which = lex.hash @@ -55,14 +57,16 @@ func (lex *LEX) index(hash string, h string) int { return which[h] } -func (lex *LEX) charset(c byte) []byte { +// }}} +func (lex *LEX) charset(c byte) []byte { // {{{ if cs, ok := lex.char[c]; ok { return cs } return []byte{c} } -func (lex *LEX) train(page int, hash int, seed []byte) int { +// }}} +func (lex *LEX) train(page int, hash int, seed []byte) int { // {{{ ss := []int{page} cn := make([]bool, lex.Capi("ncell")) @@ -220,17 +224,18 @@ func (lex *LEX) train(page int, hash int, seed []byte) int { return hash } -func (lex *LEX) parse(page int, line []byte) (hash int, rest []byte, word []byte) { +// }}} +func (lex *LEX) parse(page int, line []byte) (hash int, rest []byte, word []byte) { // {{{ pos := 0 for star, s := 0, page; s != 0 && pos < len(line); pos++ { c := line[pos] - if c == '\\' && pos < len(line)-1 { + if c == '\\' && pos < len(line)-1 { //跳过转义 pos++ c = lex.charset(line[pos])[0] } - if c > 127 { + if c > 127 { //跳过中文 word = append(word, c) continue } @@ -262,7 +267,55 @@ func (lex *LEX) parse(page int, line []byte) (hash int, rest []byte, word []byte return } -func (lex *LEX) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { +// }}} +func (lex *LEX) scan(m *ctx.Message, page int, line []byte) (hash int, rest []byte, word []byte) { // {{{ + + pos := 0 + for star, s := 0, page; s != 0 && pos < len(line); pos++ { + + c := line[pos] + if c == '\\' && pos < len(line)-1 { //跳过转义 + pos++ + c = lex.charset(line[pos])[0] + } + if c > 127 { //跳过中文 + word = append(word, c) + continue + } + + state := lex.mat[s][c] + lex.Log("debug", nil, "(%d,%d): %v", s, c, state) + if state == nil { + s, star, pos = star, 0, pos-1 + continue + } + + word = append(word, c) + + if state.star { + star = s + } else if x, ok := lex.mat[star][c]; !ok || !x.star { + star = 0 + } + + if s, hash = state.next, state.hash; s == 0 { + s, star = star, 0 + } + } + m.Log("fucK", nil, "why %d", pos) + + if pos == len(line) { + hash, pos, word = -1, 0, word[:0] + } else if hash == 0 { + pos, word = 0, word[:0] + } + rest = line[pos:] + return +} + +// }}} + +func (lex *LEX) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ c.Caches = map[string]*ctx.Cache{} c.Configs = map[string]*ctx.Config{} @@ -271,7 +324,8 @@ func (lex *LEX) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server return s } -func (lex *LEX) Begin(m *ctx.Message, arg ...string) ctx.Server { +// }}} +func (lex *LEX) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ if lex.Message = m; lex.Context == Index { Pulse = m } @@ -315,12 +369,14 @@ func (lex *LEX) Begin(m *ctx.Message, arg ...string) ctx.Server { return lex } -func (lex *LEX) Start(m *ctx.Message, arg ...string) bool { +// }}} +func (lex *LEX) Start(m *ctx.Message, arg ...string) bool { // {{{ lex.Message = m return false } -func (lex *LEX) Close(m *ctx.Message, arg ...string) bool { +// }}} +func (lex *LEX) Close(m *ctx.Message, arg ...string) bool { // {{{ switch lex.Context { case m.Target(): case m.Source(): @@ -328,13 +384,15 @@ func (lex *LEX) Close(m *ctx.Message, arg ...string) bool { return true } +// }}} + var Pulse *ctx.Message var Index = &ctx.Context{Name: "lex", Help: "词法中心", Caches: map[string]*ctx.Cache{}, Configs: map[string]*ctx.Config{}, Commands: map[string]*ctx.Command{ "train": &ctx.Command{Name: "train seed [hash [page]", Help: "添加词法规则", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) { + if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) { // {{{ page, hash := 1, 1 if len(arg) > 2 { page = lex.index("npage", arg[2]) @@ -351,10 +409,10 @@ var Index = &ctx.Context{Name: "lex", Help: "词法中心", m.Result(0, lex.train(page, hash, []byte(arg[0]))) lex.seed = append(lex.seed, &Seed{page, hash, arg[0]}) lex.Cap("stream", fmt.Sprintf("%d,%s,%s", lex.Capi("nseed", 1), lex.Cap("npage"), lex.Cap("nhash"))) - } + } // }}} }}, "parse": &ctx.Command{Name: "parse line [page]", Help: "解析单词", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) { + if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) { // {{{ page := 1 if len(arg) > 1 { page = lex.index("npage", arg[1]) @@ -363,10 +421,23 @@ var Index = &ctx.Context{Name: "lex", Help: "词法中心", hash, rest, word := lex.parse(page, []byte(arg[0])) m.Result(0, hash, string(rest), string(word)) lex.Log("debug", nil, "\033[31m[%v]\033[0m %d [%v]", string(word), hash, string(rest)) - } + } // }}} + }}, + "scan": &ctx.Command{Name: "scan line [page]", Help: "解析单词", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) { // {{{ + page := 1 + if len(arg) > 1 { + page = lex.index("npage", arg[1]) + } + + m.Log("fuck", nil, "%d %s %s", page, arg[1], arg[0]) + hash, rest, word := lex.scan(m, page, []byte(arg[0])) + m.Result(0, hash, string(rest), string(word)) + m.Log("fuck", nil, "\033[31m[%v]\033[0m %d [%v]", string(word), hash, string(rest)) + } // }}} }}, "split": &ctx.Command{Name: "split line page void help", Help: "分割语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) { + if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) { // {{{ page := 1 if len(arg) > 1 { page = lex.index("npage", arg[1]) @@ -387,10 +458,10 @@ var Index = &ctx.Context{Name: "lex", Help: "词法中心", _, _, rest = lex.parse(void, []byte(rest)) hash, word, rest := lex.parse(page, []byte(rest)) m.Add("result", fmt.Sprintf("%d", hash), string(word), string(rest)) - } + } // }}} }}, "info": &ctx.Command{Name: "info", Help: "显示缓存", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) { + if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) { // {{{ for i, v := range lex.seed { m.Echo("seed: %d %v\n", i, v) } @@ -408,10 +479,10 @@ var Index = &ctx.Context{Name: "lex", Help: "词法中心", m.Echo("node: %v %v %v\n", i, k, v) } } - } + } // }}} }}, "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 lex, ok := m.Target().Server.(*LEX); m.Assert(ok) { + if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) { // {{{ set := map[*State]bool{} nreal := 0 for _, v := range lex.state { @@ -433,7 +504,7 @@ var Index = &ctx.Context{Name: "lex", Help: "词法中心", } } m.Log("fuck", nil, "node: %d real: %d", nnode, nreal) - } + } // }}} }}, }, Index: map[string]*ctx.Context{ diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index 74bfd7f5..662f956e 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -387,26 +387,33 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { // {{{ // }}} func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ - c.Caches = map[string]*ctx.Cache{ - "pos": &ctx.Cache{Name: "读写位置", Value: "0", Help: "读写位置"}, - "nline": &ctx.Cache{Name: "缓存命令行数", Value: "0", Help: "缓存命令行数"}, - "return": &ctx.Cache{Name: "缓存命令行数", Value: "0", Help: "缓存命令行数"}, + if len(arg) > 0 && arg[0] == "scan_file" { + c.Caches = map[string]*ctx.Cache{ + "nread": &ctx.Cache{Name: "nread", Value: "0", Help: "nread"}, + } + c.Configs = map[string]*ctx.Config{} + } else { + c.Caches = map[string]*ctx.Cache{ + "pos": &ctx.Cache{Name: "读写位置", Value: "0", Help: "读写位置"}, + "nline": &ctx.Cache{Name: "缓存命令行数", Value: "0", Help: "缓存命令行数"}, + "return": &ctx.Cache{Name: "缓存命令行数", Value: "0", Help: "缓存命令行数"}, - "nbytes": &ctx.Cache{Name: "消息发送字节", Value: "0", Help: "消息发送字节"}, - "nsend": &ctx.Cache{Name: "消息发送数量", Value: "0", Help: "消息发送数量"}, - "nrecv": &ctx.Cache{Name: "消息接收数量", Value: "0", Help: "消息接收数量"}, - "target": &ctx.Cache{Name: "消息接收模块", Value: "ssh", Help: "消息接收模块"}, - "result": &ctx.Cache{Name: "前一条指令执行结果", Value: "", Help: "前一条指令执行结果"}, - "sessid": &ctx.Cache{Name: "会话令牌", Value: "", Help: "会话令牌"}, - } - c.Configs = map[string]*ctx.Config{} + "nbytes": &ctx.Cache{Name: "消息发送字节", Value: "0", Help: "消息发送字节"}, + "nsend": &ctx.Cache{Name: "消息发送数量", Value: "0", Help: "消息发送数量"}, + "nrecv": &ctx.Cache{Name: "消息接收数量", Value: "0", Help: "消息接收数量"}, + "target": &ctx.Cache{Name: "消息接收模块", Value: "ssh", Help: "消息接收模块"}, + "result": &ctx.Cache{Name: "前一条指令执行结果", Value: "", Help: "前一条指令执行结果"}, + "sessid": &ctx.Cache{Name: "会话令牌", Value: "", Help: "会话令牌"}, + } + c.Configs = map[string]*ctx.Config{} - if len(arg) > 1 { - if info, e := os.Stat(arg[1]); e == nil { - c.Caches["name"] = &ctx.Cache{Name: "name", Value: info.Name(), Help: "文件名"} - c.Caches["mode"] = &ctx.Cache{Name: "mode", Value: info.Mode().String(), Help: "文件权限"} - c.Caches["size"] = &ctx.Cache{Name: "size", Value: fmt.Sprintf("%d", info.Size()), Help: "文件大小"} - c.Caches["time"] = &ctx.Cache{Name: "time", Value: info.ModTime().Format("15:03:04"), Help: "创建时间"} + if len(arg) > 1 { + if info, e := os.Stat(arg[1]); e == nil { + c.Caches["name"] = &ctx.Cache{Name: "name", Value: info.Name(), Help: "文件名"} + c.Caches["mode"] = &ctx.Cache{Name: "mode", Value: info.Mode().String(), Help: "文件权限"} + c.Caches["size"] = &ctx.Cache{Name: "size", Value: fmt.Sprintf("%d", info.Size()), Help: "文件大小"} + c.Caches["time"] = &ctx.Cache{Name: "time", Value: info.ModTime().Format("15:03:04"), Help: "创建时间"} + } } } @@ -427,6 +434,26 @@ 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" { + in, ok := m.Optionv("in").(*os.File) + m.Assert(ok) + + for { + buf := make([]byte, m.Confi("buffer_size")) + n, e := in.Read(buf) + if m.Assert(e); n == 0 { + 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) + } + return false + } + m.Target().Sessions["nfs"] = m m.Sessions["nfs"] = m @@ -675,8 +702,25 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", "pscolor": &ctx.Config{Name: "pscolor", Value: "2", Help: "读取文件的默认大小值"}, "statuscolor": &ctx.Config{Name: "statuspscolor", Value: "1", Help: "读取文件的默认大小值"}, "statusbackcolor": &ctx.Config{Name: "statusbackcolor", Value: "2", Help: "读取文件的默认大小值"}, + + "nfs_name": &ctx.Config{Name: "nfs_name", Value: "file", Help: "默认模块命名", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { + if len(arg) > 0 { // {{{ + return arg[0] + } + return x.Value + m.Cap("nfile") + // }}} + }}, + "nfs_help": &ctx.Config{Name: "nfs_help", Value: "file", Help: "默认模块帮助"}, + "buffer_size": &ctx.Config{Name: "buffer_size", Value: "16", 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) { // {{{ + f, e := os.Open(arg[0]) + m.Assert(e) + m.Put("option", "in", f).Start(m.Confx("nfs_name", arg, 0), m.Confx("nfs_help", arg, 1), "scan_file", 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 6b09d53b..9f76c886 100644 --- a/src/contexts/yac/yac.go +++ b/src/contexts/yac/yac.go @@ -256,6 +256,120 @@ func (yac *YAC) parse(m *ctx.Message, cli *ctx.Context, page, void int, line str return cli, line, word } +// }}} +func (yac *YAC) scan(m *ctx.Message, page int, void int, line string) (string, []string) { // {{{ + + hash, word := 0, []string{} + for star, s := 0, page; s != 0 && len(line) > 0; { + line := m.Find("lex").Cmd("scan", line, yac.name(void)).Result(1) + lex := m.Find("lex").Cmd("scan", line, yac.name(s)) + + if lex.Result(0) == "-1" { + return line, word + } + + c := byte(lex.Resulti(0)) + state := yac.mat[s][c] + + if state != nil { + if key := m.Find("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 + } + } + } + } + + break + } + + return + cli := m.Target() + page := m.Optioni("page") + void := m.Optioni("void") + + 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) +} + // }}} func (yac *YAC) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ @@ -430,6 +544,21 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", } // }}} }}, + "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"]) + + rest, word := m.Option("rest"), []string{} + + m.Find("nfs").Call(func(nfs *ctx.Message) *ctx.Message { + data := nfs.Appendv(nfs.Result(0)).([]byte) + rest, word = yac.scan(m, m.Optioni("page"), m.Optioni("void"), rest+string(data)) + return nil + }, "scan_file", arg[0], "脚本解析") + } + // }}} + }}, }, Index: map[string]*ctx.Context{ "void": &ctx.Context{Name: "void", Help: "void",