1
0
forked from x/ContextOS

mac opt lex&yac 优化了词法解析与语法解析

This commit is contained in:
shaoying 2018-01-27 22:38:33 +08:00
parent 9bddeea4cc
commit 78f27e1608
11 changed files with 959 additions and 693 deletions

View File

@ -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
}

View File

@ -1,2 +1,35 @@
~cli
~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"

View File

@ -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 {

View File

@ -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
yac *ctx.Message
type CLI struct {
nfs *ctx.Message
lex *ctx.Message
yac *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 {
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.Caches["init.shy"] = &ctx.Cache{Name: "启动脚本", Value: "etc/init.shy", Help: "模块启动时自动运行的脚本"}
if len(arg) > 0 {
m.Cap("init.shy", arg[0])
}
cli.Context.Exit = make(chan bool)
cli.Context.Master(cli.Context)
if m.Has("stdio") || len(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 {
if m.Conf("yac", "yac"); 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"]
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 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)
}
} // }}}
}},
"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) { // {{{
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.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 out, e := c.CombinedOutput(); e != nil {
msg.Echo("error: ")
msg.Echo("%s\n", e)
} else {
cli.alias[arg[0]] = arg[1:]
m.Echo("%s: %v\n", arg[0], cli.alias[arg[0]])
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"))
}
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())
}
}
cli.bio = nil
} // }}}
}},
"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.Optioni("loop", m.Optioni("pos")-1)
m.Start(fmt.Sprintf("%s%d", key, m.Optioni("level", m.Capi("level")+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)
} // }}}
}},
"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())
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], "循环语句")
}
m.Add("option", "skip").Add("option", "save")
m.Put("option", "file", cli.bio).Start(arg[0], "函数定义")
<-m.Target().Exit
} // }}}
}},
"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
}

View File

@ -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,7 +1492,6 @@ 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: "私钥文件"},
},
@ -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

View File

@ -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,34 +140,25 @@ 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))
@ -189,19 +168,10 @@ func (lex *LEX) train(page int, hash int, seed []byte) int { // {{{
state.next = line
}
sn[state.next] = true
}
if s, ok := lex.state[*state]; !ok {
lex.state[*state] = state
lex.Capi("nreal", 1)
} else {
state = s
}
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'},
}
}

View File

@ -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,18 +30,24 @@ 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: "读写位置"},
"nline": &ctx.Cache{Name: "缓存命令行数", Value: "0", Help: "缓存命令行数"},
"return": &ctx.Cache{Name: "缓存命令行数", Value: "0", 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: "创建时间"}
}
}
s := new(NFS)
s.Context = c
@ -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 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()
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
}
line.Cmd(append([]string{"parse", "line", "void"}, strings.Split(bio.Text()+" \n", " ")...)...)
if result := strings.TrimRight(strings.Join(line.Meta["result"], ""), "\n"); len(result) > 0 {
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,27 +164,53 @@ 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)
}
m.Echo(m.Target().Name)
} // }}}
}},
"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)
}
}},
"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)
} // }}}
}},
"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 {
@ -152,65 +230,69 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
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 {
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil { // {{{
if len(arg) > 1 {
m.Cap("pos", arg[1])
}
if len(arg[0]) == 0 {
m.Assert(nfs.in.Truncate(int64(m.Capi("pos"))))
m.Assert(nfs.out.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")))
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
}
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 {
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]))
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)
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{},

View File

@ -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)), "主机连接")

View File

@ -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"]
}

View File

@ -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 i + 2, points, ends
}
return ends, skip
} else {
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)
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 "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)
}
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.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)
}
yac.Pulse.Log("debug", nil, "SET: %v", s)
}
}
return len(word), points, ends
}
return ends, skip
}
// }}}
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)
}
}},
},
}

View File

@ -12,6 +12,7 @@ import (
_ "context/web"
_ "context/lex"
_ "context/log"
_ "context/yac"
"os"