forked from x/icebergs
add lex.matrix
This commit is contained in:
parent
44fdfc3ce1
commit
922172e7fd
@ -104,18 +104,6 @@ func init() {
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
ROLE: {Name: "role role auto create", Help: "角色", Action: map[string]*ice.Action{
|
||||
BLACK: {Name: "black role chain...", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) {
|
||||
_role_black(m, arg[0], strings.ReplaceAll(kit.Keys(arg[1:]), "/", "."), true)
|
||||
}},
|
||||
WHITE: {Name: "white role chain...", Help: "白名单", Hand: func(m *ice.Message, arg ...string) {
|
||||
_role_white(m, arg[0], strings.ReplaceAll(kit.Keys(arg[1:]), "/", "."), true)
|
||||
}},
|
||||
RIGHT: {Name: "right role chain...", Help: "查看权限", Hand: func(m *ice.Message, arg ...string) {
|
||||
if _role_right(m, arg[0], kit.Split(strings.ReplaceAll(kit.Keys(arg[1:]), "/", "."), ".")...) {
|
||||
m.Echo(ice.OK)
|
||||
}
|
||||
}},
|
||||
|
||||
mdb.CREATE: {Name: "create role=void,tech zone=white,black key=", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Richs(ROLE, nil, m.Option(ROLE), func(key string, value map[string]interface{}) {
|
||||
list := value[m.Option(kit.MDB_ZONE)].(map[string]interface{})
|
||||
@ -130,6 +118,18 @@ func init() {
|
||||
delete(list, m.Option(kit.MDB_KEY))
|
||||
})
|
||||
}},
|
||||
|
||||
BLACK: {Name: "black role chain...", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) {
|
||||
_role_black(m, arg[0], strings.ReplaceAll(kit.Keys(arg[1:]), "/", "."), true)
|
||||
}},
|
||||
WHITE: {Name: "white role chain...", Help: "白名单", Hand: func(m *ice.Message, arg ...string) {
|
||||
_role_white(m, arg[0], strings.ReplaceAll(kit.Keys(arg[1:]), "/", "."), true)
|
||||
}},
|
||||
RIGHT: {Name: "right role chain...", Help: "查看权限", Hand: func(m *ice.Message, arg ...string) {
|
||||
if _role_right(m, arg[0], kit.Split(strings.ReplaceAll(kit.Keys(arg[1:]), "/", "."), ".")...) {
|
||||
m.Echo(ice.OK)
|
||||
}
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) < 2 { // 角色列表
|
||||
_role_list(m, kit.Select("", arg, 0))
|
||||
|
@ -41,6 +41,9 @@ func SessCheck(m *ice.Message, sessid string) {
|
||||
_sess_check(m, sessid)
|
||||
}
|
||||
func SessCreate(m *ice.Message, username string) string {
|
||||
if username == "" {
|
||||
return ""
|
||||
}
|
||||
return m.Option(ice.MSG_SESSID, _sess_create(m, username))
|
||||
}
|
||||
func SessIsCli(m *ice.Message) bool {
|
||||
@ -68,23 +71,21 @@ func init() {
|
||||
Commands: map[string]*ice.Command{
|
||||
SESS: {Name: "sess hash auto prunes", Help: "会话", Action: map[string]*ice.Action{
|
||||
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Option(mdb.FIELDS, "time,username,userrole,ip,ua")
|
||||
m.Option(mdb.FIELDS, "time,hash,username,userrole,ip,ua")
|
||||
m.Cmdy(mdb.DELETE, SESS, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
||||
}},
|
||||
mdb.PRUNES: {Name: "prunes before@date", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
||||
list := []string{}
|
||||
m.Richs(SESS, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
|
||||
m.Option(mdb.FIELDS, "time,hash,username,userrole,ip,ua")
|
||||
m.Cmd(mdb.PRUNES, SESS, "", mdb.HASH, func(key string, value map[string]interface{}) bool {
|
||||
if value = kit.GetMeta(value); kit.Time(kit.Format(value[kit.MDB_TIME])) < kit.Time(m.Option("before")) {
|
||||
list = append(list, key)
|
||||
m.Push(key, value, kit.Split(m.Option(mdb.FIELDS)))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
m.Option(mdb.FIELDS, "time,username,userrole,ip,ua")
|
||||
for _, v := range list {
|
||||
m.Cmdy(mdb.DELETE, SESS, "", mdb.HASH, kit.MDB_HASH, v)
|
||||
}
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Fields(len(arg) == 0, "time,hash,username,userrole")
|
||||
m.Fields(len(arg) == 0, "time,hash,username,userrole,ip")
|
||||
m.Cmdy(mdb.SELECT, SESS, "", mdb.HASH, kit.MDB_HASH, arg)
|
||||
m.PushAction(mdb.REMOVE)
|
||||
}},
|
||||
|
@ -69,7 +69,7 @@ func init() {
|
||||
m.Cmd(mdb.INSERT, TOTP, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME),
|
||||
SECRET, m.Option(SECRET), PERIOD, m.Option(PERIOD), NUMBER, m.Option(NUMBER),
|
||||
)
|
||||
m.ProcessRefresh("1ms")
|
||||
m.ProcessRefresh("30ms")
|
||||
}},
|
||||
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.DELETE, TOTP, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME))
|
||||
|
@ -11,41 +11,7 @@ import (
|
||||
kit "github.com/shylinux/toolkits"
|
||||
)
|
||||
|
||||
func NodeInfo(m *ice.Message, kind, name string) {
|
||||
name = strings.ReplaceAll(name, ".", "_")
|
||||
m.Conf(RUNTIME, kit.Keys(NODE, kit.MDB_TYPE), kind)
|
||||
m.Conf(RUNTIME, kit.Keys(NODE, kit.MDB_NAME), name)
|
||||
ice.Info.NodeName = name
|
||||
ice.Info.NodeType = kind
|
||||
}
|
||||
|
||||
const (
|
||||
MAKE = "make"
|
||||
CONF = "conf"
|
||||
HOST = "host"
|
||||
BOOT = "boot"
|
||||
NODE = "node"
|
||||
)
|
||||
const (
|
||||
HOSTNAME = "hostname"
|
||||
PATHNAME = "pathname"
|
||||
USERNAME = "username"
|
||||
)
|
||||
const (
|
||||
CTX_SELF = "ctx_self"
|
||||
CTX_DEV = "ctx_dev"
|
||||
CTX_SHY = "ctx_shy"
|
||||
CTX_PID = "ctx_pid"
|
||||
CTX_USER = "ctx_user"
|
||||
CTX_SHARE = "ctx_share"
|
||||
CTX_RIVER = "ctx_river"
|
||||
)
|
||||
const CLI = "cli"
|
||||
|
||||
var Index = &ice.Context{Name: CLI, Help: "命令模块",
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Load()
|
||||
func _cli_init(m *ice.Message) {
|
||||
|
||||
// 启动配置
|
||||
for _, k := range []string{CTX_SELF, CTX_DEV, CTX_SHY, CTX_PID, CTX_USER, CTX_SHARE, CTX_RIVER} {
|
||||
@ -98,6 +64,43 @@ var Index = &ice.Context{Name: CLI, Help: "命令模块",
|
||||
kit.Fetch(kit.UnMarshal(kit.Format(ice.Info.Build)), func(key string, value interface{}) {
|
||||
m.Conf(RUNTIME, kit.Keys(MAKE, strings.ToLower(key)), value)
|
||||
})
|
||||
}
|
||||
func NodeInfo(m *ice.Message, kind, name string) {
|
||||
name = strings.ReplaceAll(name, ".", "_")
|
||||
m.Conf(RUNTIME, kit.Keys(NODE, kit.MDB_TYPE), kind)
|
||||
m.Conf(RUNTIME, kit.Keys(NODE, kit.MDB_NAME), name)
|
||||
ice.Info.NodeName = name
|
||||
ice.Info.NodeType = kind
|
||||
}
|
||||
|
||||
const (
|
||||
MAKE = "make"
|
||||
CONF = "conf"
|
||||
HOST = "host"
|
||||
BOOT = "boot"
|
||||
NODE = "node"
|
||||
)
|
||||
const (
|
||||
HOSTNAME = "hostname"
|
||||
PATHNAME = "pathname"
|
||||
USERNAME = "username"
|
||||
)
|
||||
const (
|
||||
CTX_SELF = "ctx_self"
|
||||
CTX_DEV = "ctx_dev"
|
||||
CTX_SHY = "ctx_shy"
|
||||
CTX_PID = "ctx_pid"
|
||||
CTX_USER = "ctx_user"
|
||||
CTX_SHARE = "ctx_share"
|
||||
CTX_RIVER = "ctx_river"
|
||||
)
|
||||
const CLI = "cli"
|
||||
|
||||
var Index = &ice.Context{Name: CLI, Help: "命令模块",
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Load()
|
||||
_cli_init(m)
|
||||
}},
|
||||
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Save()
|
||||
|
@ -86,18 +86,9 @@ func init() {
|
||||
DAEMON: {Name: DAEMON, Help: "守护进程", Value: kit.Data(kit.MDB_PATH, path.Join(ice.USR_LOCAL, DAEMON))},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
}},
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
|
||||
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
list := []string{}
|
||||
m.Richs(DAEMON, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
|
||||
if value = kit.GetMeta(value); kit.Value(value, mdb.CACHE_CLEAR_ON_EXIT) == ice.TRUE {
|
||||
list = append(list, key)
|
||||
}
|
||||
})
|
||||
for _, k := range list {
|
||||
m.Conf(DAEMON, kit.Keys(kit.MDB_HASH, k), "")
|
||||
}
|
||||
m.Cmd(mdb.PRUNES, DAEMON, "", mdb.HASH, mdb.CACHE_CLEAR_ON_EXIT, ice.TRUE)
|
||||
}},
|
||||
|
||||
DAEMON: {Name: "daemon hash auto start prunes", Help: "守护进程", Action: map[string]*ice.Action{
|
||||
@ -107,10 +98,9 @@ func init() {
|
||||
m.Cmdy(DAEMON, START)
|
||||
}},
|
||||
START: {Name: "start cmd env dir", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Option(CMD_TYPE, DAEMON)
|
||||
m.Option(CMD_DIR, m.Option(DIR))
|
||||
m.Option(CMD_ENV, kit.Split(m.Option(ENV), " ="))
|
||||
m.Cmdy(SYSTEM, kit.Split(m.Option(CMD)))
|
||||
m.Cmdy(DAEMON, kit.Split(m.Option(CMD)))
|
||||
}},
|
||||
STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Option(mdb.FIELDS, "time,hash,status,pid,cmd,dir,env")
|
||||
@ -130,8 +120,7 @@ func init() {
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 { // 进程列表
|
||||
m.Fields(len(arg) == 0, "time,hash,status,pid,cmd,dir,env")
|
||||
m.Cmdy(mdb.SELECT, DAEMON, "", mdb.HASH)
|
||||
m.Table(func(index int, value map[string]string, head []string) {
|
||||
m.Cmdy(mdb.SELECT, DAEMON, "", mdb.HASH).Table(func(index int, value map[string]string, head []string) {
|
||||
switch value[kit.MDB_STATUS] {
|
||||
case START:
|
||||
m.PushButton(RESTART, STOP)
|
||||
|
@ -7,11 +7,10 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/skip2/go-qrcode"
|
||||
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
"github.com/skip2/go-qrcode"
|
||||
)
|
||||
|
||||
var _trans_web = map[string]color.Color{
|
||||
@ -126,7 +125,7 @@ func init() {
|
||||
m.Option(FG, kit.Select(BLUE, arg, 1))
|
||||
|
||||
if aaa.SessIsCli(m) {
|
||||
_qrcode_cli(m, kit.Select(m.Conf("web.share", kit.Keym(kit.MDB_DOMAIN)), arg))
|
||||
_qrcode_cli(m, kit.Select(m.Conf("web.share", kit.Keym(kit.MDB_DOMAIN)), arg, 0))
|
||||
} else {
|
||||
_qrcode_web(m, kit.Select(m.Option(ice.MSG_USERWEB), arg, 0))
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ func init() {
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 { // 事件列表
|
||||
m.Option(mdb.FIELDS, "time,event,count")
|
||||
m.Fields(len(arg) == 0, "time,event,count")
|
||||
m.Cmdy(mdb.SELECT, EVENT, "", mdb.HASH)
|
||||
m.PushAction(ACTION, mdb.REMOVE)
|
||||
return
|
||||
|
@ -48,6 +48,7 @@ const (
|
||||
BUILD = "build"
|
||||
SPAWN = "spawn"
|
||||
START = "start"
|
||||
ERROR = "error"
|
||||
STOP = "stop"
|
||||
|
||||
STATUS = "status"
|
||||
|
@ -3,5 +3,4 @@ chapter "gdb"
|
||||
field "协程池" routine
|
||||
field "信号量" signal
|
||||
field "事件流" event
|
||||
|
||||
field "定时器" timer
|
||||
|
@ -1,9 +1,10 @@
|
||||
package gdb
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"path"
|
||||
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/ctx"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
)
|
||||
@ -34,6 +35,7 @@ func init() {
|
||||
}},
|
||||
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Option(mdb.FIELDS, "time,hash,status,fileline")
|
||||
m.Cmdy(mdb.PRUNES, ROUTINE, "", mdb.HASH, kit.MDB_STATUS, ERROR)
|
||||
m.Cmdy(mdb.PRUNES, ROUTINE, "", mdb.HASH, kit.MDB_STATUS, STOP)
|
||||
}},
|
||||
|
||||
@ -43,15 +45,9 @@ func init() {
|
||||
m.Cmdy(INNER, arg[1:])
|
||||
default:
|
||||
ls := kit.Split(m.Option("fileline"), ":")
|
||||
switch kit.Split(ls[0], "/")[0] {
|
||||
case "usr":
|
||||
ls[0] = strings.TrimPrefix(ls[0], "usr/icebergs/")
|
||||
case "icebergs":
|
||||
ls[0] = strings.TrimPrefix(ls[0], "icebergs/")
|
||||
}
|
||||
|
||||
m.ShowPlugin("", INNER, kit.SSH_RUN)
|
||||
m.Push("args", kit.Format([]string{"usr/icebergs/", ls[0], ls[1]}))
|
||||
m.ProcessField(INNER, kit.SSH_RUN)
|
||||
m.Option(kit.SSH_ARG, kit.Format([]string{path.Dir(ls[0]), path.Base(ls[0]), ls[1]}))
|
||||
m.Cmdy(ctx.COMMAND, INNER)
|
||||
}
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
|
@ -25,7 +25,7 @@ func _timer_action(m *ice.Message, arg ...string) {
|
||||
m.Logs(TIMER, kit.MDB_KEY, key, ORDER, order)
|
||||
|
||||
msg := m.Cmd(value[kit.SSH_CMD])
|
||||
m.Grow(TIMER, kit.Keys(kit.MDB_HASH, key), kit.Dict("res", msg.Result()))
|
||||
m.Grow(TIMER, kit.Keys(kit.MDB_HASH, key), kit.Dict(kit.SSH_RES, msg.Result()))
|
||||
if value[ORDER] = kit.Format(order - 1); order > 1 {
|
||||
value[NEXT] = msg.Time(value[INTERVAL])
|
||||
}
|
||||
|
449
base/lex/lex.go
449
base/lex/lex.go
@ -1,15 +1,460 @@
|
||||
package lex
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
)
|
||||
|
||||
type Seed struct {
|
||||
page int
|
||||
hash int
|
||||
word string
|
||||
}
|
||||
type Point struct {
|
||||
s int
|
||||
c byte
|
||||
}
|
||||
type State struct {
|
||||
star bool
|
||||
next int
|
||||
hash int
|
||||
}
|
||||
type Matrix struct {
|
||||
nlang int
|
||||
ncell int
|
||||
|
||||
seed []*Seed
|
||||
page map[string]int
|
||||
hand map[int]string
|
||||
hash map[string]int
|
||||
word map[int]string
|
||||
|
||||
trans map[byte][]byte
|
||||
state map[State]*State
|
||||
mat []map[byte]*State
|
||||
|
||||
*ice.Context
|
||||
|
||||
nseed int
|
||||
npage int
|
||||
nhash int
|
||||
nline int
|
||||
nnode int
|
||||
nreal int
|
||||
}
|
||||
|
||||
func NewMatrix(m *ice.Message, nlang, ncell int) *Matrix {
|
||||
mat := &Matrix{}
|
||||
mat.nlang = nlang
|
||||
mat.ncell = ncell
|
||||
|
||||
mat.page = map[string]int{"nil": 0}
|
||||
mat.hand = map[int]string{0: "nil"}
|
||||
mat.hash = map[string]int{"nil": 0}
|
||||
mat.word = map[int]string{0: "nil"}
|
||||
|
||||
mat.trans = map[byte][]byte{}
|
||||
for k, v := range map[byte]string{
|
||||
't': "\t", 'n': "\n", 'b': "\t ", 's': "\t \n",
|
||||
'd': "0123456789", 'x': "0123456789ABCDEFabcdef",
|
||||
} {
|
||||
mat.trans[k] = []byte(v)
|
||||
}
|
||||
|
||||
mat.state = make(map[State]*State)
|
||||
mat.mat = make([]map[byte]*State, nlang)
|
||||
|
||||
mat.nline = nlang
|
||||
return mat
|
||||
}
|
||||
func (mat *Matrix) char(c byte) []byte {
|
||||
if cs, ok := mat.trans[c]; ok {
|
||||
return cs
|
||||
}
|
||||
return []byte{c}
|
||||
}
|
||||
func (mat *Matrix) index(m *ice.Message, hash string, h string) int {
|
||||
which, names := mat.hash, mat.word
|
||||
if hash == NPAGE {
|
||||
which, names = mat.page, mat.hand
|
||||
}
|
||||
|
||||
if x, e := strconv.Atoi(h); e == nil {
|
||||
if hash == NPAGE {
|
||||
m.Assert(x <= mat.npage)
|
||||
} else {
|
||||
mat.hash[h] = x
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
if x, ok := which[h]; ok {
|
||||
return x
|
||||
}
|
||||
|
||||
if hash == NPAGE {
|
||||
mat.npage++
|
||||
which[h] = mat.npage
|
||||
} else {
|
||||
mat.nhash++
|
||||
which[h] = mat.nhash
|
||||
}
|
||||
|
||||
names[which[h]] = h
|
||||
m.Assert(hash != NPAGE || mat.npage < mat.nlang)
|
||||
return which[h]
|
||||
}
|
||||
func (mat *Matrix) train(m *ice.Message, page int, hash int, seed []byte) int {
|
||||
m.Debug("%s %s page: %v hash: %v seed: %v", "train", "lex", page, hash, string(seed))
|
||||
|
||||
ss := []int{page}
|
||||
cn := make([]bool, mat.ncell)
|
||||
cc := make([]byte, 0, mat.ncell)
|
||||
sn := make([]bool, mat.nline)
|
||||
|
||||
points := []*Point{}
|
||||
|
||||
for p := 0; p < len(seed); p++ {
|
||||
|
||||
switch seed[p] {
|
||||
case '[':
|
||||
set := true
|
||||
if p++; seed[p] == '^' {
|
||||
set, p = false, p+1
|
||||
}
|
||||
|
||||
for ; seed[p] != ']'; p++ {
|
||||
if seed[p] == '\\' {
|
||||
p++
|
||||
for _, c := range mat.char(seed[p]) {
|
||||
cn[c] = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if seed[p+1] == '-' {
|
||||
begin, end := seed[p], seed[p+2]
|
||||
if begin > end {
|
||||
begin, end = end, begin
|
||||
}
|
||||
for c := begin; c <= end; c++ {
|
||||
cn[c] = true
|
||||
}
|
||||
p += 2
|
||||
continue
|
||||
}
|
||||
|
||||
cn[seed[p]] = true
|
||||
}
|
||||
|
||||
for c := 0; c < len(cn); c++ {
|
||||
if (set && cn[c]) || (!set && !cn[c]) {
|
||||
cc = append(cc, byte(c))
|
||||
}
|
||||
cn[c] = false
|
||||
}
|
||||
|
||||
case '.':
|
||||
for c := 0; c < len(cn); c++ {
|
||||
cc = append(cc, byte(c))
|
||||
}
|
||||
|
||||
case '\\':
|
||||
p++
|
||||
for _, c := range mat.char(seed[p]) {
|
||||
cc = append(cc, c)
|
||||
}
|
||||
default:
|
||||
cc = append(cc, seed[p])
|
||||
}
|
||||
|
||||
m.Debug("page: \033[31m%d %v\033[0m", len(ss), ss)
|
||||
m.Debug("cell: \033[32m%d %v\033[0m", len(cc), cc)
|
||||
|
||||
flag := '\000'
|
||||
if p+1 < len(seed) {
|
||||
switch flag = rune(seed[p+1]); flag {
|
||||
case '?', '+', '*':
|
||||
p++
|
||||
}
|
||||
}
|
||||
|
||||
for _, s := range ss {
|
||||
for _, c := range cc {
|
||||
|
||||
state := &State{}
|
||||
if mat.mat[s][c] != nil {
|
||||
*state = *mat.mat[s][c]
|
||||
} else {
|
||||
mat.nnode++
|
||||
}
|
||||
m.Debug("GET(%d,%d): %v", s, c, state)
|
||||
|
||||
switch flag {
|
||||
case '+':
|
||||
state.star = true
|
||||
case '*':
|
||||
state.star = true
|
||||
sn[s] = true
|
||||
case '?':
|
||||
sn[s] = true
|
||||
}
|
||||
|
||||
if state.next == 0 {
|
||||
mat.mat = append(mat.mat, make(map[byte]*State))
|
||||
sn = append(sn, false)
|
||||
state.next = mat.nline
|
||||
mat.nline++
|
||||
}
|
||||
sn[state.next] = true
|
||||
|
||||
mat.mat[s][c] = state
|
||||
points = append(points, &Point{s, c})
|
||||
m.Debug("SET(%d,%d): %v(%d,%d)", s, c, state, mat.nnode, mat.nreal)
|
||||
}
|
||||
}
|
||||
|
||||
cc, ss = cc[:0], ss[:0]
|
||||
for s, b := range sn {
|
||||
if sn[s] = false; b && s > 0 {
|
||||
ss = append(ss, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, s := range ss {
|
||||
if s < mat.nlang || s >= len(mat.mat) {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(mat.mat[s]) == 0 {
|
||||
last := mat.nline - 1
|
||||
mat.mat, mat.nline = mat.mat[:s], s
|
||||
m.Debug("DEL: %d-%d", last, mat.nline)
|
||||
}
|
||||
}
|
||||
|
||||
for _, s := range ss {
|
||||
for _, p := range points {
|
||||
state := &State{}
|
||||
*state = *mat.mat[p.s][p.c]
|
||||
|
||||
if state.next == s {
|
||||
m.Debug("GET(%d, %d): %v", p.s, p.c, state)
|
||||
if state.hash = hash; state.next >= len(mat.mat) {
|
||||
state.next = 0
|
||||
}
|
||||
mat.mat[p.s][p.c] = state
|
||||
m.Debug("SET(%d, %d): %v", p.s, p.c, state)
|
||||
}
|
||||
|
||||
if x, ok := mat.state[*state]; !ok {
|
||||
mat.state[*state] = mat.mat[p.s][p.c]
|
||||
mat.nreal++
|
||||
} else {
|
||||
mat.mat[p.s][p.c] = x
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m.Debug("%s %s npage: %v nhash: %v nseed: %v", "train", "lex", mat.npage, mat.nhash, len(mat.seed))
|
||||
return hash
|
||||
}
|
||||
func (mat *Matrix) parse(m *ice.Message, page int, line []byte) (hash int, rest []byte, word []byte) {
|
||||
m.Debug("%s %s page: %v line: %v", "parse", "lex", page, line)
|
||||
|
||||
pos := 0
|
||||
for star, s := 0, page; s != 0 && pos < len(line); pos++ {
|
||||
|
||||
c := line[pos]
|
||||
if c == '\\' && pos < len(line)-1 { //跳过转义
|
||||
pos++
|
||||
c = mat.char(line[pos])[0]
|
||||
}
|
||||
if c > 127 { //跳过中文
|
||||
word = append(word, c)
|
||||
continue
|
||||
}
|
||||
|
||||
state := mat.mat[s][c]
|
||||
if state == nil {
|
||||
s, star, pos = star, 0, pos-1
|
||||
continue
|
||||
}
|
||||
m.Debug("GET (%d,%d): %v", s, c, state)
|
||||
|
||||
word = append(word, c)
|
||||
|
||||
if state.star {
|
||||
star = s
|
||||
} else if x, ok := mat.mat[star][c]; !ok || !x.star {
|
||||
star = 0
|
||||
}
|
||||
|
||||
if s, hash = state.next, state.hash; s == 0 {
|
||||
s, star = star, 0
|
||||
}
|
||||
}
|
||||
|
||||
if pos == len(line) {
|
||||
// hash, pos, word = -1, 0, word[:0]
|
||||
} else if hash == 0 {
|
||||
pos, word = 0, word[:0]
|
||||
}
|
||||
rest = line[pos:]
|
||||
|
||||
m.Debug("%s %s hash: %v word: %v rest: %v", "parse", "lex", hash, word, rest)
|
||||
return
|
||||
}
|
||||
func (mat *Matrix) show(m *ice.Message, page string) {
|
||||
rows := map[int]bool{}
|
||||
cols := map[int]bool{}
|
||||
|
||||
nrow := []int{mat.page[page]}
|
||||
for i := 0; i < len(nrow); i++ {
|
||||
line := nrow[i]
|
||||
rows[line] = true
|
||||
|
||||
for i := 1; i < mat.ncell; i++ {
|
||||
if node := mat.mat[line][byte(i)]; node != nil {
|
||||
if cols[i] = true; node.next != 0 {
|
||||
nrow = append(nrow, node.next)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nrow = nrow[:0]
|
||||
ncol := []int{}
|
||||
for k := range rows {
|
||||
nrow = append(nrow, k)
|
||||
}
|
||||
for k := range cols {
|
||||
ncol = append(ncol, k)
|
||||
}
|
||||
sort.Ints(nrow)
|
||||
sort.Ints(ncol)
|
||||
|
||||
for _, i := range nrow {
|
||||
m.Push("0", kit.Select(kit.Format(i), mat.hand[i]))
|
||||
for _, j := range ncol {
|
||||
node := mat.mat[i][byte(j)]
|
||||
if node != nil {
|
||||
m.Push(kit.Format("%c", j), kit.Format("%v", node.next))
|
||||
} else {
|
||||
m.Push(kit.Format("%c", j), "")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
NLANG = "nlang"
|
||||
NCELL = "ncell"
|
||||
|
||||
NSEED = "nseed"
|
||||
NPAGE = "npage"
|
||||
NHASH = "nhash"
|
||||
)
|
||||
const (
|
||||
TRAIN = "train"
|
||||
PARSE = "parse"
|
||||
)
|
||||
const MATRIX = "matrix"
|
||||
|
||||
const LEX = "lex"
|
||||
|
||||
var Index = &ice.Context{Name: LEX, Help: "词法模块",
|
||||
Configs: map[string]*ice.Config{
|
||||
MATRIX: {Name: MATRIX, Help: "魔方矩阵", Value: kit.Data()},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
"hi": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Echo("hello %s world", c.Name)
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
|
||||
m.Load()
|
||||
m.Richs(m.Prefix(MATRIX), "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
|
||||
value = kit.GetMeta(value)
|
||||
|
||||
mat := NewMatrix(m, kit.Int(kit.Select("32", value[NLANG])), kit.Int(kit.Select("256", value[NCELL])))
|
||||
m.Grows(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) {
|
||||
page := mat.index(m, NPAGE, kit.Format(value[NPAGE]))
|
||||
hash := mat.index(m, NHASH, kit.Format(value[NHASH]))
|
||||
if mat.mat[page] == nil {
|
||||
mat.mat[page] = map[byte]*State{}
|
||||
}
|
||||
mat.seed = append(mat.seed, &Seed{page, hash, kit.Format(value[kit.MDB_TEXT])})
|
||||
mat.train(m, page, hash, []byte(kit.Format(value[kit.MDB_TEXT])))
|
||||
})
|
||||
value[MATRIX] = mat
|
||||
})
|
||||
}},
|
||||
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
|
||||
m.Save()
|
||||
}},
|
||||
MATRIX: {Name: "matrix hash npage text auto", Help: "魔方矩阵", Action: map[string]*ice.Action{
|
||||
mdb.CREATE: {Name: "create nlang=32 ncell=256", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
|
||||
mat := NewMatrix(m, kit.Int(kit.Select("32", m.Option(NLANG))), kit.Int(kit.Select("256", m.Option(NCELL))))
|
||||
m.Rich(m.Prefix(MATRIX), "", kit.Data(kit.MDB_TIME, m.Time(), MATRIX, mat, NLANG, mat.nlang, NCELL, mat.ncell))
|
||||
}},
|
||||
mdb.INSERT: {Name: "insert npage=num nhash=num text=123", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Richs(m.Prefix(MATRIX), "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
|
||||
value = kit.GetMeta(value)
|
||||
|
||||
mat, _ := value[MATRIX].(*Matrix)
|
||||
page := mat.index(m, NPAGE, m.Option(NPAGE))
|
||||
hash := mat.index(m, NHASH, m.Option(NHASH))
|
||||
if mat.mat[page] == nil {
|
||||
mat.mat[page] = map[byte]*State{}
|
||||
}
|
||||
|
||||
mat.seed = append(mat.seed, &Seed{page, hash, m.Option(kit.MDB_TEXT)})
|
||||
m.Grow(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), kit.Dict(
|
||||
kit.MDB_TIME, m.Time(), NPAGE, m.Option(NPAGE), NHASH, m.Option(NHASH), kit.MDB_TEXT, m.Option(kit.MDB_TEXT),
|
||||
))
|
||||
|
||||
mat.train(m, page, hash, []byte(m.Option(kit.MDB_TEXT)))
|
||||
|
||||
value[NSEED] = len(mat.seed)
|
||||
value[NPAGE] = len(mat.page) - 1
|
||||
value[NHASH] = len(mat.hash) - 1
|
||||
})
|
||||
}},
|
||||
mdb.REMOVE: {Name: "create", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.DELETE, m.Prefix(MATRIX), "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
|
||||
if m.Action(mdb.CREATE); len(arg) == 0 { // 矩阵列表
|
||||
m.Fields(len(arg) == 0, "time,hash,npage,nhash")
|
||||
m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), "", mdb.HASH)
|
||||
m.PushAction(mdb.INSERT, mdb.REMOVE)
|
||||
return
|
||||
}
|
||||
|
||||
if m.Action(mdb.INSERT); len(arg) == 1 { // 词法列表
|
||||
m.Fields(len(arg) == 1, "time,npage,nhash,text")
|
||||
m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST)
|
||||
return
|
||||
}
|
||||
|
||||
m.Richs(m.Prefix(MATRIX), "", arg[0], func(key string, value map[string]interface{}) {
|
||||
value = kit.GetMeta(value)
|
||||
mat, _ := value[MATRIX].(*Matrix)
|
||||
m.Debug("what %#v", mat)
|
||||
|
||||
if len(arg) == 2 { // 词法矩阵
|
||||
mat.show(m, arg[1])
|
||||
return
|
||||
}
|
||||
|
||||
hash, rest, word := mat.parse(m, mat.index(m, NPAGE, arg[1]), []byte(arg[2]))
|
||||
m.Push("time", m.Time())
|
||||
m.Push("hash", mat.word[hash])
|
||||
m.Push("word", string(word))
|
||||
m.Push("rest", string(rest))
|
||||
})
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server
|
||||
return &Frame{}
|
||||
}
|
||||
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
|
||||
f.p = make(chan *Log, 4096)
|
||||
f.p = make(chan *Log, ice.MOD_BUFS)
|
||||
ice.Log = func(msg *ice.Message, p, l, s string) {
|
||||
f.p <- &Log{m: msg, p: p, l: l, s: s}
|
||||
}
|
||||
@ -40,17 +40,17 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
|
||||
bio := m.Confv(FILE, kit.Keys(file, FILE)).(*bufio.Writer)
|
||||
|
||||
bio.WriteString(l.p)
|
||||
bio.WriteString(" ")
|
||||
bio.WriteString(ice.MOD_SP)
|
||||
if p, ok := view[PREFIX].(string); ok {
|
||||
bio.WriteString(p)
|
||||
}
|
||||
bio.WriteString(l.l)
|
||||
bio.WriteString(" ")
|
||||
bio.WriteString(ice.MOD_SP)
|
||||
bio.WriteString(l.s)
|
||||
if p, ok := view[SUFFIX].(string); ok {
|
||||
bio.WriteString(p)
|
||||
}
|
||||
bio.WriteString("\n")
|
||||
bio.WriteString(ice.MOD_NL)
|
||||
bio.Flush()
|
||||
}
|
||||
}
|
||||
|
@ -114,11 +114,18 @@ func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) {
|
||||
if val[kit.MDB_META] != nil {
|
||||
val = val[kit.MDB_META].(map[string]interface{})
|
||||
}
|
||||
switch cb := m.Optionv(kit.Keycb(PRUNES)).(type) {
|
||||
case func(string, map[string]interface{}) bool:
|
||||
if !cb(key, val) {
|
||||
return
|
||||
}
|
||||
default:
|
||||
for i := 0; i < len(arg)-1; i += 2 {
|
||||
if val[arg[i]] != arg[i+1] {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
m.Push(key, val, fields)
|
||||
})
|
||||
m.Table(func(index int, value map[string]string, head []string) {
|
||||
@ -170,9 +177,6 @@ func _list_select(m *ice.Message, prefix, chain, field, value string) {
|
||||
}
|
||||
}
|
||||
})
|
||||
// if m.Option(FIELDS) != DETAIL {
|
||||
// m.SortIntR(kit.MDB_ID)
|
||||
// }
|
||||
}
|
||||
func _list_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) {
|
||||
m.Grows(prefix, chain, field, value, func(index int, val map[string]interface{}) {
|
||||
|
@ -66,9 +66,9 @@ func init() {
|
||||
m.ProcessRewrite("offend", offend)
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Option(mdb.FIELDS, kit.Select("time,hash,count,name,file", kit.Select("time,id,file,text", mdb.DETAIL, len(arg) > 1 && arg[1] != ""), len(arg) > 0))
|
||||
m.Fields(true, kit.Select("time,hash,count,name,file", "time,id,file,text", len(arg) > 1 && arg[1] != ""))
|
||||
m.Option(mdb.CACHE_OFFEND, kit.Select("0", arg, 3))
|
||||
m.Option(mdb.CACHE_LIMIT, kit.Select("10", arg, 2))
|
||||
m.Option("cache.offend", kit.Select("0", arg, 3))
|
||||
|
||||
if m.Cmdy(mdb.SELECT, TAIL, "", mdb.ZONE, arg); len(arg) == 0 {
|
||||
m.PushAction(mdb.REMOVE)
|
||||
|
@ -57,7 +57,7 @@ func init() {
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
m.Option(mdb.FIELDS, "time,hash,file,from")
|
||||
m.Fields(len(arg) == 0, "time,hash,file,from")
|
||||
m.Cmdy(mdb.SELECT, TRASH, "", mdb.HASH)
|
||||
m.PushAction(mdb.REVERT, mdb.REMOVE)
|
||||
return
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
"github.com/shylinux/icebergs/base/ctx"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
"github.com/shylinux/icebergs/base/nfs"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
@ -28,8 +29,8 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) string {
|
||||
res := msg.Result()
|
||||
|
||||
// 输出结果
|
||||
if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, "\n") {
|
||||
fmt.Fprint(msg.O, "\n")
|
||||
if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, ice.MOD_NL) {
|
||||
fmt.Fprint(msg.O, ice.MOD_NL)
|
||||
}
|
||||
return res
|
||||
|
||||
@ -41,8 +42,8 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) string {
|
||||
}
|
||||
|
||||
// 输出结果
|
||||
if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, "\n") {
|
||||
fmt.Fprint(msg.O, "\n")
|
||||
if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, ice.MOD_NL) {
|
||||
fmt.Fprint(msg.O, ice.MOD_NL)
|
||||
}
|
||||
return res
|
||||
}
|
||||
@ -167,7 +168,7 @@ func (f *Frame) option(m *ice.Message, ls []string) []string {
|
||||
}
|
||||
func (f *Frame) change(m *ice.Message, ls []string) []string {
|
||||
if len(ls) == 1 && ls[0] == "~" { // 模块列表
|
||||
ls = []string{"context"}
|
||||
ls = []string{ctx.CONTEXT}
|
||||
|
||||
} else if len(ls) > 0 && strings.HasPrefix(ls[0], "~") { // 切换模块
|
||||
target := ls[0][1:]
|
||||
@ -282,11 +283,9 @@ func (f *Frame) scan(m *ice.Message, h, line string) *Frame {
|
||||
return f
|
||||
}
|
||||
func (f *Frame) close() {
|
||||
fmt.Printf("what %v\n", 123)
|
||||
if stdin, ok := f.stdin.(io.Closer); ok {
|
||||
stdin.Close()
|
||||
f.stdin = nil
|
||||
fmt.Printf("what %v\n", 123)
|
||||
}
|
||||
}
|
||||
|
||||
@ -406,18 +405,15 @@ func init() {
|
||||
f := m.Target().Server().(*Frame)
|
||||
m.Search(arg[0]+".", func(p *ice.Context, s *ice.Context, key string) { f.target = s })
|
||||
f.prompt(m)
|
||||
m.Echo(arg[0])
|
||||
}},
|
||||
PROMPT: {Name: "prompt arg 执行:button", Help: "命令提示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
f := m.Target().Server().(*Frame)
|
||||
f.ps1 = arg
|
||||
f.prompt(m)
|
||||
m.Echo(arg[0])
|
||||
}},
|
||||
PRINTF: {Name: "printf 执行:button text:textarea", Help: "输出显示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
f := m.Target().Server().(*Frame)
|
||||
f.printf(m, arg[0])
|
||||
m.Echo(arg[0])
|
||||
}},
|
||||
SCREEN: {Name: "screen 执行:button text:textarea", Help: "输出命令", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
f := m.Target().Server().(*Frame)
|
||||
|
@ -75,7 +75,7 @@ func init() {
|
||||
m.Richs(SESSION, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
|
||||
if w, ok := kit.Value(value, kit.Keym(INPUT)).(io.Writer); ok {
|
||||
m.Grow(SESSION, kit.Keys(kit.MDB_HASH, key), kit.Dict(kit.MDB_TYPE, CMD, kit.MDB_TEXT, m.Option(CMD)))
|
||||
w.Write([]byte(m.Option(CMD) + "\n"))
|
||||
w.Write([]byte(m.Option(CMD) + ice.MOD_NL))
|
||||
}
|
||||
})
|
||||
m.ProcessRefresh("300ms")
|
||||
|
@ -73,7 +73,7 @@ func init() {
|
||||
m.Assert(e)
|
||||
cb(c)
|
||||
case func(net.Conn, []byte, error):
|
||||
b := make([]byte, 4096)
|
||||
b := make([]byte, ice.MOD_BUFS)
|
||||
for {
|
||||
n, e := c.Read(b)
|
||||
if cb(c, b[:n], e); e != nil {
|
||||
|
@ -77,7 +77,7 @@ func init() {
|
||||
break
|
||||
}
|
||||
|
||||
b := make([]byte, 4096)
|
||||
b := make([]byte, ice.MOD_BUFS)
|
||||
if n, e := c.Read(b); e == nil {
|
||||
m.Info("nonce", string(b[:n]))
|
||||
c.Write(b[:n])
|
||||
|
@ -229,7 +229,7 @@ func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
SPACE: {Name: SPACE, Help: "空间站", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME,
|
||||
"redial", kit.Dict("a", 3000, "b", 1000, "c", 1000, "r", 4096, "w", 4096),
|
||||
"redial", kit.Dict("a", 3000, "b", 1000, "c", 1000, "r", ice.MOD_BUFS, "w", ice.MOD_BUFS),
|
||||
"timeout", kit.Dict("c", "180s"),
|
||||
)},
|
||||
},
|
||||
|
@ -1,7 +1,7 @@
|
||||
package yac
|
||||
|
||||
import (
|
||||
"github.com/shylinux/icebergs"
|
||||
ice "github.com/shylinux/icebergs"
|
||||
)
|
||||
|
||||
const YAC = "yac"
|
||||
|
2
conf.go
2
conf.go
@ -1,6 +1,8 @@
|
||||
package ice
|
||||
|
||||
const ( // MOD
|
||||
MOD_SP = " "
|
||||
MOD_NL = "\n"
|
||||
MOD_DIR = 0750
|
||||
MOD_FILE = 0640
|
||||
|
||||
|
10
misc.go
10
misc.go
@ -361,3 +361,13 @@ func (m *Message) OptionLoad(file string) *Message {
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *Message) Confi(key string, sub string) int {
|
||||
return kit.Int(m.Conf(key, sub))
|
||||
}
|
||||
func (m *Message) Capi(key string, val ...interface{}) int {
|
||||
if len(val) > 0 {
|
||||
m.Cap(key, kit.Int(m.Cap(key))+kit.Int(val[0]))
|
||||
}
|
||||
return kit.Int(m.Cap(key))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user