mirror of
https://shylinux.com/x/ContextOS
synced 2025-04-25 16:58:06 +08:00
mac opt lex&yac 优化了词法解析与语法解析
This commit is contained in:
parent
9bddeea4cc
commit
78f27e1608
@ -42,17 +42,19 @@ snippet c
|
||||
if `Filename()`.Context == Index {
|
||||
Pulse = m
|
||||
}
|
||||
`Filename()`.Message = m
|
||||
return `Filename()`
|
||||
}
|
||||
|
||||
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Start(m *ctx.Message, arg ...string) bool {
|
||||
`Filename()`.Message = m
|
||||
return false
|
||||
}
|
||||
|
||||
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Close(m *ctx.Message, arg ...string) bool {
|
||||
switch `Filename()`.Context {
|
||||
case m.Target:
|
||||
case m.Source:
|
||||
case m.Target():
|
||||
case m.Source():
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
37
etc/init.shy
37
etc/init.shy
@ -1,2 +1,35 @@
|
||||
~cli
|
||||
~aaa login root root
|
||||
~aaa login root root
|
||||
|
||||
function plus
|
||||
var a = 1
|
||||
for $a < 10
|
||||
~stdio print $a
|
||||
let a = $a + 1
|
||||
end
|
||||
end
|
||||
~yac check
|
||||
~lex check
|
||||
~log config bench.log hi.log
|
||||
|
||||
|
||||
return
|
||||
if 2 < 1
|
||||
let a = 1 +2
|
||||
if 3 = 3
|
||||
let a = 2 +4
|
||||
end
|
||||
elif 3 > 4
|
||||
let a = 1 +6
|
||||
else
|
||||
let a = 2 +2
|
||||
end
|
||||
|
||||
for $a < 10
|
||||
var b = 1
|
||||
for $b < 4
|
||||
let b = $b+1
|
||||
end
|
||||
let a = $a + 1
|
||||
end
|
||||
return $a + "hello\n context & message word\
|
||||
nice"
|
||||
|
@ -33,6 +33,7 @@ func (aaa *AAA) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
||||
}
|
||||
|
||||
func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||
aaa.Context.Master(nil)
|
||||
aaa.Caches["group"] = &ctx.Cache{Name: "用户组", Value: "", Help: "用户组"}
|
||||
aaa.Caches["username"] = &ctx.Cache{Name: "用户名", Value: "", Help: "用户名"}
|
||||
aaa.Caches["password"] = &ctx.Cache{Name: "用户密码", Value: "", Help: "用户密码,加密存储", Hand: func(m *ctx.Message, x *ctx.Cache, arg ...string) string {
|
||||
|
@ -3,9 +3,6 @@ package cli // {{{
|
||||
import ( // {{{
|
||||
"context"
|
||||
|
||||
"bufio"
|
||||
"io"
|
||||
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -19,27 +16,19 @@ import ( // {{{
|
||||
|
||||
// }}}
|
||||
|
||||
type CLI struct { // {{{
|
||||
out io.WriteCloser
|
||||
bio *bufio.Reader
|
||||
lines []string
|
||||
type CLI struct {
|
||||
nfs *ctx.Message
|
||||
lex *ctx.Message
|
||||
yac *ctx.Message
|
||||
|
||||
yac *ctx.Message
|
||||
lex *ctx.Message
|
||||
target *ctx.Context
|
||||
alias map[string][]string
|
||||
|
||||
*ctx.Context
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
func (cli *CLI) check(arg []string) bool { // {{{
|
||||
if len(arg) < 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
switch arg[0] {
|
||||
func (cli *CLI) check(arg string) bool { // {{{
|
||||
switch arg {
|
||||
case "", "0", "false":
|
||||
return false
|
||||
}
|
||||
@ -48,36 +37,33 @@ func (cli *CLI) check(arg []string) bool { // {{{
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{
|
||||
|
||||
func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
|
||||
c.Caches = map[string]*ctx.Cache{}
|
||||
c.Configs = map[string]*ctx.Config{}
|
||||
c.Caches["skip"] = &ctx.Cache{Name: "跳过执行", Value: cli.Pulse.Cap("skip"), Help: "命令只解析不执行"}
|
||||
|
||||
s := new(CLI)
|
||||
s.Context = c
|
||||
s.lex = cli.lex
|
||||
s.yac = cli.yac
|
||||
if m.Has("for") {
|
||||
s.lines = append(s.lines, cli.lines[cli.Pulse.Capi("pos")-1:]...)
|
||||
} else {
|
||||
s.lines = append(s.lines, cli.lines[cli.Pulse.Capi("pos"):]...)
|
||||
}
|
||||
s.nfs = cli.nfs
|
||||
s.target = cli.target
|
||||
return s
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
||||
func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||
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: "解析选择语句"}
|
||||
cli.Caches["loop"] = &ctx.Cache{Name: "解析循环语句", Value: "-2", Help: "解析选择语句"}
|
||||
cli.Caches["fork"] = &ctx.Cache{Name: "解析结束", Value: "-2", Help: "解析结束模块销毁"}
|
||||
cli.Caches["exit"] = &ctx.Cache{Name: "解析结束", Value: "false", Help: "解析结束模块销毁"}
|
||||
|
||||
cli.Caches["target"] = &ctx.Cache{Name: "操作目标", Value: cli.Name, Help: "命令操作的目标"}
|
||||
cli.Caches["result"] = &ctx.Cache{Name: "执行结果", Value: "", Help: "前一条命令的执行结果"}
|
||||
cli.Caches["back"] = &ctx.Cache{Name: "前一条指令", Value: "", Help: "前一条指令"}
|
||||
cli.Caches["next"] = &ctx.Cache{Name: "下一条指令", Value: "", Help: "下一条指令"}
|
||||
|
||||
cli.Caches["nline"] = &ctx.Cache{Name: "缓存命令行数", Value: "0", Help: "缓存命令行数"}
|
||||
cli.Caches["pos"] = &ctx.Cache{Name: "当前缓存命令", Value: "0", Help: "当前缓存命令"}
|
||||
|
||||
cli.Caches["else"] = &ctx.Cache{Name: "解析选择语句", Value: "false", Help: "解析选择语句"}
|
||||
cli.Caches["exit"] = &ctx.Cache{Name: "解析结束", Value: "false", Help: "解析结束模块销毁"}
|
||||
|
||||
cli.Configs["lex"] = &ctx.Config{Name: "词法解析器", Value: "", Help: "命令行词法解析器", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string {
|
||||
if len(arg) > 0 && len(arg[0]) > 0 { // {{{
|
||||
cli, ok := m.Target().Server.(*CLI)
|
||||
@ -100,7 +86,7 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
||||
// }}}
|
||||
}}
|
||||
cli.Configs["yac"] = &ctx.Config{Name: "词法解析器", Value: "", Help: "命令行词法解析器", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string {
|
||||
if len(arg) > 0 && len(arg[0]) > 0 { // {{{
|
||||
if len(arg) > 0 && len(arg[0]) > 0 {
|
||||
cli, ok := m.Target().Server.(*CLI)
|
||||
m.Assert(ok, "模块类型错误")
|
||||
|
||||
@ -108,31 +94,45 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
||||
m.Assert(yac != nil, "词法解析模块不存在")
|
||||
if yac.Cap("status") != "start" {
|
||||
yac.Target().Start(yac)
|
||||
m.Spawn(yac.Target()).Cmd("train", "void", "void", "[\t ]+")
|
||||
yac.Cmd("train", "void", "void", "[\t ]+")
|
||||
|
||||
m.Spawn(yac.Target()).Cmd("train", "key", "key", "[A-Za-z_][A-Za-z_0-9]*")
|
||||
m.Spawn(yac.Target()).Cmd("train", "num", "num", "mul{", "[1-9][0-9]*", "0[0-9]+", "0x[0-9]+", "}")
|
||||
m.Spawn(yac.Target()).Cmd("train", "str", "str", "mul{", "\"[^\"]*\"", "'[^']*'", "}")
|
||||
yac.Cmd("train", "key", "key", "[A-Za-z_][A-Za-z_0-9]*")
|
||||
yac.Cmd("train", "num", "num", "mul{", "[1-9][0-9]*", "0[0-9]+", "0x[0-9]+", "}")
|
||||
yac.Cmd("train", "str", "str", "mul{", "\"[^\"]*\"", "'[^']*'", "}")
|
||||
|
||||
m.Spawn(yac.Target()).Cmd("train", "tran", "tran", "mul{", "@", "$", "}", "opt{", "[a-zA-Z0-9]+", "}")
|
||||
m.Spawn(yac.Target()).Cmd("train", "word", "word", "mul{", "~", "!", "tran", "\"[^\"]*\"", "'[^']*'", "[a-zA-Z0-9_/.]+", "}")
|
||||
yac.Cmd("train", "tran", "tran", "mul{", "@", "$", "}", "opt{", "[a-zA-Z0-9]+", "}")
|
||||
yac.Cmd("train", "word", "word", "mul{", "~", "!", "tran", "str", "[a-zA-Z0-9_/.]+", "}")
|
||||
|
||||
// m.Spawn(yac.Target()).Cmd("train", "op1", "op1", "opt{", "mul{", "-z", "-n", "}", "}", "word")
|
||||
// m.Spawn(yac.Target()).Cmd("train", "op2", "op2", "op1", "rep{", "mul{", "+", "-", "*", "/", "}", "op1", "}")
|
||||
// m.Spawn(yac.Target()).Cmd("train", "op1", "op1", "(", "op2", ")")
|
||||
//
|
||||
m.Spawn(yac.Target()).Cmd("train", "stm", "var", "var", "key", "opt{", "=", "op2", "}")
|
||||
yac.Cmd("train", "op1", "op1", "mul{", "$", "@", "}")
|
||||
yac.Cmd("train", "op1", "op1", "mul{", "-z", "-n", "}")
|
||||
yac.Cmd("train", "op1", "op1", "mul{", "-", "+", "}")
|
||||
yac.Cmd("train", "op2", "op2", "mul{", "+", "-", "*", "/", "}")
|
||||
yac.Cmd("train", "op2", "op2", "mul{", ">", ">=", "<", "<=", "=", "!=", "}")
|
||||
|
||||
m.Spawn(yac.Target()).Cmd("train", "cmd", "cmd", "rep{", "word", "}")
|
||||
m.Spawn(yac.Target()).Cmd("train", "tran", "tran", "$", "(", "cmd", ")")
|
||||
yac.Cmd("train", "val", "val", "opt{", "op1", "}", "mul{", "num", "key", "str", "}")
|
||||
yac.Cmd("train", "exp", "exp", "val", "rep{", "op2", "val", "}")
|
||||
yac.Cmd("train", "val", "val", "(", "exp", ")")
|
||||
|
||||
m.Spawn(yac.Target()).Cmd("train", "line", "line", "opt{", "mul{", "stm", "cmd", "}", "}", "mul{", ";", "\n", "#[^\n]*\n", "}")
|
||||
yac.Cmd("train", "stm", "var", "var", "key", "opt{", "=", "exp", "}")
|
||||
yac.Cmd("train", "stm", "let", "let", "key", "=", "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", "cmd", "rep{", "word", "}")
|
||||
yac.Cmd("train", "tran", "tran", "$", "(", "cmd", ")")
|
||||
|
||||
yac.Cmd("train", "line", "line", "opt{", "mul{", "stm", "cmd", "}", "}", "mul{", ";", "\n", "#[^\n]*\n", "}")
|
||||
}
|
||||
cli.yac = yac
|
||||
return arg[0]
|
||||
}
|
||||
return x.Value
|
||||
// }}}
|
||||
|
||||
}}
|
||||
cli.Configs["PS1"] = &ctx.Config{Name: "命令行提示符(target/detail)", Value: "target", Help: "命令行提示符,target:显示当前模块,detail:显示详细信息", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string {
|
||||
if len(arg) > 0 { // {{{
|
||||
@ -176,7 +176,6 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
||||
// }}}
|
||||
}}
|
||||
|
||||
cli.target = cli.Context
|
||||
cli.alias = map[string][]string{
|
||||
"~": []string{"context"},
|
||||
"!": []string{"message"},
|
||||
@ -191,125 +190,55 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
||||
return cli
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||
func (cli *CLI) Start(m *ctx.Message, arg ...string) bool {
|
||||
cli.Caches["#"] = &ctx.Cache{Name: "参数个数", Value: fmt.Sprintf("%d", len(arg)), Help: "参数个数"}
|
||||
for i, v := range arg {
|
||||
cli.Caches[fmt.Sprintf("%d", i)] = &ctx.Cache{Name: "执行参数", Value: v, Help: "执行参数"}
|
||||
}
|
||||
|
||||
cli.Context.Exit = make(chan bool)
|
||||
if m.Caps("else", false); !m.Has("skip") {
|
||||
m.Caps("skip", false)
|
||||
} else if m.Capi("skip", 1) == 1 {
|
||||
m.Caps("else", true)
|
||||
if m.Has("level") {
|
||||
m.Cap("level", m.Option("level"))
|
||||
}
|
||||
if m.Has("skip") {
|
||||
m.Cap("skip", m.Option("skip"))
|
||||
if m.Caps("else", false); m.Capi("skip") == 1 {
|
||||
m.Caps("else", true)
|
||||
}
|
||||
}
|
||||
if m.Has("loop") {
|
||||
m.Cap("loop", m.Option("loop"))
|
||||
}
|
||||
if m.Has("fork") {
|
||||
m.Cap("fork", m.Option("fork"))
|
||||
}
|
||||
|
||||
m.Caps("exit", false)
|
||||
if true {
|
||||
if m.Has("stdio") {
|
||||
cli.Context.Exit = make(chan bool)
|
||||
cli.Context.Master(cli.Context)
|
||||
|
||||
if m.Has("stdio") || len(arg) > 0 {
|
||||
go func() {
|
||||
cli.Caches["init.shy"] = &ctx.Cache{Name: "启动脚本", Value: "etc/init.shy", Help: "模块启动时自动运行的脚本"}
|
||||
if len(arg) > 0 {
|
||||
if m.Conf("yac", "yac"); len(arg) > 0 {
|
||||
m.Cap("init.shy", arg[0])
|
||||
}
|
||||
go func() {
|
||||
m.Find("nfs").Cmd("scan", m.Cap("init.shy"))
|
||||
m.Find("nfs").Cmd("scan", "stdio")
|
||||
}()
|
||||
}
|
||||
} else {
|
||||
if m.Has("stdio") {
|
||||
cli.Caches["init.shy"] = &ctx.Cache{Name: "启动脚本", Value: "etc/init.shy", Help: "模块启动时自动运行的脚本"}
|
||||
cli.Caches["level"] = &ctx.Cache{Name: "模块嵌套层数", Value: "0", Help: "模块嵌套层数"}
|
||||
if len(arg) > 0 {
|
||||
m.Cap("init.shy", arg[0])
|
||||
}
|
||||
m.Cap("next", fmt.Sprintf("source %s\n", m.Cap("init.shy")))
|
||||
cli.bio = bufio.NewReader(os.Stdin)
|
||||
cli.out = os.Stdout
|
||||
m.Conf("yac", "yac")
|
||||
m.Cap("stream", "stdout")
|
||||
} else if stream, ok := m.Data["file"]; ok {
|
||||
if bio, ok := stream.(*bufio.Reader); ok {
|
||||
cli.bio = bio
|
||||
m.Cap("stream", "bufio")
|
||||
|
||||
if cli.nfs = m.Find("nfs"); m.Has("stdio") {
|
||||
cli.nfs.Cmd("scan", m.Cap("stream", "stdio"), m.Cmd("source", m.Cap("init.shy")).Get("result"))
|
||||
} else {
|
||||
cli.bio = bufio.NewReader(stream.(io.ReadWriteCloser))
|
||||
m.Cap("stream", "file")
|
||||
cli.nfs.Cmd("scan", m.Cap("stream", m.Cap("init.shy")))
|
||||
}
|
||||
}
|
||||
|
||||
m.Capi("nline", 0, len(cli.lines))
|
||||
m.Caps("pos", m.Has("for"))
|
||||
|
||||
m.Log("info", nil, "%p %s pos:%s nline:%s %d", cli.bio, m.Cap("stream"), m.Cap("pos"), m.Cap("nline"), len(cli.lines))
|
||||
|
||||
go m.AssertOne(m, true, func(m *ctx.Message) {
|
||||
for !m.Caps("exit") {
|
||||
line := m.Cap("next")
|
||||
if m.Cap("next", ""); line == "" {
|
||||
if cli.bio == nil {
|
||||
line = cli.lines[m.Capi("pos", 1)-1]
|
||||
} else {
|
||||
// cli.print(m.Conf("PS1"))
|
||||
if l, e := cli.bio.ReadString('\n'); m.Assert(e) {
|
||||
line = l
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if line == "\n" && cli.out != nil {
|
||||
line = m.Cap("back") + "\n"
|
||||
m.Cap("back", "")
|
||||
}
|
||||
|
||||
yac := m.Spawn(cli.yac.Target())
|
||||
yac.Cmd("parse", "line", "void", line)
|
||||
}
|
||||
}, func(m *ctx.Message) {
|
||||
m.Caps("exit", true)
|
||||
m.Spawn(cli.Context).Set("detail", "end").Post(cli.Context)
|
||||
})
|
||||
}()
|
||||
}
|
||||
|
||||
m.Deal(func(msg *ctx.Message, arg ...string) bool {
|
||||
return !cli.Has("skip") || !m.Caps("skip") || Index.Has(msg.Get("detail"), "command")
|
||||
return !m.Caps("skip") || Index.Has(msg.Get("detail"), "command")
|
||||
|
||||
}, func(msg *ctx.Message, arg ...string) bool {
|
||||
if cli.Has("skip") && m.Caps("skip") {
|
||||
if m.Caps("skip") {
|
||||
return !m.Caps("exit")
|
||||
}
|
||||
|
||||
if !msg.Hand && cli.Owner == ctx.Index.Owner {
|
||||
msg.Hand = true
|
||||
msg.Log("system", nil, "%v", msg.Meta["detail"])
|
||||
|
||||
msg.Set("result").Set("append")
|
||||
c := exec.Command(msg.Meta["detail"][0], msg.Meta["detail"][1:]...)
|
||||
|
||||
if cli.out == os.Stdout {
|
||||
c.Stdin, c.Stdout, c.Stderr = os.Stdin, os.Stdout, os.Stderr
|
||||
if e := c.Start(); e != nil {
|
||||
msg.Echo("error: ")
|
||||
msg.Echo("%s\n", e)
|
||||
} else if e := c.Wait(); e != nil {
|
||||
msg.Echo("error: ")
|
||||
msg.Echo("%s\n", e)
|
||||
}
|
||||
} else {
|
||||
if out, e := c.CombinedOutput(); e != nil {
|
||||
msg.Echo("error: ")
|
||||
msg.Echo("%s\n", e)
|
||||
} else {
|
||||
msg.Echo(string(out))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if msg.Target().Context() != nil || msg.Target() == ctx.Index {
|
||||
cli.target = msg.Target()
|
||||
}
|
||||
m.Cap("target", cli.target.Name)
|
||||
|
||||
return !m.Caps("exit")
|
||||
})
|
||||
|
||||
@ -321,26 +250,10 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||
return !cli.Pulse.Has("save")
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (cli *CLI) Close(m *ctx.Message, arg ...string) bool { // {{{
|
||||
func (cli *CLI) Close(m *ctx.Message, arg ...string) bool {
|
||||
switch cli.Context {
|
||||
case m.Target():
|
||||
if p, ok := cli.Context.Context().Server.(*CLI); ok {
|
||||
if p.bio != nil && cli.Context != Index {
|
||||
if m.Has("for") {
|
||||
cli.lines = cli.lines[1:]
|
||||
}
|
||||
p.lines = append(p.lines, cli.lines...)
|
||||
p.Pulse.Capi("nline", 0, len(p.lines))
|
||||
}
|
||||
if p.Pulse.Capi("pos", cli.Pulse.Capi("pos")); m.Has("for") {
|
||||
p.Pulse.Capi("pos", -1)
|
||||
}
|
||||
|
||||
m.Log("info", nil, "%p %s pos:%s nline:%s %d", cli.bio, m.Cap("stream"), m.Cap("pos"), m.Cap("nline"), len(cli.lines))
|
||||
m.Log("info", nil, "%p %s pos:%s nline:%s %d", p.bio, p.Pulse.Cap("stream"), p.Pulse.Cap("pos"), p.Pulse.Cap("nline"), len(p.lines))
|
||||
}
|
||||
|
||||
m.Echo(cli.nfs.Cap("return"))
|
||||
case m.Source():
|
||||
if m.Name == "aaa" {
|
||||
if !cli.Context.Close(m.Spawn(cli.Context), arg...) {
|
||||
@ -352,15 +265,40 @@ func (cli *CLI) Close(m *ctx.Message, arg ...string) bool { // {{{
|
||||
return true
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
var Pulse *ctx.Message
|
||||
var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
Caches: map[string]*ctx.Cache{
|
||||
"skip": &ctx.Cache{Name: "跳过执行", Value: "0", Help: "命令只解析不执行"},
|
||||
},
|
||||
Caches: map[string]*ctx.Cache{},
|
||||
Configs: map[string]*ctx.Config{},
|
||||
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) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{
|
||||
switch len(arg) {
|
||||
case 0:
|
||||
for k, v := range cli.alias {
|
||||
m.Echo("%s: %v\n", k, v)
|
||||
}
|
||||
case 1:
|
||||
m.Echo("%s: %v\n", arg[0], cli.alias[arg[0]])
|
||||
default:
|
||||
if arg[0] == "delete" {
|
||||
m.Echo("delete: %s %v\n", arg[1], cli.alias[arg[1]])
|
||||
delete(cli.alias, arg[1])
|
||||
} else {
|
||||
cli.alias[arg[0]] = arg[1:]
|
||||
m.Echo("%s: %v\n", arg[0], cli.alias[arg[0]])
|
||||
}
|
||||
}
|
||||
} // }}}
|
||||
}},
|
||||
"sleep": &ctx.Command{Name: "sleep time", Help: "睡眠, time(ns/us/ms/s/m/h): 时间值(纳秒/微秒/毫秒/秒/分钟/小时)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if _, ok := m.Source().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{
|
||||
if d, e := time.ParseDuration(arg[0]); m.Assert(e) {
|
||||
m.Log("info", nil, "sleep %v", d)
|
||||
time.Sleep(d)
|
||||
m.Log("info", nil, "sleep %v done", d)
|
||||
}
|
||||
} // }}}
|
||||
}},
|
||||
"express": &ctx.Command{Name: "express exp", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
result := "false" // {{{
|
||||
switch len(arg) {
|
||||
@ -448,7 +386,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
} else {
|
||||
result = fmt.Sprintf("%t", arg[0] >= arg[2])
|
||||
}
|
||||
case "==":
|
||||
case "=":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%t", v1 == v2)
|
||||
} else {
|
||||
@ -474,8 +412,24 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
m.Echo(result)
|
||||
// }}}
|
||||
}},
|
||||
"op1": &ctx.Command{Name: "op1 word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if _, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
"str": &ctx.Command{Name: "str word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{
|
||||
str := arg[0][1 : len(arg[0])-1]
|
||||
str = strings.Replace(str, "\\n", "\n", -1)
|
||||
str = strings.Replace(str, "\\t", "\t", -1)
|
||||
m.Echo(str)
|
||||
} else {
|
||||
m.Set("result", arg...)
|
||||
}
|
||||
// }}}
|
||||
}},
|
||||
"val": &ctx.Command{Name: "val word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{
|
||||
if arg[0] == "(" {
|
||||
m.Echo(arg[1])
|
||||
return
|
||||
}
|
||||
|
||||
if len(arg) == 1 {
|
||||
m.Echo(arg[0])
|
||||
return
|
||||
@ -494,19 +448,25 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
} else {
|
||||
m.Echo("true")
|
||||
}
|
||||
case "$":
|
||||
m.Echo(m.Cap(arg[1]))
|
||||
case "@":
|
||||
m.Echo(m.Conf(arg[1]))
|
||||
}
|
||||
} else {
|
||||
m.Set("result", arg...)
|
||||
}
|
||||
// }}}
|
||||
}},
|
||||
"op2": &ctx.Command{Name: "op2 word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
"exp": &ctx.Command{Name: "exp word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{
|
||||
pre := map[string]int{"+": 1, "-": 1, "*": 2, "/": 2}
|
||||
num := []string{arg[0]}
|
||||
op := []string{}
|
||||
|
||||
for i := 1; i < len(arg); i += 2 {
|
||||
if len(op) > 0 && pre[op[len(op)-1]] >= pre[arg[i]] {
|
||||
num[len(op)-1] = m.Spawn(cli.Context).Cmd("express", num[len(op)-1], op[len(op)-1], num[len(op)])
|
||||
num[len(op)-1] = m.Cmd("express", num[len(op)-1], op[len(op)-1], num[len(op)]).Get("result")
|
||||
num = num[:len(num)-1]
|
||||
op = op[:len(op)-1]
|
||||
}
|
||||
@ -516,15 +476,18 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
}
|
||||
|
||||
for i := len(op) - 1; i >= 0; i-- {
|
||||
num[i] = m.Spawn(cli.Context).Cmd("express", num[i], op[i], num[i+1])
|
||||
num[i] = m.Cmd("express", num[i], op[i], num[i+1]).Get("result")
|
||||
}
|
||||
|
||||
m.Echo("%s", num[0])
|
||||
} else {
|
||||
m.Set("result", arg...)
|
||||
}
|
||||
// }}}
|
||||
}},
|
||||
"tran": &ctx.Command{Name: "tran word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if _, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{
|
||||
msg := m.Spawn(cli.target)
|
||||
switch len(arg) {
|
||||
case 1:
|
||||
switch arg[0] {
|
||||
@ -536,16 +499,17 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
case 2:
|
||||
switch arg[0] {
|
||||
case "$":
|
||||
m.Echo(m.Cap(arg[1]))
|
||||
m.Echo(msg.Cap(arg[1]))
|
||||
case "@":
|
||||
m.Echo(m.Conf(arg[1]))
|
||||
m.Echo(msg.Conf(arg[1]))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m.Set("result", arg...)
|
||||
} // }}}
|
||||
}},
|
||||
"cmd": &ctx.Command{Name: "cmd word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") {
|
||||
msg := m.Spawn(cli.target)
|
||||
if a, ok := cli.alias[arg[0]]; ok {
|
||||
msg.Set("detail", a...)
|
||||
@ -553,182 +517,139 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
} else {
|
||||
msg.Set("detail", arg...)
|
||||
}
|
||||
msg.Cmd()
|
||||
|
||||
msg.Post(cli.Context)
|
||||
if m.Hand = false; msg.Hand {
|
||||
m.Hand = true
|
||||
m.Meta["result"] = msg.Meta["result"]
|
||||
}
|
||||
} // }}}
|
||||
}},
|
||||
"parse": &ctx.Command{Name: "parse word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if !msg.Hand && cli.Owner == ctx.Index.Owner {
|
||||
msg.Hand = true
|
||||
msg.Log("system", nil, "%v", msg.Meta["detail"])
|
||||
|
||||
msg := m.Spawn(cli.target)
|
||||
if a, ok := cli.alias[arg[0]]; ok {
|
||||
msg.Set("detail", a...)
|
||||
msg.Meta["detail"] = append(msg.Meta["detail"], arg[1:]...)
|
||||
} else {
|
||||
msg.Set("detail", arg...)
|
||||
}
|
||||
msg.Set("result").Set("append")
|
||||
c := exec.Command(msg.Meta["detail"][0], msg.Meta["detail"][1:]...)
|
||||
|
||||
msg.Post(cli.Context)
|
||||
if m.Hand = false; msg.Hand {
|
||||
m.Hand = true
|
||||
m.Meta["result"] = msg.Meta["result"]
|
||||
}
|
||||
} // }}}
|
||||
}},
|
||||
"lines": &ctx.Command{Name: "line word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
arg = arg[:len(arg)-1]
|
||||
|
||||
m.Hand = false
|
||||
result := strings.TrimRight(strings.Join(arg, ""), "\n")
|
||||
if m.Cap("result", result); len(result) > 0 {
|
||||
m.Echo(result + "\n")
|
||||
// cli.print(result + "\n")
|
||||
}
|
||||
|
||||
if m.Cap("back", ""); cli.bio != nil {
|
||||
cli.lines = append(cli.lines, strings.Join(arg, " "))
|
||||
m.Capi("nline", 1)
|
||||
m.Capi("pos", 1)
|
||||
}
|
||||
} // }}}
|
||||
}},
|
||||
"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) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) && (!cli.Has("skip") || !cli.Pulse.Caps("skip")) { // {{{
|
||||
switch len(arg) {
|
||||
case 0:
|
||||
for k, v := range cli.alias {
|
||||
m.Echo("%s: %v\n", k, v)
|
||||
}
|
||||
case 1:
|
||||
m.Echo("%s: %v\n", arg[0], cli.alias[arg[0]])
|
||||
default:
|
||||
if arg[0] == "delete" {
|
||||
m.Echo("delete: %s %v\n", arg[1], cli.alias[arg[1]])
|
||||
delete(cli.alias, arg[1])
|
||||
if false {
|
||||
c.Stdin, c.Stdout, c.Stderr = os.Stdin, os.Stdout, os.Stderr
|
||||
if e := c.Start(); e != nil {
|
||||
msg.Echo("error: ")
|
||||
msg.Echo("%s\n", e)
|
||||
} else if e := c.Wait(); e != nil {
|
||||
msg.Echo("error: ")
|
||||
m.Echo("%s\n", e)
|
||||
}
|
||||
} else {
|
||||
cli.alias[arg[0]] = arg[1:]
|
||||
m.Echo("%s: %v\n", arg[0], cli.alias[arg[0]])
|
||||
if out, e := c.CombinedOutput(); e != nil {
|
||||
msg.Echo("error: ")
|
||||
msg.Echo("%s\n", e)
|
||||
} else {
|
||||
msg.Echo(string(out))
|
||||
}
|
||||
}
|
||||
}
|
||||
} // }}}
|
||||
}},
|
||||
"sleep": &ctx.Command{Name: "sleep time", Help: "睡眠, time(ns/us/ms/s/m/h): 时间值(纳秒/微秒/毫秒/秒/分钟/小时)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Source().Server.(*CLI); m.Assert(ok) && (!cli.Has("skip") || !cli.Pulse.Caps("skip")) { // {{{
|
||||
if d, e := time.ParseDuration(arg[0]); m.Assert(e) {
|
||||
m.Log("info", nil, "sleep %v", d)
|
||||
time.Sleep(d)
|
||||
m.Log("info", nil, "sleep %v done", d)
|
||||
|
||||
if msg.Target().Context() != nil || msg.Target() == ctx.Index {
|
||||
cli.target = msg.Target()
|
||||
}
|
||||
} // }}}
|
||||
|
||||
m.Cap("target", cli.target.Name)
|
||||
m.Set("result", msg.Meta["result"]...)
|
||||
|
||||
} else {
|
||||
m.Set("result", arg...)
|
||||
}
|
||||
}},
|
||||
"var": &ctx.Command{Name: "var a [= exp]", Help: "定义变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) && (!cli.Has("skip") || !cli.Pulse.Caps("skip")) { // {{{
|
||||
val := ""
|
||||
if len(arg) > 3 {
|
||||
val = m.Spawn(cli.Context).Cmd(append([]string{"express"}, arg[3:]...)...)
|
||||
if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{
|
||||
if m.Cap(arg[1], arg[1], "", "临时变量"); len(arg) > 3 {
|
||||
m.Cap(arg[1], arg[3])
|
||||
}
|
||||
m.Cap(arg[1], arg[1], val, "临时变量")
|
||||
} else {
|
||||
m.Set("result", arg...)
|
||||
} // }}}
|
||||
}},
|
||||
"let": &ctx.Command{Name: "let a = exp", Help: "设置变量, a: 变量名, exp: 表达式(a {+|-|*|/|%} b)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Source().Server.(*CLI); m.Assert(ok) && (!cli.Has("skip") || !cli.Pulse.Caps("skip")) { // {{{
|
||||
m.Echo(cli.Pulse.Cap(arg[0], m.Spawn(cli.Context).Cmd(append([]string{"express"}, arg[2:]...)...)))
|
||||
if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{
|
||||
m.Cap(arg[1], arg[3])
|
||||
} else {
|
||||
m.Set("result", arg...)
|
||||
} // }}}
|
||||
}},
|
||||
"source": &ctx.Command{Name: "source file", Help: "运行脚本, file: 脚本文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Source().Server.(*CLI); m.Assert(ok) && (!cli.Has("skip") || !cli.Pulse.Caps("skip")) { // {{{
|
||||
if f, e := os.Open(arg[0]); m.Assert(e) {
|
||||
m.Put("option", "file", f).Start(fmt.Sprintf("%s%d", key, Pulse.Capi("level", 1)), "脚本文件")
|
||||
<-m.Target().Exit
|
||||
Pulse.Capi("level", -1)
|
||||
}
|
||||
} // }}}
|
||||
if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") {
|
||||
m.Start(fmt.Sprintf("%s%d", key, m.Optioni("level", m.Capi("level")+1)), "脚本文件", arg[0])
|
||||
}
|
||||
}},
|
||||
"return": &ctx.Command{Name: "return result...", Help: "结束脚本, rusult: 返回值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Source().Server.(*CLI); m.Assert(ok) && (!cli.Has("skip") || !cli.Pulse.Caps("skip")) { // {{{
|
||||
call := cli.Requests[len(cli.Requests)-1]
|
||||
call.Set("result", arg...)
|
||||
cli.Pulse.Caps("exit", true)
|
||||
} // }}}
|
||||
if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") {
|
||||
m.Add("append", "return", arg[1:]...)
|
||||
}
|
||||
}},
|
||||
"if": &ctx.Command{Name: "if exp", Help: "条件语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Source().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if m.Target(m.Source()); (cli.Has("skip") && cli.Pulse.Caps("skip")) || !cli.check(arg) {
|
||||
m.Add("option", "skip")
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
if m.Optioni("skip", 0); m.Caps("skip") || !cli.check(arg[1]) {
|
||||
m.Optioni("skip", m.Capi("skip")+1)
|
||||
}
|
||||
|
||||
m.Put("option", "file", cli.bio).Start(fmt.Sprintf("%s%d", key, Pulse.Capi("level", 1)), "条件语句")
|
||||
<-m.Target().Exit
|
||||
Pulse.Capi("level", -1)
|
||||
} // }}}
|
||||
m.Start(fmt.Sprintf("%s%d", key, m.Optioni("level", m.Capi("level")+1)), "条件语句")
|
||||
}
|
||||
}},
|
||||
"elif": &ctx.Command{Name: "elif exp", Help: "条件语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Source().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if cli.Pulse.Caps("skip", !cli.Pulse.Caps("else")) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
if !m.Caps("else") {
|
||||
m.Caps("skip", true)
|
||||
return
|
||||
}
|
||||
cli.Pulse.Caps("else", cli.Pulse.Caps("skip", !cli.check(arg)))
|
||||
} // }}}
|
||||
|
||||
if m.Caps("skip") {
|
||||
cli.nfs.Capi("pos", -1)
|
||||
m.Caps("skip", false)
|
||||
return
|
||||
}
|
||||
|
||||
m.Caps("else", m.Caps("skip", !cli.check(arg[1])))
|
||||
}
|
||||
}},
|
||||
"else": &ctx.Command{Name: "else", Help: "条件语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Source().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
cli.Pulse.Caps("skip", !cli.Pulse.Caps("else"))
|
||||
} // }}}
|
||||
if _, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
m.Caps("skip", !m.Caps("else"))
|
||||
}
|
||||
}},
|
||||
"end": &ctx.Command{Name: "end", Help: "结束语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Source().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if cli.Pulse.Caps("exit", true); cli.Pulse.Has("for") && !cli.Pulse.Caps("skip") {
|
||||
cli.Pulse.Caps("exit", false)
|
||||
cli.Pulse.Cap("pos", "0")
|
||||
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
if m.Capi("fork") != -2 {
|
||||
m.Spawn(cli.nfs.Target()).Cmd("copy", cli.Name, m.Cap("fork"), m.Option("pos"))
|
||||
}
|
||||
cli.bio = nil
|
||||
} // }}}
|
||||
|
||||
if m.Caps("exit", true); !m.Caps("skip") && m.Capi("loop") >= 0 {
|
||||
m.Append("back", m.Cap("loop"))
|
||||
m.Caps("exit", false)
|
||||
} else {
|
||||
m.Put("append", "cli", cli.Context.Context())
|
||||
}
|
||||
}
|
||||
}},
|
||||
"for": &ctx.Command{Name: "for exp", Help: "循环语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Source().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if cli.Pulse.Has("for") && cli.Pulse.Capi("pos") == 1 {
|
||||
cli.Pulse.Caps("skip", !cli.check(arg))
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
if m.Capi("loop") != -2 && m.Capi("loop") == m.Optioni("pos")-1 {
|
||||
m.Caps("skip", !cli.check(arg[1]))
|
||||
return
|
||||
}
|
||||
if m.Target(m.Source()); (cli.Has("skip") && cli.Pulse.Caps("skip")) || !cli.check(arg) {
|
||||
m.Add("option", "skip")
|
||||
|
||||
if m.Optioni("skip", 0); m.Caps("skip") || !cli.check(arg[1]) {
|
||||
m.Optioni("skip", m.Capi("skip")+1)
|
||||
}
|
||||
m.Add("option", "for", cli.Pulse.Cap("back"))
|
||||
m.Put("option", "file", cli.bio).Start(fmt.Sprintf("%s%d", key, Pulse.Capi("level", 1)), "循环语句")
|
||||
<-m.Target().Exit
|
||||
Pulse.Capi("level", -1)
|
||||
} // }}}
|
||||
m.Optioni("loop", m.Optioni("pos")-1)
|
||||
m.Start(fmt.Sprintf("%s%d", key, m.Optioni("level", m.Capi("level")+1)), "循环语句")
|
||||
}
|
||||
}},
|
||||
"function": &ctx.Command{Name: "function name", Help: "函数定义, name: 函数名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if cli, ok := m.Source().Server.(*CLI); m.Assert(ok) { // {{{
|
||||
if _, ok := cli.Context.Context().Server.(*CLI); ok {
|
||||
m.Target(m.Source().Context())
|
||||
} else {
|
||||
m.Target(m.Source())
|
||||
}
|
||||
|
||||
m.Add("option", "skip").Add("option", "save")
|
||||
m.Put("option", "file", cli.bio).Start(arg[0], "函数定义")
|
||||
<-m.Target().Exit
|
||||
} // }}}
|
||||
if _, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
m.Optioni("fork", m.Optioni("pos")+1)
|
||||
m.Optioni("skip", m.Capi("skip")+1)
|
||||
m.Start(arg[1], "循环语句")
|
||||
}
|
||||
}},
|
||||
"call": &ctx.Command{Name: "call name arg...", Help: "函数调用, name: 函数名, arg: 参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
m.Target(m.Source()) // {{{
|
||||
m.BackTrace(func(msg *ctx.Message) bool {
|
||||
if fun := msg.Find(arg[0], false); fun != nil {
|
||||
fun.Add("detail", arg[0], arg[1:]...).Target().Start(fun)
|
||||
<-fun.Target().Exit
|
||||
m.Set("result", fun.Meta["result"]...)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}) // }}}
|
||||
fun := m.Find("nfs.file1." + arg[0])
|
||||
fun.Target().Start(fun)
|
||||
}},
|
||||
},
|
||||
}
|
||||
@ -737,4 +658,6 @@ func init() {
|
||||
cli := &CLI{}
|
||||
cli.Context = Index
|
||||
ctx.Index.Register(Index, cli)
|
||||
|
||||
cli.target = Index
|
||||
}
|
||||
|
@ -127,6 +127,8 @@ func (c *Context) Spawn(m *Message, name string, help string) *Context { // {{{
|
||||
func (c *Context) Begin(m *Message) *Context { // {{{
|
||||
c.Caches["status"] = &Cache{Name: "服务状态(begin/start/close)", Value: "begin", Help: "服务状态,begin:初始完成,start:正在运行,close:未在运行"}
|
||||
c.Caches["stream"] = &Cache{Name: "服务数据", Value: "", Help: "服务数据"}
|
||||
c.Caches["debug"] = &Cache{Name: "命令日志", Value: "true", Help: "嵌套层级"}
|
||||
c.Configs["debug"] = &Config{Name: "过程日志", Value: "true", Help: "嵌套层级"}
|
||||
|
||||
m.Index = 1
|
||||
c.Pulse = m
|
||||
@ -153,6 +155,7 @@ func (c *Context) Begin(m *Message) *Context { // {{{
|
||||
|
||||
// }}}
|
||||
func (c *Context) Start(m *Message) bool { // {{{
|
||||
m.Hand = true
|
||||
|
||||
if m != c.Requests[0] {
|
||||
c.Requests, m.Index = append(c.Requests, m), len(c.Requests)+1
|
||||
@ -238,8 +241,11 @@ func (c *Context) Context() *Context { // {{{
|
||||
|
||||
// }}}
|
||||
func (c *Context) Master(s ...*Context) *Context { // {{{
|
||||
if len(s) > 0 && s[0] == c {
|
||||
c.master = c
|
||||
if len(s) > 0 {
|
||||
switch s[0] {
|
||||
case nil, c:
|
||||
c.master = s[0]
|
||||
}
|
||||
}
|
||||
return c.master
|
||||
}
|
||||
@ -445,8 +451,8 @@ func (c *Context) Del(arg ...string) { // {{{
|
||||
// }}}
|
||||
|
||||
type Message struct {
|
||||
code int
|
||||
time time.Time
|
||||
code int
|
||||
Hand bool
|
||||
|
||||
Recv chan bool
|
||||
@ -467,7 +473,15 @@ type Message struct {
|
||||
Template *Message
|
||||
}
|
||||
|
||||
func (m *Message) Source() *Context { // {{{
|
||||
func (m *Message) Code() int { // {{{
|
||||
return m.code
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (m *Message) Source(s ...*Context) *Context { // {{{
|
||||
if len(s) > 0 {
|
||||
m.source = s[0]
|
||||
}
|
||||
return m.source
|
||||
}
|
||||
|
||||
@ -931,18 +945,123 @@ func (m *Message) Echo(str string, arg ...interface{}) *Message { // {{{
|
||||
return m.Add("result", fmt.Sprintf(str, arg...))
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (m *Message) Copy(msg *Message, meta string, arg ...string) *Message { // {{{
|
||||
switch meta {
|
||||
case "detail", "result":
|
||||
m.Meta[meta] = append(m.Meta[meta][:0], msg.Meta[meta]...)
|
||||
case "option", "append":
|
||||
if len(arg) == 0 {
|
||||
arg = msg.Meta[meta]
|
||||
}
|
||||
|
||||
for _, k := range arg {
|
||||
if v, ok := msg.Meta[k]; ok {
|
||||
m.Set(meta, k).Add(meta, k, v...)
|
||||
}
|
||||
if v, ok := msg.Data[k]; ok {
|
||||
m.Put(meta, k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
func (m *Message) Insert(meta string, index int, arg ...interface{}) string { // {{{
|
||||
if m.Meta == nil {
|
||||
m.Meta = make(map[string][]string)
|
||||
}
|
||||
|
||||
str := []string{}
|
||||
for _, v := range arg {
|
||||
switch s := v.(type) {
|
||||
case string:
|
||||
str = append(str, s)
|
||||
case []string:
|
||||
str = append(str, s...)
|
||||
case []int:
|
||||
for _, v := range s {
|
||||
str = append(str, fmt.Sprintf("%d", v))
|
||||
}
|
||||
case []bool:
|
||||
for _, v := range s {
|
||||
str = append(str, fmt.Sprintf("%t", v))
|
||||
}
|
||||
default:
|
||||
str = append(str, fmt.Sprintf("%v", s))
|
||||
}
|
||||
}
|
||||
|
||||
if index == -1 {
|
||||
index, m.Meta[meta] = 0, append(str, m.Meta[meta]...)
|
||||
} else if index == -2 {
|
||||
index, m.Meta[meta] = len(m.Meta[meta]), append(m.Meta[meta], str...)
|
||||
} else {
|
||||
if index < -2 {
|
||||
index += len(m.Meta[meta]) + 2
|
||||
}
|
||||
if index < 0 {
|
||||
index = 0
|
||||
}
|
||||
|
||||
for i := len(m.Meta[meta]); i < index+len(str); i++ {
|
||||
m.Meta[meta] = append(m.Meta[meta], "")
|
||||
}
|
||||
for i := 0; i < len(str); i++ {
|
||||
m.Meta[meta][index+i] = str[i]
|
||||
}
|
||||
}
|
||||
|
||||
return m.Meta[meta][index]
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (m *Message) Detail(index int, arg ...interface{}) string { // {{{
|
||||
return m.Insert("detail", index, arg...)
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (m *Message) Detaili(index int, arg ...int) int { // {{{
|
||||
i, e := strconv.Atoi(m.Insert("detail", index, arg))
|
||||
m.Assert(e)
|
||||
return i
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (m *Message) Details(index int, arg ...bool) bool { // {{{
|
||||
return right(m.Insert("detail", index, arg))
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (m *Message) Result(index int, arg ...interface{}) string { // {{{
|
||||
return m.Insert("result", index, arg...)
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (m *Message) Resulti(index int, arg ...int) int { // {{{
|
||||
i, e := strconv.Atoi(m.Insert("result", index, arg))
|
||||
m.Assert(e)
|
||||
return i
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (m *Message) Results(index int, arg ...bool) bool { // {{{
|
||||
return right(m.Insert("result", index, arg))
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
func (m *Message) Option(key string, arg ...string) string { // {{{
|
||||
if len(arg) > 0 {
|
||||
m.Log("fuck", nil, "option set %s %v", key, arg)
|
||||
m.Set("option", append([]string{key}, arg...)...)
|
||||
}
|
||||
|
||||
for msg := m; msg != nil; msg = msg.message {
|
||||
msg.Log("fuck", nil, "option")
|
||||
if m.Has(key) {
|
||||
return m.Get(key)
|
||||
if msg.Has(key) {
|
||||
return msg.Get(key)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
@ -977,15 +1096,12 @@ func (m *Message) Options(key string, arg ...bool) bool { // {{{
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
func (m *Message) Append(key string, arg ...string) string { // {{{
|
||||
if len(arg) > 0 {
|
||||
m.Log("fuck", nil, "append set %s %v", key, arg)
|
||||
m.Set("append", append([]string{key}, arg...)...)
|
||||
}
|
||||
|
||||
for msg := m; msg != nil; msg = msg.message {
|
||||
msg.Log("fuck", nil, "append")
|
||||
if m.Has(key) {
|
||||
return m.Get(key)
|
||||
}
|
||||
@ -1144,16 +1260,25 @@ func (m *Message) Post(s *Context, async ...bool) string { // {{{
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (m *Message) Cmd(arg ...string) string { // {{{
|
||||
func (m *Message) Cmd(arg ...interface{}) *Message { // {{{
|
||||
if m.Hand {
|
||||
msg := m.Spawn(m.target)
|
||||
msg.source = m.source
|
||||
m = msg
|
||||
}
|
||||
|
||||
if len(arg) > 0 {
|
||||
m.Set("detail", arg...)
|
||||
m.Set("detail")
|
||||
m.Detail(0, arg...)
|
||||
}
|
||||
|
||||
if s := m.target.master; s != nil && s != m.source.master {
|
||||
return m.Post(s)
|
||||
m.Post(s)
|
||||
} else {
|
||||
m.Exec(m.Meta["detail"][0], m.Meta["detail"][1:]...)
|
||||
}
|
||||
|
||||
return m.Exec(m.Meta["detail"][0], m.Meta["detail"][1:]...)
|
||||
return m
|
||||
}
|
||||
|
||||
// }}}
|
||||
@ -1316,11 +1441,14 @@ func (m *Message) Cap(key string, arg ...string) string { // {{{
|
||||
var Pulse = &Message{code: 0, time: time.Now(), Wait: make(chan bool), source: Index, master: Index, target: Index}
|
||||
var Index = &Context{Name: "ctx", Help: "模块中心",
|
||||
Caches: map[string]*Cache{
|
||||
"debug": &Cache{Name: "服务数量", Value: "true", Help: "显示已经启动运行模块的数量"},
|
||||
"nserver": &Cache{Name: "服务数量", Value: "0", Help: "显示已经启动运行模块的数量"},
|
||||
"ncontext": &Cache{Name: "模块数量", Value: "0", Help: "显示功能树已经注册模块的数量"},
|
||||
"nmessage": &Cache{Name: "消息数量", Value: "0", Help: "显示模块启动时所创建消息的数量"},
|
||||
},
|
||||
Configs: map[string]*Config{
|
||||
"debug": &Config{Name: "调试模式(true/false)", Value: "true", Help: "是否打印错误信息,off:不打印,on:打印)"},
|
||||
|
||||
"default": &Config{Name: "默认的搜索起点(root/back/home)", Value: "root", Help: "模块搜索的默认起点,root:从根模块,back:从父模块,home:从当前模块"},
|
||||
|
||||
"start": &Config{Name: "启动模块", Value: "cli", Help: "启动时自动运行的模块"},
|
||||
@ -1364,9 +1492,8 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
|
||||
"ContextSessionSize": &Config{Name: "会话队列长度", Value: "10", Help: "每个模块可以启动其它模块的数量"},
|
||||
"MessageQueueSize": &Config{Name: "消息队列长度", Value: "10", Help: "每个模块接收消息的队列长度"},
|
||||
|
||||
"debug": &Config{Name: "调试模式(true/false)", Value: "false", Help: "是否打印错误信息,off:不打印,on:打印)"},
|
||||
"cert": &Config{Name: "证书文件", Value: "etc/cert.pem", Help: "证书文件"},
|
||||
"key": &Config{Name: "私钥文件", Value: "etc/key.pem", Help: "私钥文件"},
|
||||
"cert": &Config{Name: "证书文件", Value: "etc/cert.pem", Help: "证书文件"},
|
||||
"key": &Config{Name: "私钥文件", Value: "etc/key.pem", Help: "私钥文件"},
|
||||
},
|
||||
Commands: map[string]*Command{
|
||||
"userinfo": &Command{Name: "userinfo [add|del [context key name help]|[command|config|cache group name]]", Help: "查看模块的用户信息",
|
||||
@ -1494,6 +1621,16 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
|
||||
|
||||
// }}}
|
||||
}},
|
||||
"detail": &Command{Name: "detail index val...", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) {
|
||||
msg := m.Spawn(m.Target())
|
||||
|
||||
msg.Detail(1, "nie", 1, []string{"123", "123"}, true, []bool{false, true}, []int{1, 2, 2})
|
||||
|
||||
m.Echo("%v", msg.Meta)
|
||||
msg.Detail(2, "nie")
|
||||
m.Echo("%v", msg.Meta)
|
||||
|
||||
}},
|
||||
"option": &Command{Name: "option key val...", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) {
|
||||
if len(arg) > 0 { // {{{
|
||||
m.Option(arg[0], arg[1:]...)
|
||||
@ -1623,7 +1760,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
|
||||
})
|
||||
case len(arg) > 0 && v != m:
|
||||
v.Meta = m.Meta
|
||||
v.Cmd(arg...)
|
||||
v.Cmd(arg)
|
||||
m.Meta = v.Meta
|
||||
default:
|
||||
m.target = v.target
|
||||
@ -1881,7 +2018,7 @@ func Start(args ...string) {
|
||||
log.Println()
|
||||
|
||||
for _, m := range Pulse.Search(Pulse.Conf("start")) {
|
||||
m.Set("option", "stdio").target.Start(m)
|
||||
m.Set("detail", Pulse.Conf("init.shy")).Set("option", "stdio").target.Start(m)
|
||||
}
|
||||
|
||||
<-Index.master.Exit
|
||||
|
@ -1,31 +1,32 @@
|
||||
package lex // {{{
|
||||
// }}}
|
||||
import ( // {{{
|
||||
package lex
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// }}}
|
||||
|
||||
type Seed struct { // {{{
|
||||
type Seed struct {
|
||||
page int
|
||||
hash int
|
||||
word string
|
||||
}
|
||||
|
||||
// }}}
|
||||
type State struct { // {{{
|
||||
type State struct {
|
||||
star bool
|
||||
next int
|
||||
hash int
|
||||
}
|
||||
type Point struct {
|
||||
s int
|
||||
c byte
|
||||
}
|
||||
|
||||
// }}}
|
||||
type LEX struct { // {{{
|
||||
type LEX struct {
|
||||
seed []*Seed
|
||||
|
||||
page map[string]int
|
||||
hash map[string]int
|
||||
char map[byte][]byte
|
||||
|
||||
state map[State]*State
|
||||
mat []map[byte]*State
|
||||
@ -34,9 +35,7 @@ type LEX struct { // {{{
|
||||
*ctx.Context
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
func (lex *LEX) index(hash string, h string) int { // {{{
|
||||
func (lex *LEX) index(hash string, h string) int {
|
||||
if x, e := strconv.Atoi(h); e == nil {
|
||||
return x
|
||||
}
|
||||
@ -53,42 +52,31 @@ func (lex *LEX) index(hash string, h string) int { // {{{
|
||||
return x
|
||||
}
|
||||
|
||||
x := lex.Capi(hash, 1)
|
||||
which[h] = x
|
||||
return x
|
||||
which[h] = lex.Capi(hash, 1)
|
||||
return which[h]
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (lex *LEX) charset(c byte) []byte { // {{{
|
||||
switch c {
|
||||
case 't':
|
||||
return []byte{'\t'}
|
||||
case 'n':
|
||||
return []byte{'\n'}
|
||||
case 's':
|
||||
return []byte{'\t', ' ', '\n'}
|
||||
case 'd':
|
||||
return []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
|
||||
case 'x':
|
||||
return []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F'}
|
||||
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 {
|
||||
|
||||
cn := make([]bool, lex.Capi("ncell"))
|
||||
c := make([]byte, 0, lex.Capi("ncell"))
|
||||
sn := make([]bool, lex.Capi("nline"))
|
||||
s := []int{page}
|
||||
|
||||
ends := []*State{}
|
||||
points := []*Point{}
|
||||
|
||||
for p, set := 0, true; p < len(seed); p++ {
|
||||
for p := 0; p < len(seed); p++ {
|
||||
|
||||
switch seed[p] {
|
||||
case '[':
|
||||
set := true
|
||||
if p++; seed[p] == '^' {
|
||||
set, p = false, p+1
|
||||
}
|
||||
@ -152,56 +140,38 @@ func (lex *LEX) train(page int, hash int, seed []byte) int { // {{{
|
||||
|
||||
for i := 0; i < len(s); i++ {
|
||||
for line, j := 0, byte(0); int(j) < len(c); j++ {
|
||||
state := lex.mat[s[i]][c[j]]
|
||||
lex.Log("debug", nil, "GET(%d,%d): %v", s[i], c[j], state)
|
||||
if state == nil {
|
||||
state = &State{}
|
||||
|
||||
state := &State{}
|
||||
if lex.mat[s[i]][c[j]] != nil {
|
||||
*state = *lex.mat[s[i]][c[j]]
|
||||
} else {
|
||||
lex.Capi("nnode", 1)
|
||||
}
|
||||
lex.Log("debug", nil, "GET(%d,%d): %v", s[i], c[j], state)
|
||||
|
||||
switch flag {
|
||||
case '+':
|
||||
state.star = true
|
||||
case '*':
|
||||
state.star = true
|
||||
fallthrough
|
||||
sn[s[i]] = true
|
||||
case '?':
|
||||
if sn[s[i]] = true; p == len(seed)-1 {
|
||||
for _, n := range ends {
|
||||
if n.next == s[i] {
|
||||
lex.Log("debug", nil, "GET() state:%v", n)
|
||||
n.hash = hash
|
||||
lex.Log("debug", nil, "END() state:%v", n)
|
||||
}
|
||||
}
|
||||
}
|
||||
sn[s[i]] = true
|
||||
}
|
||||
|
||||
if p == len(seed)-1 {
|
||||
state.hash = hash
|
||||
} else {
|
||||
if state.next == 0 {
|
||||
if line == 0 || !lex.Caps("compact") {
|
||||
lex.mat = append(lex.mat, make(map[byte]*State))
|
||||
line = lex.Capi("nline", 1) - 1
|
||||
sn = append(sn, false)
|
||||
}
|
||||
state.next = line
|
||||
if state.next == 0 {
|
||||
if line == 0 || !lex.Caps("compact") {
|
||||
lex.mat = append(lex.mat, make(map[byte]*State))
|
||||
line = lex.Capi("nline", 1) - 1
|
||||
sn = append(sn, false)
|
||||
}
|
||||
sn[state.next] = true
|
||||
}
|
||||
|
||||
if s, ok := lex.state[*state]; !ok {
|
||||
lex.state[*state] = state
|
||||
lex.Capi("nreal", 1)
|
||||
} else {
|
||||
state = s
|
||||
state.next = line
|
||||
}
|
||||
sn[state.next] = true
|
||||
|
||||
lex.mat[s[i]][c[j]] = state
|
||||
|
||||
points = append(points, &Point{s[i], c[j]})
|
||||
lex.Log("debug", nil, "SET(%d,%d): %v(%s,%s)", s[i], c[j], state, lex.Cap("nnode"), lex.Cap("nreal"))
|
||||
ends = append(ends, state)
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,14 +183,50 @@ func (lex *LEX) train(page int, hash int, seed []byte) int { // {{{
|
||||
sn[i] = false
|
||||
}
|
||||
}
|
||||
|
||||
for _, n := range s {
|
||||
if n < lex.Capi("nlang") || n >= len(lex.mat) {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(lex.mat[n]) == 0 {
|
||||
lex.Log("debug", nil, "DEL: %d %d", lex.Capi("nline")-1, lex.Capi("nline", 0, n))
|
||||
lex.mat = lex.mat[:n]
|
||||
}
|
||||
}
|
||||
|
||||
for _, n := range s {
|
||||
for _, p := range points {
|
||||
state := &State{}
|
||||
*state = *lex.mat[p.s][p.c]
|
||||
|
||||
if state.next == n {
|
||||
lex.Log("debug", nil, "GET(%d, %d): %v", p.s, p.c, state)
|
||||
if state.next >= len(lex.mat) {
|
||||
state.next = 0
|
||||
}
|
||||
if hash > 0 {
|
||||
state.hash = hash
|
||||
}
|
||||
lex.Log("debug", nil, "SET(%d, %d): %v", p.s, p.c, state)
|
||||
}
|
||||
|
||||
if x, ok := lex.state[*state]; ok {
|
||||
lex.mat[p.s][p.c] = x
|
||||
} else {
|
||||
lex.state[*state] = state
|
||||
lex.mat[p.s][p.c] = state
|
||||
lex.Capi("nreal", 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hash
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (lex *LEX) parse(page int, line []byte) (hash int, word []byte, rest []byte) { // {{{
|
||||
func (lex *LEX) parse(page int, line []byte) (hash int, word []byte, rest []byte) {
|
||||
|
||||
pos := 0
|
||||
|
||||
for star, s := 0, page; s != 0 && pos < len(line); pos++ {
|
||||
|
||||
c := line[pos]
|
||||
@ -262,9 +268,7 @@ func (lex *LEX) parse(page int, line []byte) (hash int, word []byte, rest []byte
|
||||
return
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
func (lex *LEX) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{
|
||||
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{}
|
||||
|
||||
@ -273,30 +277,33 @@ 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.Context == Index {
|
||||
Pulse = m
|
||||
}
|
||||
lex.Context.Master(nil)
|
||||
lex.Message = m
|
||||
|
||||
lex.Caches["ncell"] = &ctx.Cache{Name: "字符上限", Value: "128", Help: "字符上限"}
|
||||
lex.Caches["nlang"] = &ctx.Cache{Name: "集合上限", Value: "16", Help: "集合上限"}
|
||||
lex.Caches["nlang"] = &ctx.Cache{Name: "集合上限", Value: "32", Help: "集合上限"}
|
||||
|
||||
lex.Caches["nseed"] = &ctx.Cache{Name: "种子数量", Value: "0", Help: "种子数量"}
|
||||
lex.Caches["npage"] = &ctx.Cache{Name: "集合数量", Value: "0", Help: "集合数量"}
|
||||
lex.Caches["nhash"] = &ctx.Cache{Name: "类型数量", Value: "0", Help: "类型数量"}
|
||||
|
||||
lex.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: "16", Help: "状态数量"}
|
||||
lex.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: "32", Help: "状态数量"}
|
||||
lex.Caches["nnode"] = &ctx.Cache{Name: "节点数量", Value: "0", Help: "节点数量"}
|
||||
lex.Caches["nreal"] = &ctx.Cache{Name: "实点数量", Value: "0", Help: "实点数量"}
|
||||
|
||||
lex.Caches["compact"] = &ctx.Cache{Name: "紧凑模式", Value: "true", Help: "实点数量"}
|
||||
lex.Caches["debug"] = &ctx.Cache{Name: "调试模式", Value: "false", Help: "调试模式"}
|
||||
|
||||
lex.Caps("debug", false)
|
||||
lex.Confs("debug", false)
|
||||
return lex
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (lex *LEX) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||
func (lex *LEX) Start(m *ctx.Message, arg ...string) bool {
|
||||
lex.Context.Master(nil)
|
||||
lex.Message = m
|
||||
|
||||
lex.seed = make([]*Seed, 0, 9)
|
||||
@ -308,8 +315,7 @@ func (lex *LEX) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||
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():
|
||||
@ -317,18 +323,17 @@ 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])
|
||||
m.Assert(page < m.Capi("nlang"), "词法集合过多")
|
||||
}
|
||||
if len(arg) > 1 {
|
||||
hash = lex.index("nhash", arg[1])
|
||||
@ -338,26 +343,24 @@ var Index = &ctx.Context{Name: "lex", Help: "词法中心",
|
||||
lex.mat[page] = map[byte]*State{}
|
||||
}
|
||||
|
||||
lex.seed = append(lex.seed, &Seed{page, hash, string(arg[0])})
|
||||
lex.Log("debug", nil, "%d %d %d %v", page, hash, lex.Capi("nseed", 1), arg[0])
|
||||
lex.Cap("stream", fmt.Sprintf("%s,%s,%s", lex.Cap("nseed"), lex.Cap("npage"), lex.Cap("nhash")))
|
||||
|
||||
m.Echo("%d", lex.train(page, hash, []byte(arg[0])))
|
||||
} // }}}
|
||||
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])
|
||||
}
|
||||
|
||||
hash, word, rest := lex.parse(page, []byte(arg[0]))
|
||||
m.Add("result", fmt.Sprintf("%d", hash), string(word), string(rest))
|
||||
} // }}}
|
||||
m.Result(0, hash, string(word), 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])
|
||||
@ -378,10 +381,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)
|
||||
}
|
||||
@ -399,7 +402,32 @@ 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) {
|
||||
set := map[*State]bool{}
|
||||
nreal := 0
|
||||
for _, v := range lex.state {
|
||||
nreal++
|
||||
set[v] = true
|
||||
}
|
||||
|
||||
nnode := 0
|
||||
for i, v := range lex.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)
|
||||
}
|
||||
}},
|
||||
},
|
||||
}
|
||||
@ -408,4 +436,13 @@ func init() {
|
||||
lex := &LEX{}
|
||||
lex.Context = Index
|
||||
ctx.Index.Register(Index, lex)
|
||||
|
||||
lex.char = map[byte][]byte{
|
||||
't': []byte{'\t'},
|
||||
'n': []byte{'\n'},
|
||||
'b': []byte{'\t', ' '},
|
||||
's': []byte{'\t', ' ', '\n'},
|
||||
'd': []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'},
|
||||
'x': []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F'},
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package nfs
|
||||
|
||||
import (
|
||||
package nfs // {{{
|
||||
// }}}
|
||||
import ( // {{{
|
||||
"context"
|
||||
|
||||
"bufio"
|
||||
@ -12,13 +12,16 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// }}}
|
||||
|
||||
type NFS struct {
|
||||
in *os.File
|
||||
out *os.File
|
||||
buf []string
|
||||
*ctx.Context
|
||||
}
|
||||
|
||||
func (nfs *NFS) print(str string, arg ...interface{}) bool {
|
||||
func (nfs *NFS) print(str string, arg ...interface{}) bool { // {{{
|
||||
if nfs.out == nil {
|
||||
return false
|
||||
}
|
||||
@ -27,17 +30,23 @@ func (nfs *NFS) print(str string, arg ...interface{}) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
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: "读写位置"},
|
||||
"pos": &ctx.Cache{Name: "读写位置", Value: "0", Help: "读写位置"},
|
||||
"nline": &ctx.Cache{Name: "缓存命令行数", Value: "0", Help: "缓存命令行数"},
|
||||
"return": &ctx.Cache{Name: "缓存命令行数", Value: "0", Help: "缓存命令行数"},
|
||||
}
|
||||
c.Configs = map[string]*ctx.Config{}
|
||||
|
||||
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: "创建时间"}
|
||||
}
|
||||
}
|
||||
|
||||
s := new(NFS)
|
||||
@ -46,13 +55,15 @@ 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 {
|
||||
func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
||||
nfs.Context.Master(nil)
|
||||
if nfs.Context == Index {
|
||||
Pulse = m
|
||||
}
|
||||
return nfs
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
|
||||
if out, ok := m.Data["out"]; ok {
|
||||
nfs.out = out.(*os.File)
|
||||
@ -60,34 +71,75 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
|
||||
if in, ok := m.Data["in"]; ok {
|
||||
nfs.in = in.(*os.File)
|
||||
}
|
||||
|
||||
m.Log("info", nil, "%d %v", Pulse.Capi("nfile"), arg)
|
||||
if m.Cap("stream", arg[1]); arg[0] == "open" {
|
||||
return false
|
||||
if len(arg) > 1 {
|
||||
if m.Cap("stream", arg[1]); arg[0] == "open" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
cli := m.Reply()
|
||||
cli.Conf("yac", "yac")
|
||||
yac := m.Find(cli.Conf("yac"))
|
||||
bio := bufio.NewScanner(nfs.in)
|
||||
nfs.Context.Master(nil)
|
||||
pos := 0
|
||||
|
||||
if buf, ok := m.Data["buf"]; ok {
|
||||
nfs.buf = buf.([]string)
|
||||
m.Capi("nline", len(nfs.buf))
|
||||
goto out
|
||||
}
|
||||
|
||||
if len(arg) > 2 {
|
||||
nfs.print("%v\n", arg[2])
|
||||
}
|
||||
nfs.print("%s", cli.Conf("PS1"))
|
||||
|
||||
for bio.Scan() {
|
||||
line := m
|
||||
if yac != nil {
|
||||
// line = cli.Spawn(yac.Target())
|
||||
line = m.Spawn(yac.Target())
|
||||
} else {
|
||||
line = m.Reply()
|
||||
}
|
||||
line.Cmd(append([]string{"parse", "line", "void"}, strings.Split(bio.Text()+" \n", " ")...)...)
|
||||
for rest, text := "", ""; pos < m.Capi("nline") || bio.Scan(); {
|
||||
if pos == m.Capi("nline") {
|
||||
if text = bio.Text(); len(text) > 0 && text[len(text)-1] == '\\' {
|
||||
rest += text[:len(text)-1]
|
||||
continue
|
||||
}
|
||||
|
||||
if result := strings.TrimRight(strings.Join(line.Meta["result"], ""), "\n"); len(result) > 0 {
|
||||
nfs.print("%s", result+"\n")
|
||||
if text, rest = rest+text, ""; len(text) == 0 && len(nfs.buf) > 0 && nfs.in == os.Stdin {
|
||||
pos--
|
||||
} else {
|
||||
nfs.buf = append(nfs.buf, text)
|
||||
m.Capi("nline", 1)
|
||||
}
|
||||
}
|
||||
|
||||
for ; pos < m.Capi("nline"); pos++ {
|
||||
|
||||
for text = nfs.buf[pos] + "\n"; text != ""; {
|
||||
line := m.Spawn(yac.Target())
|
||||
line.Optioni("pos", pos)
|
||||
line.Put("option", "cli", cli.Target())
|
||||
text = line.Cmd("parse", "line", "void", text).Get("result")
|
||||
cli.Target(line.Data["cli"].(*ctx.Context))
|
||||
if line.Has("return") {
|
||||
goto out
|
||||
}
|
||||
if line.Has("back") {
|
||||
pos = line.Appendi("back")
|
||||
}
|
||||
|
||||
if result := strings.TrimRight(strings.Join(line.Meta["result"][1:len(line.Meta["result"])-1], ""), "\n"); len(result) > 0 {
|
||||
nfs.print("%s", result+"\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nfs.print("%s", cli.Conf("PS1"))
|
||||
}
|
||||
return true
|
||||
|
||||
out:
|
||||
if len(arg) > 1 {
|
||||
cli.Cmd("end")
|
||||
} else {
|
||||
m.Cap("status", "stop")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool {
|
||||
@ -112,105 +164,135 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
||||
"size": &ctx.Config{Name: "size", Value: "1024", Help: "读取文件的默认大小值"},
|
||||
},
|
||||
Commands: map[string]*ctx.Command{
|
||||
"scan": &ctx.Command{Name: "scan file", Help: "扫描文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if arg[0] == "stdio" {
|
||||
m.Put("option", "in", os.Stdin).Put("option", "out", os.Stdout)
|
||||
m.Start("stdio", "扫描文件", m.Meta["detail"]...)
|
||||
} else if f, e := os.Open(arg[0]); m.Assert(e) {
|
||||
m.Put("option", "in", f)
|
||||
m.Start(fmt.Sprintf("file%d", Pulse.Capi("nfile", 1)), "扫描文件", m.Meta["detail"]...)
|
||||
"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 {
|
||||
m.Echo("%d: %s\n", i, v)
|
||||
}
|
||||
} // }}}
|
||||
}},
|
||||
"copy": &ctx.Command{Name: "copy name [begin [end]]", Help: "复制文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && len(nfs.buf) > 0 {
|
||||
begin, end := 0, len(nfs.buf)
|
||||
if len(arg) > 1 {
|
||||
i, e := strconv.Atoi(arg[1])
|
||||
m.Assert(e)
|
||||
begin = i
|
||||
}
|
||||
if len(arg) > 2 {
|
||||
i, e := strconv.Atoi(arg[2])
|
||||
m.Assert(e)
|
||||
end = i
|
||||
}
|
||||
m.Put("option", "buf", nfs.buf[begin:end])
|
||||
m.Start(arg[0], "扫描文件", key)
|
||||
}
|
||||
m.Echo(m.Target().Name)
|
||||
}},
|
||||
"scan": &ctx.Command{Name: "scan file", Help: "扫描文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if arg[0] == "stdio" { // {{{
|
||||
m.Put("option", "in", os.Stdin).Put("option", "out", os.Stdout).Start("stdio", "扫描文件", m.Meta["detail"]...)
|
||||
} else if f, e := os.Open(arg[0]); m.Assert(e) {
|
||||
m.Put("option", "in", f).Start(fmt.Sprintf("file%d", Pulse.Capi("nfile", 1)), "扫描文件", m.Meta["detail"]...)
|
||||
}
|
||||
// }}}
|
||||
}},
|
||||
"print": &ctx.Command{Name: "print str", 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.out != nil { // {{{
|
||||
fmt.Fprintf(nfs.out, "%s\n", arg[0])
|
||||
}
|
||||
// }}}
|
||||
}},
|
||||
"open": &ctx.Command{Name: "open file", Help: "打开文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
if f, e := os.OpenFile(arg[0], os.O_RDWR|os.O_CREATE, os.ModePerm); m.Assert(e) {
|
||||
if f, e := os.OpenFile(arg[0], os.O_RDWR|os.O_CREATE, os.ModePerm); m.Assert(e) { // {{{
|
||||
m.Put("option", "in", f).Put("option", "out", f)
|
||||
m.Start(fmt.Sprintf("file%d", Pulse.Capi("nfile", 1)), "打开文件", m.Meta["detail"]...)
|
||||
}
|
||||
m.Echo(m.Target().Name)
|
||||
m.Echo(m.Target().Name)
|
||||
} // }}}
|
||||
}},
|
||||
"read": &ctx.Command{Name: "read [size [pos]]", Help: "读取文件, size: 读取大小, pos: 读取位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
nfs, ok := m.Target().Server.(*NFS)
|
||||
m.Assert(ok)
|
||||
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.in != nil { // {{{
|
||||
var e error
|
||||
n := m.Confi("size")
|
||||
if len(arg) > 0 {
|
||||
n, e = strconv.Atoi(arg[0])
|
||||
m.Assert(e)
|
||||
}
|
||||
if len(arg) > 1 {
|
||||
m.Cap("pos", arg[1])
|
||||
}
|
||||
|
||||
var e error
|
||||
n := m.Confi("size")
|
||||
if len(arg) > 0 {
|
||||
n, e = strconv.Atoi(arg[0])
|
||||
m.Assert(e)
|
||||
}
|
||||
if len(arg) > 1 {
|
||||
m.Cap("pos", arg[1])
|
||||
}
|
||||
buf := make([]byte, n)
|
||||
if n, e = nfs.in.ReadAt(buf, int64(m.Capi("pos"))); e != io.EOF {
|
||||
m.Assert(e)
|
||||
}
|
||||
m.Echo(string(buf))
|
||||
|
||||
buf := make([]byte, n)
|
||||
if n, e = nfs.in.ReadAt(buf, int64(m.Capi("pos"))); e != io.EOF {
|
||||
m.Assert(e)
|
||||
}
|
||||
m.Echo(string(buf))
|
||||
|
||||
if m.Capi("pos", n); m.Capi("pos") == m.Capi("size") {
|
||||
m.Cap("pos", "0")
|
||||
}
|
||||
if m.Capi("pos", n); m.Capi("pos") == m.Capi("size") {
|
||||
m.Cap("pos", "0")
|
||||
}
|
||||
} // }}}
|
||||
}},
|
||||
"write": &ctx.Command{Name: "write string [pos]", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
nfs, ok := m.Target().Server.(*NFS)
|
||||
if m.Assert(ok); len(arg) > 1 {
|
||||
m.Cap("pos", arg[1])
|
||||
}
|
||||
|
||||
if len(arg[0]) == 0 {
|
||||
m.Assert(nfs.in.Truncate(int64(m.Capi("pos"))))
|
||||
m.Cap("size", m.Cap("pos"))
|
||||
m.Cap("pos", "0")
|
||||
} else {
|
||||
n, e := nfs.in.WriteAt([]byte(arg[0]), int64(m.Capi("pos")))
|
||||
if m.Assert(e) && m.Capi("pos", n) > m.Capi("size") {
|
||||
m.Cap("size", m.Cap("pos"))
|
||||
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil { // {{{
|
||||
if len(arg) > 1 {
|
||||
m.Cap("pos", arg[1])
|
||||
}
|
||||
}
|
||||
|
||||
m.Echo(m.Cap("pos"))
|
||||
if len(arg[0]) == 0 {
|
||||
m.Assert(nfs.out.Truncate(int64(m.Capi("pos"))))
|
||||
m.Cap("size", m.Cap("pos"))
|
||||
m.Cap("pos", "0")
|
||||
} else {
|
||||
n, e := nfs.out.WriteAt([]byte(arg[0]), int64(m.Capi("pos")))
|
||||
if m.Assert(e) && m.Capi("pos", n) > m.Capi("size") {
|
||||
m.Cap("size", m.Cap("pos"))
|
||||
}
|
||||
}
|
||||
|
||||
m.Echo(m.Cap("pos"))
|
||||
} // }}}
|
||||
}},
|
||||
"load": &ctx.Command{Name: "load file [size]", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
f, e := os.Open(arg[0])
|
||||
if e != nil {
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
if f, e := os.Open(arg[0]); m.Assert(e) { // {{{
|
||||
defer f.Close()
|
||||
|
||||
m.Meta = nil
|
||||
size := 1024
|
||||
if len(arg) > 1 {
|
||||
if s, e := strconv.Atoi(arg[1]); e == nil {
|
||||
size = s
|
||||
m.Meta = nil
|
||||
size := 1024
|
||||
if len(arg) > 1 {
|
||||
if s, e := strconv.Atoi(arg[1]); m.Assert(e) {
|
||||
size = s
|
||||
}
|
||||
}
|
||||
}
|
||||
buf := make([]byte, size)
|
||||
l, e := f.Read(buf)
|
||||
m.Echo(string(buf[:l]))
|
||||
m.Log("info", nil, "read %d", l)
|
||||
buf := make([]byte, size)
|
||||
|
||||
if l, e := f.Read(buf); m.Assert(e) {
|
||||
m.Log("info", nil, "read %d", l)
|
||||
m.Echo(string(buf[:l]))
|
||||
}
|
||||
} // }}}
|
||||
}},
|
||||
"save": &ctx.Command{Name: "save file string...", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
f, e := os.Create(arg[0])
|
||||
m.Assert(e)
|
||||
defer f.Close()
|
||||
fmt.Fprint(f, strings.Join(arg[1:], ""))
|
||||
if f, e := os.Create(arg[0]); m.Assert(e) { // {{{
|
||||
defer f.Close()
|
||||
|
||||
fmt.Fprint(f, strings.Join(arg[1:], ""))
|
||||
} // }}}
|
||||
}},
|
||||
"genqr": &ctx.Command{Name: "genqr [size] file string...", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
size := 256
|
||||
size := 256 // {{{
|
||||
if len(arg) > 2 {
|
||||
if s, e := strconv.Atoi(arg[0]); e == nil {
|
||||
arg = arg[1:]
|
||||
size = s
|
||||
}
|
||||
}
|
||||
qrcode.WriteFile(strings.Join(arg[1:], ""), qrcode.Medium, size, arg[0])
|
||||
qrcode.WriteFile(strings.Join(arg[1:], ""), qrcode.Medium, size, arg[0]) // }}}
|
||||
}},
|
||||
},
|
||||
Index: map[string]*ctx.Context{
|
||||
"void": &ctx.Context{Name: "void",
|
||||
Commands: map[string]*ctx.Command{
|
||||
"scan": &ctx.Command{},
|
||||
"open": &ctx.Command{},
|
||||
"save": &ctx.Command{},
|
||||
"load": &ctx.Command{},
|
||||
|
@ -59,7 +59,7 @@ func (ssh *SSH) Start(m *ctx.Message, arg ...string) bool {
|
||||
if msg.Log("info", nil, "remote: %v", msg.Meta["option"]); msg.Has("detail") {
|
||||
msg.Log("info", nil, "%d exec: %v", m.Capi("nrecv", 1), msg.Meta["detail"])
|
||||
|
||||
msg.Cmd(msg.Meta["detail"]...)
|
||||
msg.Cmd(msg.Meta["detail"])
|
||||
target = msg.Target()
|
||||
m.Cap("target", target.Name)
|
||||
|
||||
@ -113,10 +113,10 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
||||
Configs: map[string]*ctx.Config{},
|
||||
Commands: map[string]*ctx.Command{
|
||||
"listen": &ctx.Command{Name: "listen address protocol", Help: "监听连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
m.Find("tcp").Cmd(m.Meta["detail"]...)
|
||||
m.Find("tcp").Cmd(m.Meta["detail"])
|
||||
}},
|
||||
"dial": &ctx.Command{Name: "dial address protocol", Help: "建立连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
m.Find("tcp").Cmd(m.Meta["detail"]...)
|
||||
m.Find("tcp").Cmd(m.Meta["detail"])
|
||||
}},
|
||||
"open": &ctx.Command{Name: "open", Help: "打开连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||
m.Start(fmt.Sprintf("host%d", Pulse.Capi("nhost", 1)), "主机连接")
|
||||
|
@ -240,7 +240,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
||||
if line = strings.TrimSpace(line); line != "" {
|
||||
lex.Cmd("split", line, "void")
|
||||
cli.Wait = make(chan bool)
|
||||
cli.Cmd(lex.Meta["result"]...)
|
||||
cli.Cmd(lex.Meta["result"])
|
||||
m.Meta["result"] = cli.Meta["result"]
|
||||
}
|
||||
|
||||
|
@ -1,29 +1,29 @@
|
||||
package yac // {{{
|
||||
// }}}
|
||||
import ( // {{{
|
||||
package yac
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// }}}
|
||||
|
||||
type Seed struct { // {{{
|
||||
type Seed struct {
|
||||
page int
|
||||
hash int
|
||||
word []string
|
||||
}
|
||||
|
||||
// }}}
|
||||
type State struct { // {{{
|
||||
star int
|
||||
type State struct {
|
||||
next int
|
||||
star int
|
||||
hash int
|
||||
}
|
||||
type Point struct {
|
||||
s int
|
||||
c byte
|
||||
}
|
||||
|
||||
// }}}
|
||||
type YAC struct { // {{{
|
||||
type YAC struct {
|
||||
seed []*Seed
|
||||
|
||||
page map[string]int
|
||||
word map[int]string
|
||||
hash map[string]int
|
||||
@ -37,122 +37,100 @@ type YAC struct { // {{{
|
||||
*ctx.Context
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
func (yac *YAC) train(page, hash int, word []string) ([]*State, int) { // {{{
|
||||
|
||||
if yac.mat[page] == nil {
|
||||
yac.mat[page] = map[byte]*State{}
|
||||
for i := 0; i < yac.Capi("nlang"); i++ {
|
||||
yac.mat[page][byte(i)] = nil
|
||||
}
|
||||
func (yac *YAC) name(page int) string {
|
||||
name, ok := yac.word[page]
|
||||
if !ok {
|
||||
name = fmt.Sprintf("yac%d", page)
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func (yac *YAC) train(page, hash int, word []string) (int, []*Point, []*Point) {
|
||||
sn := make([]bool, yac.Capi("nline"))
|
||||
ss := []int{page}
|
||||
|
||||
begin := page
|
||||
point := []*State{}
|
||||
ends := []*State{}
|
||||
state := []*State{}
|
||||
mul := false
|
||||
skip := len(word)
|
||||
points := []*Point{}
|
||||
ends := []*Point{}
|
||||
|
||||
for i, n := 0, 1; i < len(word); i += n {
|
||||
if !mul {
|
||||
for i, n, m := 0, 1, false; i < len(word); i += n {
|
||||
if !m {
|
||||
if hash <= 0 && word[i] == "}" {
|
||||
if skip = i + 2; hash == -1 {
|
||||
hash = 0
|
||||
break
|
||||
}
|
||||
return ends, skip
|
||||
} else {
|
||||
ends = ends[:0]
|
||||
return i + 2, points, ends
|
||||
}
|
||||
ends = ends[:0]
|
||||
}
|
||||
|
||||
for _, s := range ss {
|
||||
switch word[i] {
|
||||
case "opt{":
|
||||
case "opt{", "rep{":
|
||||
sn[s] = true
|
||||
state, n = yac.train(s, 0, word[i+1:])
|
||||
for _, x := range state {
|
||||
for i := len(sn); i <= x.next; i++ {
|
||||
num, point, end := yac.train(s, 0, word[i+1:])
|
||||
n, points = num, append(points, point...)
|
||||
for _, x := range end {
|
||||
state := &State{}
|
||||
*state = *yac.mat[x.s][x.c]
|
||||
for i := len(sn); i <= state.next; i++ {
|
||||
sn = append(sn, false)
|
||||
}
|
||||
sn[x.next] = true
|
||||
point = append(point, x)
|
||||
}
|
||||
case "rep{":
|
||||
sn[s] = true
|
||||
state, n = yac.train(s, -1, word[i+1:])
|
||||
for _, x := range state {
|
||||
x.star = s
|
||||
sn[x.next] = true
|
||||
point = append(point, x)
|
||||
yac.Pulse.Log("debug", nil, "END: %v", x)
|
||||
sn[state.next] = true
|
||||
points = append(points, x)
|
||||
|
||||
if word[i] == "rep{" {
|
||||
state.star = s
|
||||
yac.mat[x.s][x.c] = state
|
||||
yac.Log("debug", nil, "REP(%d, %d): %v", x.s, x.c, state)
|
||||
}
|
||||
}
|
||||
case "mul{":
|
||||
mul, n = true, 1
|
||||
m, n = true, 1
|
||||
goto next
|
||||
case "}":
|
||||
if mul {
|
||||
mul = false
|
||||
if m {
|
||||
m = false
|
||||
goto next
|
||||
}
|
||||
fallthrough
|
||||
default:
|
||||
c := byte(0)
|
||||
if x, ok := yac.page[word[i]]; !ok {
|
||||
lex := yac.lex.Spawn(yac.lex.Target())
|
||||
lex.Cmd("parse", word[i], fmt.Sprintf("yac%d", s))
|
||||
x, ok := yac.page[word[i]]
|
||||
|
||||
if !ok {
|
||||
lex := yac.lex.Cmd("parse", word[i], yac.name(s))
|
||||
if lex.Gets("result") {
|
||||
x = lex.Geti("result")
|
||||
} else {
|
||||
x = len(yac.mat[s])
|
||||
lex = yac.lex.Spawn(yac.lex.Target())
|
||||
lex.Cmd("train", word[i], fmt.Sprintf("%d", x), fmt.Sprintf("yac%d", s))
|
||||
yac.lex.Cmd("train", word[i], x, yac.name(s))
|
||||
}
|
||||
c = byte(x)
|
||||
} else {
|
||||
c = byte(x)
|
||||
}
|
||||
|
||||
state := yac.mat[s][c]
|
||||
yac.Pulse.Log("debug", nil, "GET(%d, %d): %v", s, c, state)
|
||||
if state == nil {
|
||||
state = &State{}
|
||||
yac.Pulse.Capi("nnode", 1)
|
||||
c := byte(x)
|
||||
state := &State{}
|
||||
if yac.mat[s][c] != nil {
|
||||
*state = *yac.mat[s][c]
|
||||
} else {
|
||||
yac.Capi("nnode", 1)
|
||||
}
|
||||
yac.Log("debug", nil, "GET(%d, %d): %v \033[31m(%s)\033[0m", s, c, state, word[i])
|
||||
|
||||
if state.next == 0 {
|
||||
state.next = yac.Capi("nline", 1) - 1
|
||||
yac.mat = append(yac.mat, map[byte]*State{})
|
||||
state.next = yac.Pulse.Capi("nline", 1) - 1
|
||||
for i := 0; i < yac.Capi("nlang"); i++ {
|
||||
yac.mat[state.next][byte(i)] = nil
|
||||
}
|
||||
sn = append(sn, false)
|
||||
}
|
||||
sn[state.next] = true
|
||||
|
||||
if x, ok := yac.state[*state]; !ok {
|
||||
yac.Pulse.Capi("nreal", 1)
|
||||
yac.state[*state] = state
|
||||
} else {
|
||||
yac.mat[s][c] = x
|
||||
}
|
||||
yac.mat[s][c] = state
|
||||
|
||||
yac.Pulse.Log("debug", nil, "SET(%d, %d): %v", s, c, state)
|
||||
ends = append(ends, state)
|
||||
point = append(point, state)
|
||||
if s > begin {
|
||||
begin = s
|
||||
}
|
||||
|
||||
ends = append(ends, &Point{s, c})
|
||||
points = append(points, &Point{s, c})
|
||||
yac.Log("debug", nil, "SET(%d, %d): %v", s, c, state)
|
||||
}
|
||||
}
|
||||
|
||||
next:
|
||||
if !mul {
|
||||
if !m {
|
||||
ss = ss[:0]
|
||||
for s, b := range sn {
|
||||
if sn[s] = false; b {
|
||||
@ -163,7 +141,7 @@ func (yac *YAC) train(page, hash int, word []string) ([]*State, int) { // {{{
|
||||
}
|
||||
|
||||
for _, n := range ss {
|
||||
if n < yac.Pulse.Capi("nlang") || n >= len(yac.mat) {
|
||||
if n < yac.Capi("nlang") || n >= len(yac.mat) {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -175,33 +153,41 @@ func (yac *YAC) train(page, hash int, word []string) ([]*State, int) { // {{{
|
||||
}
|
||||
}
|
||||
if void {
|
||||
yac.Pulse.Log("debug", nil, "DEL: %d %d", yac.Pulse.Capi("nline"), n)
|
||||
yac.Pulse.Capi("nline", 0, n)
|
||||
yac.Log("debug", nil, "DEL: %d %d", yac.Capi("nline")-1, yac.Capi("nline", 0, n))
|
||||
yac.mat = yac.mat[:n]
|
||||
}
|
||||
}
|
||||
|
||||
for _, n := range ss {
|
||||
for _, s := range point {
|
||||
if s.next == n {
|
||||
yac.Pulse.Log("debug", nil, "GET: %v", s)
|
||||
if s.next >= len(yac.mat) {
|
||||
s.next = 0
|
||||
for _, p := range points {
|
||||
state := &State{}
|
||||
*state = *yac.mat[p.s][p.c]
|
||||
|
||||
if state.next == n {
|
||||
yac.Log("debug", nil, "GET(%d, %d): %v", p.s, p.c, state)
|
||||
if state.next >= len(yac.mat) {
|
||||
state.next = 0
|
||||
}
|
||||
if hash > 0 {
|
||||
s.hash = hash
|
||||
state.hash = hash
|
||||
}
|
||||
yac.Pulse.Log("debug", nil, "SET: %v", s)
|
||||
yac.Log("debug", nil, "SET(%d, %d): %v", p.s, p.c, state)
|
||||
}
|
||||
|
||||
if x, ok := yac.state[*state]; ok {
|
||||
yac.mat[p.s][p.c] = x
|
||||
} else {
|
||||
yac.state[*state] = state
|
||||
yac.mat[p.s][p.c] = state
|
||||
yac.Capi("nreal", 1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ends, skip
|
||||
return len(word), points, ends
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (yac *YAC) parse(m *ctx.Message, page, void int, line string) ([]string, string) { // {{{
|
||||
func (yac *YAC) parse(m *ctx.Message, cli *ctx.Context, page, void int, line string) (*ctx.Context, string, []string) {
|
||||
|
||||
level := m.Capi("level", 1)
|
||||
m.Log("debug", nil, "%s\\%d %s(%d):", m.Cap("label")[0:level], level, yac.word[page], page)
|
||||
@ -209,35 +195,34 @@ func (yac *YAC) parse(m *ctx.Message, page, void int, line string) ([]string, st
|
||||
hash, word := 0, []string{}
|
||||
for star, s := 0, page; s != 0 && len(line) > 0; {
|
||||
|
||||
lex := yac.lex.Spawn(yac.lex.Target())
|
||||
lex.Cmd("parse", line, fmt.Sprintf("yac%d", void))
|
||||
line = lex.Meta["result"][2]
|
||||
line = yac.lex.Cmd("parse", line, yac.name(void)).Result(2)
|
||||
lex := yac.lex.Cmd("parse", line, yac.name(s))
|
||||
|
||||
lex = yac.lex.Spawn(yac.lex.Target())
|
||||
lex.Cmd("parse", line, fmt.Sprintf("yac%d", s))
|
||||
|
||||
c := byte(lex.Geti("result"))
|
||||
c := byte(lex.Resulti(0))
|
||||
state := yac.mat[s][c]
|
||||
if state == nil {
|
||||
if state != nil {
|
||||
if key := yac.lex.Cmd("parse", line, "key"); key.Resulti(0) == 0 || len(key.Result(1)) <= len(lex.Result(1)) {
|
||||
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(1))
|
||||
line, word = lex.Result(2), append(word, lex.Result(1))
|
||||
} else {
|
||||
state = nil
|
||||
}
|
||||
}
|
||||
|
||||
if state == nil {
|
||||
for i := 0; i < yac.Capi("ncell"); i++ {
|
||||
x := yac.mat[s][byte(i)]
|
||||
if i >= m.Capi("nlang") || x == nil {
|
||||
continue
|
||||
}
|
||||
m.Log("debug", nil, "%s|%d try(%d,%d): %v", m.Cap("label")[0:level], level, s, i, x)
|
||||
if w, l := yac.parse(m, i, void, line); l != line {
|
||||
if c, l, w := yac.parse(m, cli, i, void, line); l != line {
|
||||
m.Log("debug", nil, "%s|%d end(%d,%d): %v", m.Cap("label")[0:level], level, s, i, x)
|
||||
cli, line, state = c, l, x
|
||||
word = append(word, w...)
|
||||
state = x
|
||||
line = l
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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.Meta["result"][1])
|
||||
word = append(word, lex.Meta["result"][1])
|
||||
line = lex.Meta["result"][2]
|
||||
}
|
||||
|
||||
if state == nil {
|
||||
@ -245,8 +230,7 @@ func (yac *YAC) parse(m *ctx.Message, page, void int, line string) ([]string, st
|
||||
continue
|
||||
}
|
||||
|
||||
star, s, hash = state.star, state.next, state.hash
|
||||
if s == 0 {
|
||||
if s, star, hash = state.next, state.star, state.hash; s == 0 {
|
||||
s, star = star, 0
|
||||
}
|
||||
}
|
||||
@ -254,21 +238,24 @@ func (yac *YAC) parse(m *ctx.Message, page, void int, line string) ([]string, st
|
||||
if hash == 0 {
|
||||
word = word[:0]
|
||||
} else {
|
||||
msg := m.Spawn(yac.Message.Source()).Add("detail", yac.hand[hash], word...)
|
||||
if msg.Cmd(); 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"])
|
||||
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)
|
||||
level = m.Capi("level", -1)
|
||||
return word, line
|
||||
m.Capi("level", -1)
|
||||
return cli, line, word
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
func (yac *YAC) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{
|
||||
func (yac *YAC) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
|
||||
c.Caches = map[string]*ctx.Cache{}
|
||||
c.Configs = map[string]*ctx.Config{}
|
||||
|
||||
@ -277,45 +264,47 @@ func (yac *YAC) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
||||
return s
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
||||
yac.Message = m
|
||||
func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||
if yac.Context == Index {
|
||||
Pulse = m
|
||||
}
|
||||
yac.Context.Master(nil)
|
||||
yac.Message = m
|
||||
|
||||
yac.Caches["ncell"] = &ctx.Cache{Name: "单词上限", Value: "128", Help: "单词上限"}
|
||||
yac.Caches["nlang"] = &ctx.Cache{Name: "集合上限", Value: "16", Help: "集合上限"}
|
||||
yac.Caches["ncell"] = &ctx.Cache{Name: "词法上限", Value: "128", Help: "词法集合的最大数量"}
|
||||
yac.Caches["nlang"] = &ctx.Cache{Name: "语法上限", Value: "16", Help: "语法集合的最大数量"}
|
||||
|
||||
yac.Caches["nseed"] = &ctx.Cache{Name: "种子数量", Value: "0", Help: "种子数量"}
|
||||
yac.Caches["npage"] = &ctx.Cache{Name: "集合数量", Value: "0", Help: "集合数量"}
|
||||
yac.Caches["nhash"] = &ctx.Cache{Name: "类型数量", Value: "0", Help: "类型数量"}
|
||||
yac.Caches["nseed"] = &ctx.Cache{Name: "种子数量", Value: "0", Help: "语法模板的数量"}
|
||||
yac.Caches["npage"] = &ctx.Cache{Name: "集合数量", Value: "0", Help: "语法集合的数量"}
|
||||
yac.Caches["nhash"] = &ctx.Cache{Name: "类型数量", Value: "0", Help: "语句类型的数量"}
|
||||
|
||||
yac.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: "16", Help: "状态数量"}
|
||||
yac.Caches["nnode"] = &ctx.Cache{Name: "节点数量", Value: "0", Help: "节点数量"}
|
||||
yac.Caches["nreal"] = &ctx.Cache{Name: "实点数量", Value: "0", Help: "实点数量"}
|
||||
yac.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: "16", Help: "状态机状态的数量"}
|
||||
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: "嵌套层级"}
|
||||
yac.Caches["level"] = &ctx.Cache{Name: "嵌套层级", Value: "0", Help: "语法解析嵌套层级"}
|
||||
yac.Caches["label"] = &ctx.Cache{Name: "嵌套标记", Value: "####################", Help: "嵌套层级日志的标记"}
|
||||
|
||||
yac.Caps("debug", true)
|
||||
yac.Confs("debug", false)
|
||||
|
||||
yac.page = map[string]int{"nil": 0}
|
||||
yac.word = map[int]string{0: "nil"}
|
||||
yac.hash = map[string]int{"nil": 0}
|
||||
yac.hand = map[int]string{0: "nil"}
|
||||
|
||||
yac.mat = make([]map[byte]*State, m.Capi("nlang"))
|
||||
yac.state = map[State]*State{}
|
||||
yac.mat = make([]map[byte]*State, m.Capi("nlang"))
|
||||
return yac
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (yac *YAC) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||
func (yac *YAC) Start(m *ctx.Message, arg ...string) bool {
|
||||
yac.Context.Master(nil)
|
||||
yac.Message = m
|
||||
return false
|
||||
}
|
||||
|
||||
// }}}
|
||||
func (yac *YAC) Close(m *ctx.Message, arg ...string) bool { // {{{
|
||||
func (yac *YAC) Close(m *ctx.Message, arg ...string) bool {
|
||||
switch yac.Context {
|
||||
case m.Target():
|
||||
case m.Source():
|
||||
@ -323,20 +312,24 @@ func (yac *YAC) Close(m *ctx.Message, arg ...string) bool { // {{{
|
||||
return true
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
var Pulse *ctx.Message
|
||||
var Index = &ctx.Context{Name: "yac", Help: "语法中心",
|
||||
Caches: map[string]*ctx.Cache{},
|
||||
Configs: map[string]*ctx.Config{},
|
||||
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) { // {{{
|
||||
if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
|
||||
page, ok := yac.page[arg[0]]
|
||||
if !ok {
|
||||
page = m.Capi("npage", 1)
|
||||
yac.page[arg[0]] = page
|
||||
yac.word[page] = arg[0]
|
||||
|
||||
m.Assert(page < m.Capi("nlang"), "语法集合过多")
|
||||
yac.mat[page] = map[byte]*State{}
|
||||
for i := 0; i < yac.Capi("nlang"); i++ {
|
||||
yac.mat[page][byte(i)] = nil
|
||||
}
|
||||
}
|
||||
|
||||
hash, ok := yac.hash[arg[1]]
|
||||
@ -348,23 +341,80 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
|
||||
|
||||
if yac.lex == nil {
|
||||
lex := m.Find("lex", true)
|
||||
lex.Start("lyacc", "语法词法")
|
||||
if lex.Cap("status") == "start" {
|
||||
lex.Start(yac.Context.Name+"lex", "语法词法")
|
||||
} else {
|
||||
lex.Target().Start(lex)
|
||||
}
|
||||
yac.lex = lex
|
||||
}
|
||||
yac.seed = append(yac.seed, &Seed{page, hash, arg[2:]})
|
||||
yac.Capi("nseed", 1)
|
||||
|
||||
yac.train(page, hash, arg[2:])
|
||||
} // }}}
|
||||
yac.seed = append(yac.seed, &Seed{page, hash, arg[2:]})
|
||||
yac.Cap("stream", fmt.Sprintf("%d,%s,%s", yac.Capi("nseed", 1), yac.Cap("npage"), yac.Cap("nhash")))
|
||||
}
|
||||
}},
|
||||
"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) { // {{{
|
||||
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)
|
||||
word, rest := yac.parse(m, page, void, strings.Join(arg[2:], " "))
|
||||
m.Add("result", rest, word...)
|
||||
} // }}}
|
||||
|
||||
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 {
|
||||
m.Echo("seed: %d %v\n", i, v)
|
||||
}
|
||||
for i, v := range yac.page {
|
||||
m.Echo("page: %s %d\n", i, v)
|
||||
}
|
||||
for i, v := range yac.hash {
|
||||
m.Echo("hash: %s %d\n", i, v)
|
||||
}
|
||||
for i, v := range yac.state {
|
||||
m.Echo("node: %v %v\n", i, v)
|
||||
}
|
||||
for i, v := range yac.mat {
|
||||
for k, v := range v {
|
||||
if v != nil {
|
||||
m.Echo("node: %s(%d,%d): %v\n", yac.name(i), 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 yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
|
||||
set := map[*State]bool{}
|
||||
nreal := 0
|
||||
for _, v := range yac.state {
|
||||
nreal++
|
||||
set[v] = true
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
_ "context/web"
|
||||
|
||||
_ "context/lex"
|
||||
_ "context/log"
|
||||
_ "context/yac"
|
||||
|
||||
"os"
|
||||
|
Loading…
x
Reference in New Issue
Block a user