mirror of
https://shylinux.com/x/ContextOS
synced 2025-04-25 16:58:06 +08:00
opt yac
This commit is contained in:
parent
9f81fa985d
commit
5461b95f36
@ -1,11 +1,11 @@
|
||||
~aaa
|
||||
role root user shy shaoying
|
||||
|
||||
~mdb
|
||||
note model favor spirit spirit relate relate
|
||||
note model money expend expend amount amount
|
||||
note model state active active elapse elapse
|
||||
note model event action action target target
|
||||
note model proxy ctx text cmd text
|
||||
note model share stuff stuff right right
|
||||
|
||||
# ~mdb
|
||||
# note model favor spirit spirit relate relate
|
||||
# note model money expend expend amount amount
|
||||
# note model state active active elapse elapse
|
||||
# note model event action action target target
|
||||
# note model proxy ctx text cmd text
|
||||
# note model share stuff stuff right right
|
||||
#
|
||||
|
@ -1,7 +1,6 @@
|
||||
package aaa
|
||||
|
||||
import (
|
||||
"gopkg.in/gomail.v2"
|
||||
"contexts/ctx"
|
||||
"crypto"
|
||||
"crypto/aes"
|
||||
@ -16,6 +15,7 @@ import (
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"gopkg.in/gomail.v2"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
@ -36,7 +36,7 @@ type AAA struct {
|
||||
}
|
||||
|
||||
func Auto(m *ctx.Message, arg ...string) {
|
||||
msg := m.Spawn().Add("option", "auto_cmd", "").Cmd("auth", arg)
|
||||
msg := m.Spawn().Add("option", "bio.cmd", "").Cmd("auth", arg)
|
||||
msg.Table(func(line int, maps map[string]string) {
|
||||
m.Add("append", "value", maps["key"])
|
||||
m.Add("append", "name", fmt.Sprintf("%s: %s", maps["type"], maps["meta"]))
|
||||
|
@ -16,24 +16,13 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"plugin"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Frame struct {
|
||||
key string
|
||||
run bool
|
||||
pos int
|
||||
index int
|
||||
list []string
|
||||
}
|
||||
type CLI struct {
|
||||
label map[string]string
|
||||
stack []*Frame
|
||||
|
||||
*time.Timer
|
||||
Context *ctx.Context
|
||||
}
|
||||
@ -51,51 +40,16 @@ func (cli *CLI) schedule(m *ctx.Message) string {
|
||||
}
|
||||
|
||||
func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
|
||||
c.Caches = map[string]*ctx.Cache{
|
||||
"level": &ctx.Cache{Name: "level", Value: "0", Help: "嵌套层级"},
|
||||
"parse": &ctx.Cache{Name: "parse(true/false)", Value: "true", Help: "命令解析"},
|
||||
}
|
||||
|
||||
return &CLI{Context: c}
|
||||
}
|
||||
func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||
return cli
|
||||
}
|
||||
func (cli *CLI) Start(m *ctx.Message, arg ...string) bool {
|
||||
m.Cap("stream", m.Sess("yac").Call(func(cmd *ctx.Message) *ctx.Message {
|
||||
if !m.Caps("parse") {
|
||||
switch cmd.Detail(0) {
|
||||
case "if":
|
||||
cmd.Set("detail", "if", "false")
|
||||
case "else":
|
||||
case "end":
|
||||
case "for":
|
||||
default:
|
||||
cmd.Hand = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if cmd.Cmd(); cmd.Has("return") {
|
||||
m.Options("scan_end", true)
|
||||
m.Target().Close(m)
|
||||
}
|
||||
|
||||
v := cmd.Optionv("ps_target")
|
||||
if v != nil {
|
||||
m.Optionv("ps_target", v)
|
||||
}
|
||||
return nil
|
||||
}, "scan", arg).Target().Name)
|
||||
|
||||
return false
|
||||
return true
|
||||
}
|
||||
func (cli *CLI) Close(m *ctx.Message, arg ...string) bool {
|
||||
switch cli.Context {
|
||||
case m.Target():
|
||||
case m.Source():
|
||||
}
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
@ -605,52 +559,6 @@ func main() {
|
||||
}
|
||||
return
|
||||
}},
|
||||
"source": &ctx.Command{Name: "source [script|stdio|snippet]", Help: "解析脚本, script: 脚本文件, stdio: 命令终端, snippet: 代码片段", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Cmdy("dir", "", "dir_deep", "dir_reg", ".*\\.(sh|shy|py)$")
|
||||
return
|
||||
}
|
||||
|
||||
// 解析脚本文件
|
||||
if p := m.Cmdx("nfs.path", arg[0]); p != "" && strings.Contains(p, ".") {
|
||||
arg[0] = p
|
||||
switch path.Ext(p) {
|
||||
case "":
|
||||
case ".shy":
|
||||
m.Option("scan_end", "false")
|
||||
m.Start(fmt.Sprintf("shell%d", m.Capi("nshell", 1)), "shell", arg...)
|
||||
m.Wait()
|
||||
default:
|
||||
m.Cmdy("system", m.Conf("system", []string{"script", strings.TrimPrefix(path.Ext(p), ".")}), arg)
|
||||
}
|
||||
m.Append("directory", "")
|
||||
return
|
||||
}
|
||||
|
||||
// 解析终端命令
|
||||
if arg[0] == "stdio" {
|
||||
m.Option("scan_end", "false")
|
||||
m.Start("shy", "shell", "stdio", "engine")
|
||||
m.Wait()
|
||||
return
|
||||
}
|
||||
|
||||
text := strings.Join(arg, " ")
|
||||
if !strings.HasPrefix(text, "sess") && m.Options("remote") {
|
||||
text = m.Current(text)
|
||||
}
|
||||
|
||||
// 解析代码片段
|
||||
m.Sess("yac").Call(func(msg *ctx.Message) *ctx.Message {
|
||||
switch msg.Cmd().Detail(0) {
|
||||
case "cmd":
|
||||
m.Set("append").Copy(msg, "append")
|
||||
m.Set("result").Copy(msg, "result")
|
||||
}
|
||||
return nil
|
||||
}, "parse", "line", "void", text)
|
||||
return
|
||||
}},
|
||||
"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) (e error) {
|
||||
if d, e := time.ParseDuration(arg[0]); m.Assert(e) {
|
||||
m.Log("info", "sleep %v", d)
|
||||
@ -866,7 +774,7 @@ func main() {
|
||||
m.Echo("quit")
|
||||
|
||||
case "1":
|
||||
if m.Option("cli.modal") != "action" {
|
||||
if m.Option("bio.modal") != "action" {
|
||||
m.Cmd("cli.source", m.Conf("system", "script.exit"))
|
||||
m.Echo("restart")
|
||||
}
|
||||
@ -1289,16 +1197,16 @@ var version = struct {
|
||||
detail = append(detail, arg...)
|
||||
|
||||
// 目标切换
|
||||
target := m.Optionv("ps_target")
|
||||
target := m.Optionv("bio.ctx")
|
||||
if detail[0] != "context" {
|
||||
defer func() { m.Optionv("ps_target", target) }()
|
||||
defer func() { m.Optionv("bio.ctx", target) }()
|
||||
}
|
||||
|
||||
// 解析脚本
|
||||
msg := m
|
||||
for k, v := range m.Confv("system", "script").(map[string]interface{}) {
|
||||
if strings.HasSuffix(detail[0], "."+k) {
|
||||
msg = m.Spawn(m.Optionv("ps_target"))
|
||||
msg = m.Spawn(m.Optionv("bio.ctx"))
|
||||
detail[0] = m.Cmdx("nfs.path", detail[0])
|
||||
detail = append([]string{v.(string)}, detail...)
|
||||
break
|
||||
@ -1319,7 +1227,7 @@ var version = struct {
|
||||
}
|
||||
detail[0] = routes[len(routes)-1]
|
||||
} else {
|
||||
msg = m.Spawn(m.Optionv("ps_target"))
|
||||
msg = m.Spawn(m.Optionv("bio.ctx"))
|
||||
}
|
||||
}
|
||||
msg.Copy(m, "option").Copy(m, "append")
|
||||
@ -1378,7 +1286,7 @@ var version = struct {
|
||||
if msg.Set("detail", args).Cmd(); !msg.Hand {
|
||||
msg.Cmd("system", args)
|
||||
}
|
||||
if msg.Appends("ps_target1") {
|
||||
if msg.Appends("bio.ctx1") {
|
||||
target = msg.Target()
|
||||
}
|
||||
|
||||
@ -1413,251 +1321,11 @@ var version = struct {
|
||||
}
|
||||
|
||||
// 返回结果
|
||||
m.Optionv("ps_target", msg.Target())
|
||||
m.Optionv("bio.ctx", msg.Target())
|
||||
m.Set("append").Copy(msg, "append")
|
||||
m.Set("result").Copy(msg, "result")
|
||||
return
|
||||
}},
|
||||
"str": &ctx.Command{Name: "str word", Help: "解析字符串", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Echo(arg[0][1 : len(arg[0])-1])
|
||||
return
|
||||
}},
|
||||
"exe": &ctx.Command{Name: "exe $ ( cmd )", Help: "解析嵌套命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
switch len(arg) {
|
||||
case 1:
|
||||
m.Echo(arg[0])
|
||||
case 2:
|
||||
msg := m.Spawn(m.Optionv("ps_target"))
|
||||
switch arg[0] {
|
||||
case "$":
|
||||
m.Echo(msg.Cap(arg[1]))
|
||||
case "@":
|
||||
value := msg.Option(arg[1])
|
||||
if value == "" {
|
||||
value = msg.Conf(arg[1])
|
||||
}
|
||||
|
||||
m.Echo(value)
|
||||
default:
|
||||
m.Echo(arg[0]).Echo(arg[1])
|
||||
}
|
||||
default:
|
||||
switch arg[0] {
|
||||
case "$", "@":
|
||||
m.Result(0, arg[2:len(arg)-1])
|
||||
}
|
||||
}
|
||||
return
|
||||
}},
|
||||
"val": &ctx.Command{Name: "val exp", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
result := "false"
|
||||
switch len(arg) {
|
||||
case 0:
|
||||
result = ""
|
||||
case 1:
|
||||
result = arg[0]
|
||||
case 2:
|
||||
switch arg[0] {
|
||||
case "-z":
|
||||
if arg[1] == "" {
|
||||
result = "true"
|
||||
}
|
||||
case "-n":
|
||||
if arg[1] != "" {
|
||||
result = "true"
|
||||
}
|
||||
|
||||
case "-e":
|
||||
if _, e := os.Stat(arg[1]); e == nil {
|
||||
result = "true"
|
||||
}
|
||||
case "-f":
|
||||
if info, e := os.Stat(arg[1]); e == nil && !info.IsDir() {
|
||||
result = "true"
|
||||
}
|
||||
case "-d":
|
||||
if info, e := os.Stat(arg[1]); e == nil && info.IsDir() {
|
||||
result = "true"
|
||||
}
|
||||
case "+":
|
||||
result = arg[1]
|
||||
case "-":
|
||||
result = arg[1]
|
||||
if i, e := strconv.Atoi(arg[1]); e == nil {
|
||||
result = fmt.Sprintf("%d", -i)
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
v1, e1 := strconv.Atoi(arg[0])
|
||||
v2, e2 := strconv.Atoi(arg[2])
|
||||
switch arg[1] {
|
||||
case ":=":
|
||||
if !m.Target().Has(arg[0]) {
|
||||
result = m.Cap(arg[0], arg[0], arg[2], "临时变量")
|
||||
}
|
||||
case "=":
|
||||
result = m.Cap(arg[0], arg[2])
|
||||
case "+=":
|
||||
if i, e := strconv.Atoi(m.Cap(arg[0])); e == nil && e2 == nil {
|
||||
result = m.Cap(arg[0], fmt.Sprintf("%d", v2+i))
|
||||
} else {
|
||||
result = m.Cap(arg[0], m.Cap(arg[0])+arg[2])
|
||||
}
|
||||
case "+":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%d", v1+v2)
|
||||
} else {
|
||||
result = arg[0] + arg[2]
|
||||
}
|
||||
case "-":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%d", v1-v2)
|
||||
} else {
|
||||
result = strings.Replace(arg[0], arg[1], "", -1)
|
||||
}
|
||||
case "*":
|
||||
result = arg[0]
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%d", v1*v2)
|
||||
}
|
||||
case "/":
|
||||
result = arg[0]
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%d", v1/v2)
|
||||
}
|
||||
case "%":
|
||||
result = arg[0]
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%d", v1%v2)
|
||||
}
|
||||
|
||||
case "<":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%t", v1 < v2)
|
||||
} else {
|
||||
result = fmt.Sprintf("%t", arg[0] < arg[2])
|
||||
}
|
||||
case "<=":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%t", v1 <= v2)
|
||||
} else {
|
||||
result = fmt.Sprintf("%t", arg[0] <= arg[2])
|
||||
}
|
||||
case ">":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%t", v1 > v2)
|
||||
} else {
|
||||
result = fmt.Sprintf("%t", arg[0] > arg[2])
|
||||
}
|
||||
case ">=":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%t", v1 >= v2)
|
||||
} else {
|
||||
result = fmt.Sprintf("%t", arg[0] >= arg[2])
|
||||
}
|
||||
case "==":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%t", v1 == v2)
|
||||
} else {
|
||||
result = fmt.Sprintf("%t", arg[0] == arg[2])
|
||||
}
|
||||
case "!=":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%t", v1 != v2)
|
||||
} else {
|
||||
result = fmt.Sprintf("%t", arg[0] != arg[2])
|
||||
}
|
||||
|
||||
case "~":
|
||||
if m, e := regexp.MatchString(arg[2], arg[0]); m && e == nil {
|
||||
result = "true"
|
||||
}
|
||||
case "!~":
|
||||
if m, e := regexp.MatchString(arg[2], arg[0]); !m || e != nil {
|
||||
result = "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
m.Echo(result)
|
||||
|
||||
return
|
||||
}},
|
||||
"exp": &ctx.Command{Name: "exp word", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) > 0 && arg[0] == "{" {
|
||||
msg := m.Spawn()
|
||||
for i := 1; i < len(arg); i++ {
|
||||
key := arg[i]
|
||||
for i += 3; i < len(arg); i++ {
|
||||
if arg[i] == "]" {
|
||||
break
|
||||
}
|
||||
msg.Add("append", key, arg[i])
|
||||
}
|
||||
}
|
||||
m.Echo("%d", msg.Code())
|
||||
return
|
||||
}
|
||||
|
||||
pre := map[string]int{
|
||||
"=": 1,
|
||||
"+": 2, "-": 2,
|
||||
"*": 3, "/": 3, "%": 3,
|
||||
}
|
||||
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().Cmd("val", num[len(op)-1], op[len(op)-1], num[len(op)]).Get("result")
|
||||
num = num[:len(num)-1]
|
||||
op = op[:len(op)-1]
|
||||
}
|
||||
|
||||
num = append(num, arg[i+1])
|
||||
op = append(op, arg[i])
|
||||
}
|
||||
|
||||
for i := len(op) - 1; i >= 0; i-- {
|
||||
num[i] = m.Spawn().Cmd("val", num[i], op[i], num[i+1]).Get("result")
|
||||
}
|
||||
|
||||
m.Echo("%s", num[0])
|
||||
return
|
||||
}},
|
||||
"let": &ctx.Command{Name: "let a = exp", Help: "设置变量, a: 变量名, exp: 表达式(a {+|-|*|/|%} b)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
switch arg[2] {
|
||||
case "=":
|
||||
m.Cap(arg[1], arg[3])
|
||||
case "<-":
|
||||
m.Cap(arg[1], m.Cap("last_msg"))
|
||||
}
|
||||
m.Echo(m.Cap(arg[1]))
|
||||
return
|
||||
}},
|
||||
"var": &ctx.Command{Name: "var a [= exp]", Help: "定义变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if m.Cap(arg[1], arg[1], "", "临时变量"); len(arg) > 1 {
|
||||
switch arg[2] {
|
||||
case "=":
|
||||
m.Cap(arg[1], arg[3])
|
||||
case "<-":
|
||||
m.Cap(arg[1], m.Cap("last_msg"))
|
||||
}
|
||||
}
|
||||
m.Echo(m.Cap(arg[1]))
|
||||
return
|
||||
}},
|
||||
"expr": &ctx.Command{Name: "expr arg...", Help: "输出表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Echo("%s", strings.Join(arg[1:], ""))
|
||||
return
|
||||
}},
|
||||
"return": &ctx.Command{Name: "return result...", Help: "结束脚本, result: 返回值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Add("append", "return", arg[1:])
|
||||
return
|
||||
}},
|
||||
"arguments": &ctx.Command{Name: "arguments", Help: "脚本参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Set("result", m.Optionv("arguments"))
|
||||
return
|
||||
}},
|
||||
|
||||
"tmux": &ctx.Command{Name: "tmux buffer", Help: "终端管理, buffer: 查看复制", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
switch arg[0] {
|
||||
@ -1702,125 +1370,6 @@ var version = struct {
|
||||
m.Table()
|
||||
return
|
||||
}},
|
||||
|
||||
"label": &ctx.Command{Name: "label name", Help: "记录当前脚本的位置, name: 位置名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
if cli.label == nil {
|
||||
cli.label = map[string]string{}
|
||||
}
|
||||
cli.label[arg[1]] = m.Option("file_pos")
|
||||
}
|
||||
return
|
||||
}},
|
||||
"goto": &ctx.Command{Name: "goto label [exp] condition", Help: "向上跳转到指定位置, label: 跳转位置, condition: 跳转条件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
if pos, ok := cli.label[arg[1]]; ok {
|
||||
if !kit.Right(arg[len(arg)-1]) {
|
||||
return
|
||||
}
|
||||
m.Append("file_pos0", pos)
|
||||
}
|
||||
}
|
||||
return
|
||||
}},
|
||||
"if": &ctx.Command{Name: "if exp", Help: "条件语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
run := m.Caps("parse") && kit.Right(arg[1])
|
||||
cli.stack = append(cli.stack, &Frame{pos: m.Optioni("file_pos"), key: key, run: run})
|
||||
m.Capi("level", 1)
|
||||
m.Caps("parse", run)
|
||||
}
|
||||
return
|
||||
}},
|
||||
"else": &ctx.Command{Name: "else", Help: "条件语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
if !m.Caps("parse") {
|
||||
m.Caps("parse", true)
|
||||
} else {
|
||||
if len(cli.stack) == 1 {
|
||||
m.Caps("parse", false)
|
||||
} else {
|
||||
frame := cli.stack[len(cli.stack)-2]
|
||||
m.Caps("parse", !frame.run)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}},
|
||||
"end": &ctx.Command{Name: "end", Help: "结束语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
if frame := cli.stack[len(cli.stack)-1]; frame.key == "for" && frame.run {
|
||||
m.Append("file_pos0", frame.pos)
|
||||
return
|
||||
}
|
||||
|
||||
if cli.stack = cli.stack[:len(cli.stack)-1]; m.Capi("level", -1) > 0 {
|
||||
m.Caps("parse", cli.stack[len(cli.stack)-1].run)
|
||||
} else {
|
||||
m.Caps("parse", true)
|
||||
}
|
||||
}
|
||||
return
|
||||
}},
|
||||
"for": &ctx.Command{Name: "for [[express ;] condition]|[index message meta value]",
|
||||
Help: "循环语句, express: 每次循环运行的表达式, condition: 循环条件, index: 索引消息, message: 消息编号, meta: value: ",
|
||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) {
|
||||
run := m.Caps("parse")
|
||||
defer func() { m.Caps("parse", run) }()
|
||||
|
||||
msg := m
|
||||
if run {
|
||||
if arg[1] == "index" {
|
||||
if code, e := strconv.Atoi(arg[2]); m.Assert(e) {
|
||||
msg = m.Target().Message().Tree(code)
|
||||
run = run && msg != nil && msg.Meta != nil
|
||||
switch len(arg) {
|
||||
case 4:
|
||||
run = run && len(msg.Meta) > 0
|
||||
case 5:
|
||||
run = run && len(msg.Meta[arg[3]]) > 0
|
||||
}
|
||||
}
|
||||
} else {
|
||||
run = run && kit.Right(arg[len(arg)-1])
|
||||
}
|
||||
|
||||
if len(cli.stack) > 0 {
|
||||
if frame := cli.stack[len(cli.stack)-1]; frame.key == "for" && frame.pos == m.Optioni("file_pos") {
|
||||
if arg[1] == "index" {
|
||||
frame.index++
|
||||
if run = run && len(frame.list) > frame.index; run {
|
||||
if len(arg) == 5 {
|
||||
arg[3] = arg[4]
|
||||
}
|
||||
m.Cap(arg[3], frame.list[frame.index])
|
||||
}
|
||||
}
|
||||
frame.run = run
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cli.stack = append(cli.stack, &Frame{pos: m.Optioni("file_pos"), key: key, run: run, index: 0})
|
||||
if m.Capi("level", 1); run && arg[1] == "index" {
|
||||
frame := cli.stack[len(cli.stack)-1]
|
||||
switch len(arg) {
|
||||
case 4:
|
||||
frame.list = []string{}
|
||||
for k, _ := range msg.Meta {
|
||||
frame.list = append(frame.list, k)
|
||||
}
|
||||
case 5:
|
||||
frame.list = msg.Meta[arg[3]]
|
||||
arg[3] = arg[4]
|
||||
}
|
||||
m.Cap(arg[3], arg[3], frame.list[0], "临时变量")
|
||||
}
|
||||
}
|
||||
return
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -4,5 +4,5 @@ var version = struct {
|
||||
host string
|
||||
self int
|
||||
}{
|
||||
"2019-07-20 15:41:22", "mac", 229,
|
||||
"2019-07-20 17:10:58", "mac", 232,
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ func (c *Context) Plugin(s *Context, args []string) string {
|
||||
m := &Message{code: 0, time: time.Now(), source: s, target: s, Meta: map[string][]string{}}
|
||||
kit.DisableLog = true
|
||||
m.Option("log.disable", true)
|
||||
m.Option("cli.modal", "action")
|
||||
m.Option("bio.modal", "action")
|
||||
|
||||
if len(args) == 0 {
|
||||
m.Echo("%s: %s\n\n", s.Name, s.Help)
|
||||
@ -235,7 +235,7 @@ func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message))
|
||||
}
|
||||
func (m *Message) Gos(msg *Message, hand ...func(msg *Message)) *Message {
|
||||
go func() {
|
||||
msg.Option("routine", m.Capi("ngo", 1))
|
||||
msg.Option("ctx.routine", m.Capi("ngo", 1))
|
||||
m.TryCatch(msg, true, hand...)
|
||||
}()
|
||||
return m
|
||||
|
@ -22,10 +22,15 @@ func (ctx *CTX) Spawn(m *Message, c *Context, arg ...string) Server {
|
||||
return s
|
||||
}
|
||||
func (ctx *CTX) Begin(m *Message, arg ...string) Server {
|
||||
m.Option("ctx.routine", 0)
|
||||
m.Option("log.disable", true)
|
||||
m.Option("ctx.chain", "aaa", "ssh", "cli", "nfs")
|
||||
|
||||
m.Option("page.limit", 10)
|
||||
m.Option("page.offset", 0)
|
||||
m.Option("routine", 0)
|
||||
m.Optionv("ctx.form", map[string]int{
|
||||
"page.limit": 1, "page.offset": 1,
|
||||
})
|
||||
|
||||
m.root = m
|
||||
m.Sess(m.target.Name, m)
|
||||
@ -39,19 +44,20 @@ func (ctx *CTX) Begin(m *Message, arg ...string) Server {
|
||||
return ctx
|
||||
}
|
||||
func (ctx *CTX) Start(m *Message, arg ...string) bool {
|
||||
m.Cmd("ctx._init")
|
||||
if m.Optionv("ps_target", Index); len(arg) == 0 {
|
||||
m.Option("cli.modal", "active")
|
||||
if m.Optionv("bio.ctx", Index); len(arg) == 0 {
|
||||
m.Option("bio.modal", "active")
|
||||
m.Option("log.disable", false)
|
||||
m.Cap("stream", "shy")
|
||||
m.Cap("stream", "stdio")
|
||||
m.Cmd("log._init")
|
||||
m.Cmd("yac._init")
|
||||
m.Cmd("gdb._init")
|
||||
m.Cmd("cli.source", m.Conf("system", "script.init")).Cmd("cli.source", "stdio").Cmd("cli.source", m.Conf("system", "script.exit"))
|
||||
|
||||
m.Cmd("ctx._init")
|
||||
m.Cmd("nfs.source", m.Conf("system", "script.init")).Cmd("nfs.source", "stdio").Cmd("nfs.source", m.Conf("system", "script.exit"))
|
||||
} else {
|
||||
m.Option("cli.modal", "action")
|
||||
// m.Cmd("yac._init")
|
||||
for _, v := range m.Spawn().Cmd(arg).Meta["result"] {
|
||||
m.Option("bio.modal", "action")
|
||||
|
||||
m.Cmd("ctx._init")
|
||||
for _, v := range m.Sess("cli").Cmd(arg).Meta["result"] {
|
||||
fmt.Printf("%s", v)
|
||||
}
|
||||
}
|
||||
@ -103,7 +109,8 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
|
||||
},
|
||||
Commands: map[string]*Command{
|
||||
"_init": &Command{Name: "_init", Help: "启动", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
|
||||
for _, x := range []string{"lex", "cli", "nfs", "aaa", "ssh", "web"} {
|
||||
for _, x := range []string{"lex", "cli", "yac", "nfs", "aaa", "ssh", "web"} {
|
||||
kit.Log("error", "%v", x)
|
||||
m.Cmd(x + "._init")
|
||||
}
|
||||
return
|
||||
@ -735,7 +742,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
|
||||
|
||||
"message": &Command{Name: "message [code] [cmd...]", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) {
|
||||
msg := m
|
||||
if ms := m.Find(m.Cap("ps_target")); ms != nil {
|
||||
if ms := m.Find(m.Cap("bio.ctx")); ms != nil {
|
||||
msg = ms
|
||||
}
|
||||
|
||||
@ -816,7 +823,11 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{},
|
||||
keys[k] = true
|
||||
m.Add("append", "key", k)
|
||||
m.Add("append", "len", len(msg.Meta[k]))
|
||||
m.Add("append", "value", fmt.Sprintf("%v", msg.Meta[k]))
|
||||
if _, ok := msg.Data[k]; ok {
|
||||
m.Add("append", "value", kit.Format(msg.Data[k]))
|
||||
} else {
|
||||
m.Add("append", "value", kit.Format(msg.Meta[k]))
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
@ -1420,7 +1431,7 @@ func Start(args ...string) bool {
|
||||
args = args[1:]
|
||||
}
|
||||
if len(args) > 0 && args[0] == "daemon" {
|
||||
Pulse.Options("cli.modal", "daemon")
|
||||
Pulse.Options("bio.modal", "daemon")
|
||||
Pulse.Options("daemon", true)
|
||||
args = args[1:]
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ func (m *Message) Format(arg ...interface{}) string {
|
||||
case "code":
|
||||
meta = append(meta, kit.Format(m.code))
|
||||
case "ship":
|
||||
meta = append(meta, fmt.Sprintf("%s:%d(%s->%s)", m.Option("routine"), m.code, m.source.Name, m.target.Name))
|
||||
meta = append(meta, fmt.Sprintf("%s:%d(%s->%s)", m.Option("ctx.routine"), m.code, m.source.Name, m.target.Name))
|
||||
case "source":
|
||||
target := m.target
|
||||
m.target = m.source
|
||||
@ -535,7 +535,7 @@ func (m *Message) Log(action string, str string, arg ...interface{}) *Message {
|
||||
func (m *Message) Show(str string, args ...interface{}) *Message {
|
||||
res := fmt.Sprintf(str, args...)
|
||||
|
||||
if m.Option("cli.modal") == "action" {
|
||||
if m.Option("bio.modal") == "action" {
|
||||
fmt.Printf(res)
|
||||
} else if kit.STDIO != nil {
|
||||
kit.STDIO.Show(res)
|
||||
@ -631,7 +631,7 @@ func (m *Message) Match(key string, spawn bool, hand func(m *Message, s *Context
|
||||
}
|
||||
|
||||
context := []*Context{m.target}
|
||||
for _, v := range []string{"aaa", "ssh", "cli", "nfs"} {
|
||||
for _, v := range kit.Trans(m.Optionv("ctx.chain")) {
|
||||
if msg := m.Sess(v, false); msg != nil && msg.target != nil {
|
||||
context = append(context, msg.target)
|
||||
}
|
@ -281,6 +281,97 @@ func (m *Message) Results(arg ...interface{}) bool {
|
||||
return kit.Right(m.Result(arg...))
|
||||
}
|
||||
|
||||
func (m *Message) Form(x *Command, arg []string) []string {
|
||||
for _, form := range []map[string]int{m.Optionv("ctx.form").(map[string]int), x.Form} {
|
||||
|
||||
if args := []string{}; form != nil {
|
||||
for i := 0; i < len(arg); i++ {
|
||||
if n, ok := form[arg[i]]; ok {
|
||||
if n < 0 {
|
||||
n += len(arg) - i
|
||||
}
|
||||
for j := i + 1; j <= i+n && j < len(arg); j++ {
|
||||
if _, ok := form[arg[j]]; ok {
|
||||
n = j - i - 1
|
||||
}
|
||||
}
|
||||
if i+1+n > len(arg) {
|
||||
m.Add("option", arg[i], arg[i+1:])
|
||||
} else {
|
||||
m.Add("option", arg[i], arg[i+1:i+1+n])
|
||||
}
|
||||
i += n
|
||||
} else {
|
||||
args = append(args, arg[i])
|
||||
}
|
||||
}
|
||||
arg = args
|
||||
}
|
||||
}
|
||||
|
||||
return arg
|
||||
}
|
||||
func (m *Message) Push(str string, arg ...interface{}) *Message {
|
||||
return m.Add("append", str, arg...)
|
||||
}
|
||||
func (m *Message) Sort(key string, arg ...string) *Message {
|
||||
cmp := "str"
|
||||
if len(arg) > 0 {
|
||||
cmp = arg[0]
|
||||
}
|
||||
|
||||
number := map[int]int{}
|
||||
table := []map[string]string{}
|
||||
m.Table(func(index int, line map[string]string) {
|
||||
table = append(table, line)
|
||||
switch cmp {
|
||||
case "int":
|
||||
number[index] = kit.Int(line[key])
|
||||
case "int_r":
|
||||
number[index] = -kit.Int(line[key])
|
||||
case "time":
|
||||
number[index] = kit.Time(line[key])
|
||||
case "time_r":
|
||||
number[index] = -kit.Time(line[key])
|
||||
}
|
||||
})
|
||||
|
||||
for i := 0; i < len(table)-1; i++ {
|
||||
for j := i + 1; j < len(table); j++ {
|
||||
result := false
|
||||
switch cmp {
|
||||
case "str":
|
||||
if table[i][key] > table[j][key] {
|
||||
result = true
|
||||
}
|
||||
case "str_r":
|
||||
if table[i][key] < table[j][key] {
|
||||
result = true
|
||||
}
|
||||
default:
|
||||
if number[i] > number[j] {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
|
||||
if result {
|
||||
table[i], table[j] = table[j], table[i]
|
||||
number[i], number[j] = number[j], number[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, k := range m.Meta["append"] {
|
||||
delete(m.Meta, k)
|
||||
}
|
||||
|
||||
for _, v := range table {
|
||||
for _, k := range m.Meta["append"] {
|
||||
m.Add("append", k, v[k])
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
func (m *Message) Table(cbs ...interface{}) *Message {
|
||||
if len(m.Meta["append"]) == 0 {
|
||||
return m
|
||||
@ -376,63 +467,11 @@ func (m *Message) Table(cbs ...interface{}) *Message {
|
||||
|
||||
return m
|
||||
}
|
||||
func (m *Message) Sort(key string, arg ...string) *Message {
|
||||
cmp := "str"
|
||||
func (m *Message) Echo(str string, arg ...interface{}) *Message {
|
||||
if len(arg) > 0 {
|
||||
cmp = arg[0]
|
||||
return m.Add("result", fmt.Sprintf(str, arg...))
|
||||
}
|
||||
|
||||
number := map[int]int{}
|
||||
table := []map[string]string{}
|
||||
m.Table(func(index int, line map[string]string) {
|
||||
table = append(table, line)
|
||||
switch cmp {
|
||||
case "int":
|
||||
number[index] = kit.Int(line[key])
|
||||
case "int_r":
|
||||
number[index] = -kit.Int(line[key])
|
||||
case "time":
|
||||
number[index] = kit.Time(line[key])
|
||||
case "time_r":
|
||||
number[index] = -kit.Time(line[key])
|
||||
}
|
||||
})
|
||||
|
||||
for i := 0; i < len(table)-1; i++ {
|
||||
for j := i + 1; j < len(table); j++ {
|
||||
result := false
|
||||
switch cmp {
|
||||
case "str":
|
||||
if table[i][key] > table[j][key] {
|
||||
result = true
|
||||
}
|
||||
case "str_r":
|
||||
if table[i][key] < table[j][key] {
|
||||
result = true
|
||||
}
|
||||
default:
|
||||
if number[i] > number[j] {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
|
||||
if result {
|
||||
table[i], table[j] = table[j], table[i]
|
||||
number[i], number[j] = number[j], number[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, k := range m.Meta["append"] {
|
||||
delete(m.Meta, k)
|
||||
}
|
||||
|
||||
for _, v := range table {
|
||||
for _, k := range m.Meta["append"] {
|
||||
m.Add("append", k, v[k])
|
||||
}
|
||||
}
|
||||
return m
|
||||
return m.Add("result", str)
|
||||
}
|
||||
func (m *Message) Copy(msg *Message, arg ...string) *Message {
|
||||
if msg == nil || m == msg {
|
||||
@ -487,15 +526,6 @@ func (m *Message) Copy(msg *Message, arg ...string) *Message {
|
||||
|
||||
return m
|
||||
}
|
||||
func (m *Message) Push(str string, arg ...interface{}) *Message {
|
||||
return m.Add("append", str, arg...)
|
||||
}
|
||||
func (m *Message) Echo(str string, arg ...interface{}) *Message {
|
||||
if len(arg) > 0 {
|
||||
return m.Add("result", fmt.Sprintf(str, arg...))
|
||||
}
|
||||
return m.Add("result", str)
|
||||
}
|
||||
|
||||
func (m *Message) Cmdp(t time.Duration, head []string, prefix []string, suffix [][]string) *Message {
|
||||
if head != nil && len(head) > 0 {
|
||||
@ -571,43 +601,19 @@ func (m *Message) Cmd(args ...interface{}) *Message {
|
||||
if x, ok := c.Commands[key]; ok && x.Hand != nil {
|
||||
msg.TryCatch(msg, true, func(msg *Message) {
|
||||
msg.Log("cmd", "%s %s %v %v", c.Name, key, arg, msg.Meta["option"])
|
||||
|
||||
for _, form := range []map[string]int{map[string]int{"page.limit": 1, "page.offset": 1}, x.Form} {
|
||||
|
||||
if args := []string{}; form != nil {
|
||||
for i := 0; i < len(arg); i++ {
|
||||
if n, ok := form[arg[i]]; ok {
|
||||
if n < 0 {
|
||||
n += len(arg) - i
|
||||
}
|
||||
for j := i + 1; j <= i+n && j < len(arg); j++ {
|
||||
if _, ok := form[arg[j]]; ok {
|
||||
n = j - i - 1
|
||||
}
|
||||
}
|
||||
if i+1+n > len(arg) {
|
||||
msg.Add("option", arg[i], arg[i+1:])
|
||||
} else {
|
||||
msg.Add("option", arg[i], arg[i+1:i+1+n])
|
||||
}
|
||||
i += n
|
||||
} else {
|
||||
args = append(args, arg[i])
|
||||
}
|
||||
}
|
||||
arg = args
|
||||
}
|
||||
}
|
||||
msg.Hand = true
|
||||
x.Hand(msg, c, key, msg.Form(x, arg)...)
|
||||
msg.Log("cmd", "%s %s %v %v", c.Name, key, len(msg.Meta["result"]), msg.Meta["append"])
|
||||
return
|
||||
|
||||
target := msg.target
|
||||
msg.target = s
|
||||
|
||||
msg.Hand = true
|
||||
switch v := msg.Gdb("command", key, arg).(type) {
|
||||
case string:
|
||||
msg.Echo(v)
|
||||
case nil:
|
||||
if msg.Options("auto_cmd") {
|
||||
if msg.Options("bio.cmd") {
|
||||
if x.Auto != nil {
|
||||
x.Auto(msg, c, key, arg...)
|
||||
}
|
||||
|
@ -22,11 +22,12 @@ type State struct {
|
||||
next int
|
||||
hash int
|
||||
}
|
||||
|
||||
type LEX struct {
|
||||
seed []*Seed
|
||||
hash map[string]int
|
||||
hashs map[int]string
|
||||
pages map[int]string
|
||||
word map[int]string
|
||||
hand map[int]string
|
||||
page map[string]int
|
||||
|
||||
char map[byte][]byte
|
||||
@ -36,10 +37,16 @@ type LEX struct {
|
||||
*ctx.Context
|
||||
}
|
||||
|
||||
func (lex *LEX) charset(c byte) []byte {
|
||||
if cs, ok := lex.char[c]; ok {
|
||||
return cs
|
||||
}
|
||||
return []byte{c}
|
||||
}
|
||||
func (lex *LEX) index(m *ctx.Message, hash string, h string) int {
|
||||
which, names := lex.hash, lex.hashs
|
||||
which, names := lex.hash, lex.word
|
||||
if hash == "npage" {
|
||||
which, names = lex.page, lex.pages
|
||||
which, names = lex.page, lex.hand
|
||||
}
|
||||
|
||||
if x, e := strconv.Atoi(h); e == nil {
|
||||
@ -60,12 +67,6 @@ func (lex *LEX) index(m *ctx.Message, hash string, h string) int {
|
||||
m.Assert(hash != "npage" || m.Capi("npage") < m.Confi("meta", "nlang"), "语法集合超过上限")
|
||||
return which[h]
|
||||
}
|
||||
func (lex *LEX) charset(c byte) []byte {
|
||||
if cs, ok := lex.char[c]; ok {
|
||||
return cs
|
||||
}
|
||||
return []byte{c}
|
||||
}
|
||||
func (lex *LEX) train(m *ctx.Message, page int, hash int, seed []byte) int {
|
||||
m.Log("debug", "%s %s page: %v hash: %v seed: %v", "train", "lex", page, hash, string(seed))
|
||||
|
||||
@ -288,8 +289,8 @@ func (lex *LEX) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||
|
||||
lex.page = map[string]int{"nil": 0}
|
||||
lex.hash = map[string]int{"nil": 0}
|
||||
lex.hashs = map[int]string{0: "nil"}
|
||||
lex.pages = map[int]string{0: "nil"}
|
||||
lex.word = map[int]string{0: "nil"}
|
||||
lex.hand = map[int]string{0: "nil"}
|
||||
|
||||
lex.char = map[byte][]byte{
|
||||
't': []byte{'\t'},
|
||||
@ -376,7 +377,7 @@ var Index = &ctx.Context{Name: "lex", Help: "词法中心",
|
||||
}
|
||||
|
||||
m.Push("word", string(word))
|
||||
m.Push("hash", lex.hashs[hash])
|
||||
m.Push("hash", lex.word[hash])
|
||||
m.Push("rest", string(rest))
|
||||
input = rest
|
||||
}
|
||||
@ -387,40 +388,34 @@ var Index = &ctx.Context{Name: "lex", Help: "词法中心",
|
||||
"show": &ctx.Command{Name: "show seed|page|hash|mat|node", Help: "查看信息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) {
|
||||
if len(arg) == 0 {
|
||||
m.Append("seed", len(lex.seed))
|
||||
m.Append("page", len(lex.page))
|
||||
m.Append("hash", len(lex.hash))
|
||||
m.Append("nmat", len(lex.mat))
|
||||
m.Append("node", len(lex.state))
|
||||
m.Push("seed", len(lex.seed))
|
||||
m.Push("page", len(lex.page))
|
||||
m.Push("hash", len(lex.hash))
|
||||
m.Push("nmat", len(lex.mat))
|
||||
m.Push("node", len(lex.state))
|
||||
m.Table()
|
||||
return
|
||||
}
|
||||
switch arg[0] {
|
||||
case "seed":
|
||||
for _, v := range lex.seed {
|
||||
m.Push("page", fmt.Sprintf("%s", lex.pages[v.page]))
|
||||
m.Push("word", fmt.Sprintf("%s", strings.Replace(strings.Replace(v.word, "\n", "\\n", -1), "\t", "\\t", -1)))
|
||||
m.Push("hash", fmt.Sprintf("%s", lex.hashs[v.hash]))
|
||||
m.Push("page", lex.hand[v.page])
|
||||
m.Push("word", strings.Replace(strings.Replace(v.word, "\n", "\\n", -1), "\t", "\\t", -1))
|
||||
m.Push("hash", lex.word[v.hash])
|
||||
}
|
||||
m.Sort("page", "int").Table()
|
||||
|
||||
case "page":
|
||||
for k, v := range lex.page {
|
||||
if k == "nil" {
|
||||
continue
|
||||
}
|
||||
m.Push("page", k)
|
||||
m.Push("code", fmt.Sprintf("%d", v))
|
||||
m.Push("code", v)
|
||||
}
|
||||
m.Sort("code", "int").Table()
|
||||
|
||||
case "hash":
|
||||
for k, v := range lex.hash {
|
||||
if k == "nil" {
|
||||
continue
|
||||
}
|
||||
m.Push("hash", k)
|
||||
m.Push("code", fmt.Sprintf("%d", v))
|
||||
m.Push("code", v)
|
||||
}
|
||||
m.Sort("code", "int").Table()
|
||||
|
||||
@ -435,7 +430,7 @@ var Index = &ctx.Context{Name: "lex", Help: "词法中心",
|
||||
case "mat":
|
||||
for i, v := range lex.mat {
|
||||
if i <= m.Capi("npage") {
|
||||
m.Push("index", lex.pages[i])
|
||||
m.Push("index", lex.hand[i])
|
||||
} else if i < m.Confi("meta", "nlang") {
|
||||
continue
|
||||
} else {
|
||||
|
@ -265,7 +265,7 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
|
||||
"db": &ctx.Command{Name: "db [which]", Help: "查看或选择数据库",
|
||||
Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool {
|
||||
if len(arg) == 0 {
|
||||
m.Put("option", "auto_cmd", "").Spawn().Cmd("query", "show databases").Table(func(line map[string]string) {
|
||||
m.Put("option", "bio.cmd", "").Spawn().Cmd("query", "show databases").Table(func(line map[string]string) {
|
||||
for _, v := range line {
|
||||
m.Auto(v, "", "")
|
||||
}
|
||||
@ -287,13 +287,13 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
|
||||
Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool {
|
||||
switch len(arg) {
|
||||
case 0:
|
||||
m.Put("option", "auto_cmd", "").Spawn().Cmd("query", "show tables").Table(func(line map[string]string) {
|
||||
m.Put("option", "bio.cmd", "").Spawn().Cmd("query", "show tables").Table(func(line map[string]string) {
|
||||
for _, v := range line {
|
||||
m.Auto(v, "", "")
|
||||
}
|
||||
})
|
||||
case 1:
|
||||
m.Put("option", "auto_cmd", "").Spawn().Cmd("query", fmt.Sprintf("desc %s", arg[0])).Table(func(line map[string]string) {
|
||||
m.Put("option", "bio.cmd", "").Spawn().Cmd("query", fmt.Sprintf("desc %s", arg[0])).Table(func(line map[string]string) {
|
||||
m.Auto(line["Field"], line["Type"], line["Default"])
|
||||
})
|
||||
}
|
||||
@ -314,7 +314,7 @@ var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
|
||||
Form: map[string]int{"where": 1, "eq": 2, "like": 2, "in": 2, "begin": 2, "group": 1, "order": 1, "desc": 0, "limit": 1, "offset": 1, "other": -1},
|
||||
Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool {
|
||||
if len(arg) == 0 {
|
||||
m.Put("option", "auto_cmd", "").Spawn().Cmd("query", "show tables").Table(func(line map[string]string) {
|
||||
m.Put("option", "bio.cmd", "").Spawn().Cmd("query", "show tables").Table(func(line map[string]string) {
|
||||
for _, v := range line {
|
||||
m.Auto(v, "", "")
|
||||
}
|
||||
|
@ -191,11 +191,10 @@ func (nfs *NFS) Read(p []byte) (n int, err error) {
|
||||
rest := make([]rune, 0, 1024)
|
||||
back := make([]rune, 0, 1024)
|
||||
|
||||
m.Optionv("auto_target", m.Optionv("ps_target"))
|
||||
m.Option("auto_cmd", "")
|
||||
m.Options("show_shadow", m.Confs("show_shadow"))
|
||||
m.Option("bio.cmd", "")
|
||||
m.Options("bio.shadow", m.Confs("show_shadow"))
|
||||
|
||||
defer func() { m.Option("auto_cmd", "") }()
|
||||
defer func() { m.Option("bio.cmd", "") }()
|
||||
|
||||
frame, table, index, pick := map[string]interface{}{}, []map[string]string{}, 0, 0
|
||||
if change, f, t, i := nfs.Auto(what, ":", 0); change {
|
||||
@ -358,13 +357,13 @@ func (nfs *NFS) Read(p []byte) (n int, err error) {
|
||||
|
||||
case termbox.KeyCtrlG:
|
||||
case termbox.KeyCtrlX:
|
||||
m.Options("show_shadow", !m.Options("show_shadow"))
|
||||
m.Options("bio.shadow", !m.Options("bio.shadow"))
|
||||
case termbox.KeyCtrlS:
|
||||
|
||||
case termbox.KeyCtrlZ:
|
||||
|
||||
case termbox.KeyTab:
|
||||
m.Options("show_shadow", true)
|
||||
m.Options("bio.shadow", true)
|
||||
// if index > len(what) {
|
||||
// nfs.shadow("", table, frame)
|
||||
// } else {
|
||||
@ -380,7 +379,7 @@ func (nfs *NFS) Read(p []byte) (n int, err error) {
|
||||
case termbox.KeySpace:
|
||||
what = append(what, ' ')
|
||||
nfs.prompt(what).shadow(rest)
|
||||
if !m.Options("show_shadow") {
|
||||
if !m.Options("bio.shadow") {
|
||||
break
|
||||
}
|
||||
|
||||
@ -402,7 +401,7 @@ func (nfs *NFS) Read(p []byte) (n int, err error) {
|
||||
default:
|
||||
what = append(what, ev.Ch)
|
||||
nfs.prompt(what).shadow(rest)
|
||||
if !m.Options("show_shadow") {
|
||||
if !m.Options("bio.shadow") {
|
||||
break
|
||||
}
|
||||
|
||||
@ -428,9 +427,10 @@ func (nfs *NFS) Read(p []byte) (n int, err error) {
|
||||
return
|
||||
}
|
||||
func (nfs *NFS) Auto(what []rune, trigger string, index int) (change bool, frame map[string]interface{}, table []map[string]string, nindex int) {
|
||||
return
|
||||
m := nfs.Context.Message()
|
||||
|
||||
auto_target := m.Optionv("auto_target").(*ctx.Context)
|
||||
auto_target := m.Optionv("bio.ctx").(*ctx.Context)
|
||||
auto_cmd := ""
|
||||
auto_arg := []string{}
|
||||
|
||||
@ -439,14 +439,14 @@ func (nfs *NFS) Auto(what []rune, trigger string, index int) (change bool, frame
|
||||
switch m.Conf("term", "help_state") {
|
||||
case "context":
|
||||
auto_target = auto_target.Sub(m.Option("auto_key"))
|
||||
m.Optionv("auto_target", auto_target)
|
||||
m.Optionv("bio.ctx", auto_target)
|
||||
trigger = ":"
|
||||
case "command":
|
||||
m.Option("arg_index", index)
|
||||
auto_cmd = m.Option("auto_cmd", m.Option("auto_key"))
|
||||
auto_cmd = m.Option("bio.cmd", m.Option("auto_key"))
|
||||
trigger = "="
|
||||
case "argument":
|
||||
auto_cmd = m.Option("auto_cmd")
|
||||
auto_cmd = m.Option("bio.cmd")
|
||||
auto_arg = strings.Split(strings.TrimSpace(string(what[m.Optioni("arg_index"):])), " ")
|
||||
trigger = "="
|
||||
}
|
||||
@ -720,7 +720,7 @@ func (nfs *NFS) Term(msg *ctx.Message, action string, args ...interface{}) *NFS
|
||||
}
|
||||
func (nfs *NFS) prompt(arg ...interface{}) *NFS {
|
||||
m := nfs.Context.Message()
|
||||
target, _ := m.Optionv("ps_target").(*ctx.Context)
|
||||
target, _ := m.Optionv("bio.ctx").(*ctx.Context)
|
||||
if target == nil {
|
||||
target = nfs.Context
|
||||
}
|
||||
@ -783,10 +783,10 @@ func (nfs *NFS) shadow(args ...interface{}) *NFS {
|
||||
|
||||
return nfs
|
||||
}
|
||||
func (nfs *NFS) printf(arg ...interface{}) *NFS {
|
||||
func (nfs *NFS) print(arg ...string) *NFS {
|
||||
m := nfs.Context.Message()
|
||||
|
||||
line := strings.TrimRight(kit.Format(arg...), "\n")
|
||||
line := strings.TrimRight(strings.Join(arg, ""), "\n")
|
||||
m.Log("debug", "noutput %s", m.Cap("noutput", m.Capi("noutput")+1))
|
||||
m.Confv("output", -2, map[string]interface{}{"time": time.Now().Unix(), "line": line})
|
||||
|
||||
@ -900,16 +900,6 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
|
||||
}
|
||||
|
||||
if len(arg) > 0 && arg[0] == "scan" {
|
||||
// 终端用户
|
||||
m.Cmd("aaa.role", "root", "user", m.Option("username", m.Conf("runtime", "boot.username")))
|
||||
|
||||
// 创建会话
|
||||
m.Option("sessid", m.Cmdx("aaa.user", "session", "select"))
|
||||
|
||||
// 创建空间
|
||||
m.Option("bench", m.Cmdx("aaa.sess", "bench", "select"))
|
||||
|
||||
// 默认配置
|
||||
m.Cap("stream", arg[1])
|
||||
nfs.Caches["ninput"] = &ctx.Cache{Value: "0"}
|
||||
nfs.Caches["noutput"] = &ctx.Cache{Value: "0"}
|
||||
@ -919,20 +909,28 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
|
||||
nfs.Configs["prompt"] = &ctx.Config{Value: ""}
|
||||
|
||||
// 终端控制
|
||||
if nfs.in = m.Optionv("in").(*os.File); m.Has("out") {
|
||||
if nfs.out = m.Optionv("out").(*os.File); m.Conf("runtime", "host.GOOS") != "windows" && !m.Options("daemon") {
|
||||
kit.STDIO = nfs
|
||||
nfs.Term(m, "init")
|
||||
m.Conf("term", "use", true)
|
||||
if nfs.in = m.Optionv("bio.in").(*os.File); m.Has("bio.out") {
|
||||
if nfs.out = m.Optionv("bio.out").(*os.File); m.Conf("runtime", "host.GOOS") != "windows" && !m.Options("daemon") {
|
||||
m.Conf("term", "use", nfs.Term(m, "init") != nil)
|
||||
defer nfs.Term(m, "exit")
|
||||
}
|
||||
if what := make(chan bool); m.Options("daemon") {
|
||||
<-what
|
||||
kit.STDIO = nfs
|
||||
|
||||
} else if m.Options("daemon") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// 终端用户
|
||||
m.Cmd("aaa.role", "root", "user", m.Option("username", m.Conf("runtime", "boot.username")))
|
||||
m.Option("sessid", m.Cmdx("aaa.user", "session", "select"))
|
||||
m.Optionv("bio.ctx", m.Target())
|
||||
stack := kit.Stack{}
|
||||
stack.Push(m.Option("stack.key", "source"), m.Options("stack.run", true), m.Optioni("stack.pos", 0))
|
||||
|
||||
line, bio := "", bufio.NewScanner(nfs)
|
||||
for nfs.prompt(); !m.Options("scan_end"); nfs.prompt() {
|
||||
for nfs.prompt(); ; nfs.prompt() {
|
||||
|
||||
// 读取数据
|
||||
for bio.Scan() {
|
||||
if text := bio.Text(); text == "" {
|
||||
continue
|
||||
@ -944,31 +942,66 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
|
||||
}
|
||||
}
|
||||
if line == "" {
|
||||
line = "return"
|
||||
break
|
||||
}
|
||||
|
||||
m.Log("debug", "%s %d %d [%s]", "input", m.Capi("ninput", 1), len(line), line)
|
||||
m.Confv("input", -2, map[string]interface{}{"time": time.Now().Unix(), "line": line})
|
||||
|
||||
// 解析数据
|
||||
for i := m.Capi("ninput") - 1; i < m.Capi("ninput"); i++ {
|
||||
line = m.Conf("input", []interface{}{i, "line"})
|
||||
|
||||
msg := m.Backs(m.Spawn(m.Source()).Set(
|
||||
"detail", line).Set(
|
||||
"option", "file_pos", i).Set(
|
||||
"option", "username", m.Conf("runtime", "boot.username")))
|
||||
// 结束语句
|
||||
if strings.TrimSpace(line) == "end" {
|
||||
m.Log("stack", " pop %v", stack.Peek().String("/"))
|
||||
if stack.Pop(); m.Options("stack.run") && m.Option("stack.key") == "for" {
|
||||
i = m.Optioni("stack.pos") - 1
|
||||
}
|
||||
frame := stack.Peek()
|
||||
m.Options("stack.run", frame.Run)
|
||||
m.Option("stack.key", frame.Key)
|
||||
continue
|
||||
}
|
||||
|
||||
nfs.printf(m.Conf("prompt"), line)
|
||||
nfs.printf(msg.Meta["result"])
|
||||
// 跳过语句
|
||||
if !stack.Peek().Run {
|
||||
m.Log("stack", "skip %v", line)
|
||||
continue
|
||||
}
|
||||
|
||||
if msg.Appends("file_pos0") {
|
||||
i = int(msg.Appendi("file_pos0")) - 1
|
||||
msg.Append("file_pos0", "")
|
||||
// 执行语句
|
||||
msg := m.Cmd("yac.parse", line+"\n").Set("option", "bio.pos", i)
|
||||
nfs.print(m.Conf("prompt"), line)
|
||||
nfs.print(msg.Meta["result"]...)
|
||||
|
||||
// 切换模块
|
||||
if v := msg.Optionv("bio.ctx"); v != nil {
|
||||
m.Optionv("bio.ctx", v)
|
||||
}
|
||||
|
||||
// 压栈语句
|
||||
if msg.Appends("stack.key") {
|
||||
stack.Push(m.Option("stack.key", msg.Append("stack.key")), m.Options("stack.run", msg.Appends("stack.run")), m.Optioni("stack.pos", i))
|
||||
m.Log("stack", "push %v", stack.Peek().String("\\"))
|
||||
msg.Append("stack.key", "")
|
||||
}
|
||||
|
||||
// 跳转语句
|
||||
if msg.Appends("bio.pos0") {
|
||||
i = int(msg.Appendi("bio.pos0")) - 1
|
||||
msg.Append("bio.pos0", "")
|
||||
}
|
||||
|
||||
// 结束脚本
|
||||
if msg.Appends("bio.end") {
|
||||
m.Copy(msg, "append")
|
||||
m.Copy(msg, "result")
|
||||
break
|
||||
}
|
||||
}
|
||||
line = ""
|
||||
}
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
m.Cap("stream", m.Option("ms_source"))
|
||||
@ -1775,7 +1808,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
||||
}
|
||||
|
||||
m.Start(fmt.Sprintf("file%d", m.Capi("nfile")), fmt.Sprintf("file %s", arg[0]), "open", arg[0])
|
||||
m.Append("ps_target1", m.Cap("module"))
|
||||
m.Append("bio.ctx1", m.Cap("module"))
|
||||
m.Echo(m.Cap("module"))
|
||||
return
|
||||
}},
|
||||
@ -1819,19 +1852,9 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
||||
return
|
||||
}},
|
||||
|
||||
"scan": &ctx.Command{Name: "scan file name", Help: "扫描文件, file: 文件名, name: 模块名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if _, ok := m.Target().Server.(*NFS); m.Assert(ok) {
|
||||
if help := fmt.Sprintf("scan %s", arg[0]); arg[0] == "stdio" {
|
||||
m.Put("option", "in", os.Stdin).Put("option", "out", os.Stdout).Start(arg[0], help, key, arg[0])
|
||||
} else if p, f, e := open(m, arg[0]); m.Assert(e) {
|
||||
m.Put("option", "in", f).Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), help, key, p)
|
||||
}
|
||||
}
|
||||
return
|
||||
}},
|
||||
"printf": &ctx.Command{Name: "printf arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
|
||||
nfs.printf(arg)
|
||||
nfs.print(arg...)
|
||||
}
|
||||
return
|
||||
}},
|
||||
@ -1850,8 +1873,8 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
||||
"action": &ctx.Command{Name: "action cmd", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
|
||||
msg := m.Cmd("cli.source", arg)
|
||||
nfs.printf(msg.Conf("prompt"), arg, "\n")
|
||||
nfs.printf(msg.Meta["result"])
|
||||
// nfs.print(msg.Conf("prompt"), arg, "\n")
|
||||
nfs.print(msg.Meta["result"]...)
|
||||
}
|
||||
return
|
||||
}},
|
||||
@ -1876,6 +1899,103 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
||||
}
|
||||
return
|
||||
}},
|
||||
|
||||
"source": &ctx.Command{Name: "source [script|stdio|snippet]", Help: "解析脚本, script: 脚本文件, stdio: 命令终端, snippet: 代码片段", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if _, ok := m.Target().Server.(*NFS); m.Assert(ok) {
|
||||
m.Optionv("bio.args", arg)
|
||||
if help := fmt.Sprintf("scan %s", arg[0]); arg[0] == "stdio" {
|
||||
m.Put("option", "bio.in", os.Stdin).Put("option", "bio.out", os.Stdout).Start(arg[0], help, "scan", arg[0])
|
||||
m.Wait()
|
||||
|
||||
} else if p, f, e := open(m, arg[0]); e == nil {
|
||||
m.Put("option", "bio.in", f).Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), help, "scan", p)
|
||||
m.Wait()
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
return
|
||||
if len(arg) == 0 {
|
||||
m.Cmdy("dir", "", "dir_deep", "dir_reg", ".*\\.(sh|shy|py)$")
|
||||
return
|
||||
}
|
||||
|
||||
m.Cap("stream", m.Sess("yac").Call(func(cmd *ctx.Message) *ctx.Message {
|
||||
if !m.Caps("parse") {
|
||||
switch cmd.Detail(0) {
|
||||
case "if":
|
||||
cmd.Set("detail", "if", "false")
|
||||
case "else":
|
||||
case "end":
|
||||
case "for":
|
||||
default:
|
||||
cmd.Hand = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if cmd.Cmd(); cmd.Has("return") {
|
||||
m.Options("scan_end", true)
|
||||
m.Target().Close(m)
|
||||
}
|
||||
|
||||
v := cmd.Optionv("bio.ctx")
|
||||
if v != nil {
|
||||
m.Optionv("bio.ctx", v)
|
||||
}
|
||||
return nil
|
||||
}, "scan", arg).Target().Name)
|
||||
|
||||
// 解析脚本文件
|
||||
if p := m.Cmdx("nfs.path", arg[0]); p != "" && strings.Contains(p, ".") {
|
||||
arg[0] = p
|
||||
switch path.Ext(p) {
|
||||
case "":
|
||||
case ".shy":
|
||||
m.Option("scan_end", "false")
|
||||
m.Start(fmt.Sprintf("shell%d", m.Capi("nshell", 1)), "shell", arg...)
|
||||
m.Wait()
|
||||
default:
|
||||
m.Cmdy("system", m.Conf("system", []string{"script", strings.TrimPrefix(path.Ext(p), ".")}), arg)
|
||||
}
|
||||
m.Append("directory", "")
|
||||
return
|
||||
}
|
||||
|
||||
// 解析终端命令
|
||||
if arg[0] == "stdio" {
|
||||
m.Option("scan_end", "false")
|
||||
m.Start("shy", "shell", "stdio", "engine")
|
||||
m.Wait()
|
||||
return
|
||||
}
|
||||
|
||||
text := strings.Join(arg, " ")
|
||||
if !strings.HasPrefix(text, "sess") && m.Options("remote") {
|
||||
text = m.Current(text)
|
||||
}
|
||||
|
||||
// 解析代码片段
|
||||
m.Sess("yac").Call(func(msg *ctx.Message) *ctx.Message {
|
||||
switch msg.Cmd().Detail(0) {
|
||||
case "cmd":
|
||||
m.Set("append").Copy(msg, "append")
|
||||
m.Set("result").Copy(msg, "result")
|
||||
}
|
||||
return nil
|
||||
}, "parse", "line", "void", text)
|
||||
return
|
||||
}},
|
||||
"arguments": &ctx.Command{Name: "arguments", Help: "脚本参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
args := kit.Trans(m.Optionv("bio.args"))
|
||||
if len(arg) == 0 {
|
||||
m.Set("result", args)
|
||||
} else {
|
||||
m.Echo(kit.Select("", args, kit.Int(arg[0])))
|
||||
}
|
||||
return
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,11 @@ package yac
|
||||
import (
|
||||
"contexts/ctx"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"toolkit"
|
||||
)
|
||||
|
||||
type Seed struct {
|
||||
@ -12,26 +15,28 @@ type Seed struct {
|
||||
hash int
|
||||
word []string
|
||||
}
|
||||
type State struct {
|
||||
next int
|
||||
star int
|
||||
hash int
|
||||
}
|
||||
type Point struct {
|
||||
s int
|
||||
c byte
|
||||
}
|
||||
type State struct {
|
||||
star int
|
||||
next int
|
||||
hash int
|
||||
}
|
||||
type YAC struct {
|
||||
seed []*Seed
|
||||
page map[string]int
|
||||
word map[int]string
|
||||
hash map[string]int
|
||||
hand map[int]string
|
||||
hash map[string]int
|
||||
|
||||
mat []map[byte]*State
|
||||
state map[State]*State
|
||||
mat []map[byte]*State
|
||||
|
||||
lex *ctx.Message
|
||||
|
||||
label map[string]string
|
||||
*ctx.Context
|
||||
}
|
||||
|
||||
@ -41,6 +46,21 @@ func (yac *YAC) name(page int) string {
|
||||
}
|
||||
return fmt.Sprintf("yac%d", page)
|
||||
}
|
||||
func (yac *YAC) index(m *ctx.Message, hash string, h string) int {
|
||||
which, names := yac.page, yac.word
|
||||
if hash == "nhash" {
|
||||
which, names = yac.hash, yac.hand
|
||||
}
|
||||
|
||||
if x, ok := which[h]; ok {
|
||||
return x
|
||||
}
|
||||
|
||||
which[h] = m.Capi(hash, 1)
|
||||
names[which[h]] = h
|
||||
m.Assert(hash != "npage" || m.Capi("npage") < m.Confi("meta", "nlang"), "语法集合超过上限")
|
||||
return which[h]
|
||||
}
|
||||
func (yac *YAC) train(m *ctx.Message, page, hash int, word []string, level int) (int, []*Point, []*Point) {
|
||||
m.Log("debug", "%s %s\\%d page: %v hash: %v word: %v", "train", strings.Repeat("#", level), level, page, hash, word)
|
||||
|
||||
@ -127,7 +147,7 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string, level int)
|
||||
}
|
||||
}
|
||||
for _, s := range ss {
|
||||
if s < m.Confi("info", "nlang") || s >= len(yac.mat) {
|
||||
if s < m.Confi("meta", "nlang") || s >= len(yac.mat) {
|
||||
continue
|
||||
}
|
||||
void := true
|
||||
@ -171,127 +191,152 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string, level int)
|
||||
m.Log("debug", "%s %s/%d word: %d point: %d end: %d", "train", strings.Repeat("#", level), level, len(word), len(points), len(ends))
|
||||
return len(word), points, ends
|
||||
}
|
||||
func (yac *YAC) parse(m *ctx.Message, out *ctx.Message, page int, void int, line string, level int) (string, []string, int) {
|
||||
func (yac *YAC) parse(m *ctx.Message, msg *ctx.Message, page int, void int, line string, level int) (string, []string, int) {
|
||||
m.Log("debug", "%s %s\\%d %s(%d): %s", "parse", strings.Repeat("#", level), level, yac.name(page), page, line)
|
||||
|
||||
hash, word := 0, []string{}
|
||||
lex, hash, word := yac.lex, 0, []string{}
|
||||
for star, s := 0, page; s != 0 && len(line) > 0; {
|
||||
//解析空白
|
||||
lex := yac.lex.Spawn()
|
||||
if lex.Cmd("parse", line, yac.name(void)); lex.Result(0) == "-1" {
|
||||
if lex = yac.lex.Spawn().Cmd("parse", line, yac.name(void)); lex.Result(0) == "-1" {
|
||||
break
|
||||
}
|
||||
//解析单词
|
||||
line = lex.Result(1)
|
||||
lex = yac.lex.Spawn()
|
||||
if lex.Cmd("parse", line, yac.name(s)); lex.Result(0) == "-1" {
|
||||
|
||||
//解析单词
|
||||
if lex = yac.lex.Spawn().Cmd("parse", line, yac.name(s)); lex.Result(0) == "-1" {
|
||||
break
|
||||
}
|
||||
//解析状态
|
||||
result := append([]string{}, lex.Meta["result"]...)
|
||||
i, _ := strconv.Atoi(result[0])
|
||||
c := byte(i)
|
||||
state := yac.mat[s][c]
|
||||
if state != nil { //全局语法检查
|
||||
|
||||
//解析状态
|
||||
state := yac.mat[s][byte(kit.Int(result[0]))]
|
||||
|
||||
//全局语法检查
|
||||
if state != nil {
|
||||
if key := yac.lex.Spawn().Cmd("parse", line, "key"); key.Resulti(0) == 0 || len(key.Result(2)) <= len(result[2]) {
|
||||
line, word = result[1], append(word, result[2])
|
||||
} else {
|
||||
state = nil
|
||||
}
|
||||
}
|
||||
if state == nil { //嵌套语法递归解析
|
||||
for i := 0; i < m.Confi("info", "ncell"); i++ {
|
||||
if x := yac.mat[s][byte(i)]; i < m.Confi("info", "nlang") && x != nil {
|
||||
if l, w, _ := yac.parse(m, out, i, void, line, level+1); l != line {
|
||||
line, word = l, append(word, w...)
|
||||
state = x
|
||||
//嵌套语法递归解析
|
||||
if state == nil {
|
||||
for i := 0; i < m.Confi("meta", "ncell"); i++ {
|
||||
if x := yac.mat[s][byte(i)]; i < m.Confi("meta", "nlang") && x != nil {
|
||||
if l, w, _ := yac.parse(m, msg, i, void, line, level+1); l != line {
|
||||
line, word, state = l, append(word, w...), x
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if state == nil { //语法切换
|
||||
|
||||
//语法切换
|
||||
if state == nil {
|
||||
s, star = star, 0
|
||||
continue
|
||||
}
|
||||
if s, star, hash = state.next, state.star, state.hash; s == 0 { //状态切换
|
||||
} else if s, star, hash = state.next, state.star, state.hash; s == 0 {
|
||||
s, star = star, 0
|
||||
}
|
||||
}
|
||||
|
||||
if hash == 0 {
|
||||
word = word[:0]
|
||||
|
||||
} else if !m.Confs("exec", []string{yac.hand[hash], "disable"}) { //执行命令
|
||||
msg := out.Spawn(m.Source()).Add("detail", yac.hand[hash], word)
|
||||
if m.Back(msg); msg.Hand { //命令替换
|
||||
word = msg.Meta["result"]
|
||||
cmd := msg.Spawn(m.Optionv("bio.ctx"))
|
||||
if cmd.Cmd(yac.hand[hash], word); cmd.Hand {
|
||||
word = cmd.Meta["result"]
|
||||
}
|
||||
if v := cmd.Optionv("bio.ctx"); v != nil {
|
||||
m.Optionv("bio.ctx", v)
|
||||
}
|
||||
}
|
||||
|
||||
m.Log("debug", "%s %s/%d %s(%d): %v", "parse", strings.Repeat("#", level), level, yac.name(page), page, word)
|
||||
m.Log("debug", "%s %s/%d %s(%d): %v", "parse", strings.Repeat("#", level), level, yac.hand[hash], hash, word)
|
||||
return line, word, hash
|
||||
}
|
||||
|
||||
func (yac *YAC) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
|
||||
if len(arg) > 0 && arg[0] == "scan" {
|
||||
return yac
|
||||
}
|
||||
|
||||
return &YAC{Context: c}
|
||||
}
|
||||
func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||
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: m.Conf("meta", "nlang"), 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: "level", Value: "0", Help: "嵌套层级"}
|
||||
yac.Caches["parse"] = &ctx.Cache{Name: "parse(true/false)", Value: "true", Help: "命令解析"}
|
||||
|
||||
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.state = map[State]*State{}
|
||||
yac.mat = make([]map[byte]*State, m.Capi("nline"))
|
||||
return yac
|
||||
}
|
||||
func (yac *YAC) Start(m *ctx.Message, arg ...string) (close bool) {
|
||||
if len(arg) > 0 && arg[0] == "scan" {
|
||||
m.Cap("stream", arg[1])
|
||||
m.Sess("nfs").Call(func(input *ctx.Message) *ctx.Message {
|
||||
_, word, _ := yac.parse(m, input, m.Optioni("page"), m.Optioni("void"), input.Detail(0)+"\n", 1)
|
||||
input.Result(0, word)
|
||||
return nil
|
||||
}, "scan", arg[1:])
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (yac *YAC) Close(m *ctx.Message, arg ...string) bool {
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
var Index = &ctx.Context{Name: "yac", Help: "语法中心",
|
||||
Caches: map[string]*ctx.Cache{
|
||||
"nparse": &ctx.Cache{Name: "nparse", Value: "0", Help: "解析器数量"},
|
||||
"nshy": &ctx.Cache{Name: "nshy", Value: "0", Help: "引擎数量"},
|
||||
},
|
||||
Configs: map[string]*ctx.Config{
|
||||
"nline": &ctx.Config{Name: "nline", Value: "line", Help: "默认页"},
|
||||
"nvoid": &ctx.Config{Name: "nvoid", Value: "void", Help: "默认值"},
|
||||
"meta": &ctx.Config{Name: "meta", Value: map[string]interface{}{
|
||||
"ncell": 128, "nlang": 64, "compact": true,
|
||||
"name": "shy%d", "help": "engine",
|
||||
}, Help: "初始参数"},
|
||||
"seed": &ctx.Config{Name: "seed", Value: []interface{}{
|
||||
map[string]interface{}{"page": "void", "hash": "void", "word": []interface{}{"[\t ]+"}},
|
||||
|
||||
map[string]interface{}{"page": "key", "hash": "key", "word": []interface{}{"[A-Za-z_][A-Za-z_0-9]*"}},
|
||||
map[string]interface{}{"page": "num", "hash": "num", "word": []interface{}{"mul{", "0", "-?[1-9][0-9]*", "0[0-9]+", "0x[0-9]+", "}"}},
|
||||
map[string]interface{}{"page": "key", "hash": "key", "word": []interface{}{"[A-Za-z_][A-Za-z_0-9]*"}},
|
||||
map[string]interface{}{"page": "str", "hash": "str", "word": []interface{}{"mul{", "\"[^\"]*\"", "'[^']*'", "}"}},
|
||||
map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"mul{", "$", "@", "}", "key"}},
|
||||
map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"mul{", "$", "@", "}", "opt{", "key", "}"}},
|
||||
|
||||
map[string]interface{}{"page": "op1", "hash": "op1", "word": []interface{}{"mul{", "-", "+", "}"}},
|
||||
map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", "+", "-", "*", "/", "%", "}"}},
|
||||
map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", "<", "<=", ">", ">=", "==", "!=", "}"}},
|
||||
map[string]interface{}{"page": "val", "hash": "val", "word": []interface{}{"opt{", "op1", "}", "mul{", "num", "key", "str", "exe", "}"}},
|
||||
map[string]interface{}{"page": "exp", "hash": "exp", "word": []interface{}{"val", "rep{", "op2", "val", "}"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "let", "word": []interface{}{"let", "key", "opt{", "=", "exp", "}"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "var", "word": []interface{}{"var", "key", "opt{", "=", "exp", "}"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "return", "word": []interface{}{"return", "rep{", "exp", "}"}},
|
||||
|
||||
map[string]interface{}{"page": "word", "hash": "word", "word": []interface{}{"mul{", "~", "!", "\\?", "\\?\\?", "exe", "str", "[\\-a-zA-Z0-9_:/.]+", "=", "<", ">$", ">@", ">", "\\|", "%", "}"}},
|
||||
map[string]interface{}{"page": "cmd", "hash": "cmd", "word": []interface{}{"rep{", "word", "}"}},
|
||||
map[string]interface{}{"page": "com", "hash": "com", "word": []interface{}{"mul{", ";", "#[^\n]*\n?", "\n", "}"}},
|
||||
map[string]interface{}{"page": "line", "hash": "line", "word": []interface{}{"opt{", "mul{", "stm", "cmd", "}", "}", "com"}},
|
||||
|
||||
map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"$", "(", "cmd", ")"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "if", "word": []interface{}{"if", "exp"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "for", "word": []interface{}{"for", "rep{", "exp", "}"}},
|
||||
/*
|
||||
|
||||
map[string]interface{}{"page": "op1", "hash": "op1", "word": []interface{}{"mul{", "-z", "-n", "}"}},
|
||||
map[string]interface{}{"page": "op1", "hash": "op1", "word": []interface{}{"mul{", "-e", "-f", "-d", "}"}},
|
||||
map[string]interface{}{"page": "op1", "hash": "op1", "word": []interface{}{"mul{", "-", "+", "}"}},
|
||||
map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", ":=", "=", "+=", "}"}},
|
||||
map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", "+", "-", "*", "/", "%", "}"}},
|
||||
map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", "<", "<=", ">", ">=", "==", "!=", "}"}},
|
||||
map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", "~", "!~", "}"}},
|
||||
|
||||
map[string]interface{}{"page": "val", "hash": "val", "word": []interface{}{"opt{", "op1", "}", "mul{", "num", "key", "str", "exe", "}"}},
|
||||
map[string]interface{}{"page": "exp", "hash": "exp", "word": []interface{}{"val", "rep{", "op2", "val", "}"}},
|
||||
map[string]interface{}{"page": "map", "hash": "map", "word": []interface{}{"key", ":", "\\[", "rep{", "key", "}", "\\]"}},
|
||||
map[string]interface{}{"page": "exp", "hash": "exp", "word": []interface{}{"\\{", "rep{", "map", "}", "\\}"}},
|
||||
map[string]interface{}{"page": "val", "hash": "val", "word": []interface{}{"opt{", "op1", "}", "(", "exp", ")"}},
|
||||
|
||||
map[string]interface{}{"page": "stm", "hash": "var", "word": []interface{}{"var", "key", "opt{", "=", "exp", "}"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "let", "word": []interface{}{"let", "key", "opt{", "=", "exp", "}"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "var", "word": []interface{}{"var", "key", "<-"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "var", "word": []interface{}{"var", "key", "<-", "opt{", "exe", "}"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "let", "word": []interface{}{"let", "key", "<-", "opt{", "exe", "}"}},
|
||||
|
||||
map[string]interface{}{"page": "stm", "hash": "if", "word": []interface{}{"if", "exp"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "else", "word": []interface{}{"else"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "end", "word": []interface{}{"end"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "for", "word": []interface{}{"for", "opt{", "exp", ";", "}", "exp"}},
|
||||
@ -302,37 +347,23 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
|
||||
map[string]interface{}{"page": "stm", "hash": "expr", "word": []interface{}{"expr", "rep{", "exp", "}"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "return", "word": []interface{}{"return", "rep{", "exp", "}"}},
|
||||
|
||||
map[string]interface{}{"page": "word", "hash": "word", "word": []interface{}{"mul{", "~", "!", "=", "\\?\\?", "\\?", "<", ">$", ">@", ">", "\\|", "%", "exe", "str", "[a-zA-Z0-9_/\\-.:*%]+", "}"}},
|
||||
map[string]interface{}{"page": "cmd", "hash": "cmd", "word": []interface{}{"rep{", "word", "}"}},
|
||||
map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"$", "(", "cmd", ")"}},
|
||||
*/
|
||||
|
||||
map[string]interface{}{"page": "line", "hash": "line", "word": []interface{}{"opt{", "mul{", "stm", "cmd", "}", "}", "mul{", ";", "\n", "#[^\n]*\n", "}"}},
|
||||
}, Help: "语法集合的最大数量"},
|
||||
"info": &ctx.Config{Name: "info", Value: map[string]interface{}{"ncell": 128, "nlang": 64}, Help: "嵌套层级日志的标记"},
|
||||
"exec": &ctx.Config{Name: "info", Value: map[string]interface{}{
|
||||
"line": map[string]interface{}{"disable": true},
|
||||
"void": map[string]interface{}{"disable": true},
|
||||
"num": map[string]interface{}{"disable": true},
|
||||
"key": map[string]interface{}{"disable": true},
|
||||
"op1": map[string]interface{}{"disable": true},
|
||||
"op2": map[string]interface{}{"disable": true},
|
||||
"word": map[string]interface{}{"disable": true},
|
||||
"line": map[string]interface{}{"disable": true},
|
||||
}, Help: "嵌套层级日志的标记"},
|
||||
},
|
||||
Commands: map[string]*ctx.Command{
|
||||
"_init": &ctx.Command{Name: "_init", Help: "添加语法规则, page: 语法集合, hash: 语句类型, word: 语法模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
|
||||
yac.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: "64", Help: "状态机状态的数量"}
|
||||
yac.Caches["nnode"] = &ctx.Cache{Name: "节点数量", Value: "0", Help: "状态机连接的逻辑数量"}
|
||||
yac.Caches["nreal"] = &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.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.Confi("info", "nlang"))
|
||||
yac.state = map[State]*State{}
|
||||
|
||||
yac.lex = m.Cmd("lex.spawn")
|
||||
m.Confm("seed", func(line int, seed map[string]interface{}) {
|
||||
m.Spawn().Cmd("train", seed["page"], seed["hash"], seed["word"])
|
||||
})
|
||||
@ -341,70 +372,40 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
|
||||
}},
|
||||
"train": &ctx.Command{Name: "train page hash word...", Help: "添加语法规则, page: 语法集合, hash: 语句类型, word: 语法模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
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.Confi("info", "nlang"), "语法集合过多")
|
||||
|
||||
page := yac.index(m, "npage", arg[0])
|
||||
hash := yac.index(m, "nhash", arg[1])
|
||||
if yac.mat[page] == nil {
|
||||
yac.mat[page] = map[byte]*State{}
|
||||
for i := 0; i < m.Confi("info", "nlang"); i++ {
|
||||
for i := 0; i < m.Confi("meta", "nlang"); i++ {
|
||||
yac.mat[page][byte(i)] = nil
|
||||
}
|
||||
}
|
||||
|
||||
hash, ok := yac.hash[arg[1]]
|
||||
if !ok {
|
||||
hash = m.Capi("nhash", 1)
|
||||
yac.hash[arg[1]] = hash
|
||||
yac.hand[hash] = arg[1]
|
||||
}
|
||||
|
||||
if yac.lex == nil {
|
||||
yac.lex = m.Cmd("lex.spawn")
|
||||
}
|
||||
|
||||
yac.train(m, page, hash, arg[2:], 1)
|
||||
|
||||
yac.seed = append(yac.seed, &Seed{page, hash, arg[2:]})
|
||||
m.Cap("stream", fmt.Sprintf("%d,%s,%s", m.Capi("nseed", 1), m.Cap("npage"), m.Cap("nhash")))
|
||||
m.Cap("stream", fmt.Sprintf("%d,%s,%s", m.Cap("nseed", len(yac.seed)),
|
||||
m.Cap("npage"), m.Cap("nhash", len(yac.hash)-1)))
|
||||
}
|
||||
return
|
||||
}},
|
||||
"parse": &ctx.Command{Name: "parse page void word...", Help: "解析语句, page: 初始语法, void: 空白语法, word: 解析语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
"parse": &ctx.Command{Name: "parse line", Help: "解析语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
|
||||
str, word, hash := yac.parse(m, m, m.Optioni("page", yac.page[arg[0]]), m.Optioni("void", yac.page[arg[1]]), arg[2], 1)
|
||||
m.Result(str, yac.hand[hash], word)
|
||||
}
|
||||
return
|
||||
}},
|
||||
"scan": &ctx.Command{Name: "scan filename modulename", Help: "解析文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
|
||||
m.Optioni("page", yac.page["line"])
|
||||
m.Optioni("void", yac.page["void"])
|
||||
m.Optioni("yac.page", yac.page[m.Conf("nline")])
|
||||
m.Optioni("yac.void", yac.page[m.Conf("nvoid")])
|
||||
|
||||
name := ""
|
||||
if len(arg) > 1 {
|
||||
name = arg[1]
|
||||
} else {
|
||||
name = fmt.Sprintf("parse%d", m.Capi("nparse", 1))
|
||||
}
|
||||
|
||||
if len(arg) > 0 {
|
||||
m.Start(name, "parse", key, arg[0])
|
||||
} else {
|
||||
m.Start(name, "parse")
|
||||
}
|
||||
_, word, _ := yac.parse(m, m, m.Optioni("yac.page"), m.Optioni("yac.void"), arg[0], 1)
|
||||
m.Result(word)
|
||||
}
|
||||
return
|
||||
}},
|
||||
"show": &ctx.Command{Name: "show seed|page|hash|mat", Help: "查看信息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
|
||||
if len(arg) == 0 {
|
||||
m.Append("seed", len(yac.seed))
|
||||
m.Append("page", len(yac.page))
|
||||
m.Append("hash", len(yac.hash))
|
||||
m.Append("node", len(yac.state))
|
||||
m.Push("seed", len(yac.seed))
|
||||
m.Push("page", len(yac.page))
|
||||
m.Push("hash", len(yac.hash))
|
||||
m.Push("nmat", len(yac.mat))
|
||||
m.Push("node", len(yac.state))
|
||||
m.Table()
|
||||
return
|
||||
}
|
||||
@ -412,32 +413,51 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
|
||||
switch arg[0] {
|
||||
case "seed":
|
||||
for _, v := range yac.seed {
|
||||
m.Add("append", "page", fmt.Sprintf("%d", v.page))
|
||||
m.Add("append", "hash", fmt.Sprintf("%d", v.hash))
|
||||
m.Add("append", "word", fmt.Sprintf("%s", strings.Replace(strings.Replace(strings.Join(v.word, " "), "\n", "\\n", -1), "\t", "\\t", -1)))
|
||||
m.Push("page", yac.hand[v.page])
|
||||
m.Push("word", strings.Replace(strings.Replace(fmt.Sprint(v.word), "\n", "\\n", -1), "\t", "\\t", -1))
|
||||
m.Push("hash", yac.word[v.hash])
|
||||
}
|
||||
m.Table()
|
||||
m.Sort("page", "int").Table()
|
||||
|
||||
case "page":
|
||||
for k, v := range yac.page {
|
||||
m.Add("append", "page", k)
|
||||
m.Add("append", "code", fmt.Sprintf("%d", v))
|
||||
m.Add("append", "code", v)
|
||||
}
|
||||
m.Sort("code", "int").Table()
|
||||
|
||||
case "hash":
|
||||
for k, v := range yac.hash {
|
||||
m.Add("append", "hash", k)
|
||||
m.Add("append", "code", fmt.Sprintf("%d", v))
|
||||
m.Add("append", "code", v)
|
||||
m.Add("append", "hand", yac.hand[v])
|
||||
}
|
||||
m.Sort("code", "int").Table()
|
||||
|
||||
case "node":
|
||||
for _, v := range yac.state {
|
||||
m.Push("star", v.star)
|
||||
m.Push("next", v.next)
|
||||
m.Push("hash", v.hash)
|
||||
}
|
||||
m.Table()
|
||||
|
||||
case "mat":
|
||||
for _, v := range yac.mat {
|
||||
for j := byte(0); j < byte(m.Confi("info", "ncell")); j++ {
|
||||
s := v[j]
|
||||
if s == nil {
|
||||
m.Add("append", fmt.Sprintf("%d", j), "")
|
||||
for i, v := range yac.mat {
|
||||
if i <= m.Capi("npage") {
|
||||
m.Push("index", yac.hand[i])
|
||||
} else if i < m.Confi("meta", "nlang") {
|
||||
continue
|
||||
} else {
|
||||
m.Add("append", fmt.Sprintf("%d", j), fmt.Sprintf("%d,%d,%d", s.star, s.next, s.hash))
|
||||
m.Push("index", i)
|
||||
}
|
||||
|
||||
for j := byte(0); j < byte(m.Confi("meta", "ncell")); j++ {
|
||||
c := fmt.Sprintf("%d", j)
|
||||
if s := v[j]; s == nil {
|
||||
m.Push(c, "")
|
||||
} else {
|
||||
m.Push(c, fmt.Sprintf("%d,%d,%d", s.star, s.next, s.hash))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -480,6 +500,352 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
|
||||
}
|
||||
return
|
||||
}},
|
||||
|
||||
"str": &ctx.Command{Name: "str word", Help: "解析字符串", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Echo(arg[0][1 : len(arg[0])-1])
|
||||
return
|
||||
}},
|
||||
"exe": &ctx.Command{Name: "exe $ ( cmd )", Help: "解析嵌套命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
switch len(arg) {
|
||||
case 1:
|
||||
m.Echo(arg[0])
|
||||
case 2:
|
||||
msg := m.Spawn(m.Optionv("bio.ctx"))
|
||||
switch arg[0] {
|
||||
case "$":
|
||||
m.Echo(msg.Cap(arg[1]))
|
||||
case "@":
|
||||
value := msg.Option(arg[1])
|
||||
if value == "" {
|
||||
value = msg.Conf(arg[1])
|
||||
}
|
||||
|
||||
m.Echo(value)
|
||||
default:
|
||||
m.Echo(arg[0]).Echo(arg[1])
|
||||
}
|
||||
default:
|
||||
switch arg[0] {
|
||||
case "$", "@":
|
||||
m.Result(0, arg[2:len(arg)-1])
|
||||
}
|
||||
}
|
||||
return
|
||||
}},
|
||||
"val": &ctx.Command{Name: "val exp", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
result := "false"
|
||||
switch len(arg) {
|
||||
case 0:
|
||||
result = ""
|
||||
case 1:
|
||||
result = arg[0]
|
||||
case 2:
|
||||
switch arg[0] {
|
||||
case "-z":
|
||||
if arg[1] == "" {
|
||||
result = "true"
|
||||
}
|
||||
case "-n":
|
||||
if arg[1] != "" {
|
||||
result = "true"
|
||||
}
|
||||
|
||||
case "-e":
|
||||
if _, e := os.Stat(arg[1]); e == nil {
|
||||
result = "true"
|
||||
}
|
||||
case "-f":
|
||||
if info, e := os.Stat(arg[1]); e == nil && !info.IsDir() {
|
||||
result = "true"
|
||||
}
|
||||
case "-d":
|
||||
if info, e := os.Stat(arg[1]); e == nil && info.IsDir() {
|
||||
result = "true"
|
||||
}
|
||||
case "+":
|
||||
result = arg[1]
|
||||
case "-":
|
||||
result = arg[1]
|
||||
if i, e := strconv.Atoi(arg[1]); e == nil {
|
||||
result = fmt.Sprintf("%d", -i)
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
v1, e1 := strconv.Atoi(arg[0])
|
||||
v2, e2 := strconv.Atoi(arg[2])
|
||||
switch arg[1] {
|
||||
case ":=":
|
||||
if !m.Target().Has(arg[0]) {
|
||||
result = m.Cap(arg[0], arg[0], arg[2], "临时变量")
|
||||
}
|
||||
case "=":
|
||||
result = m.Cap(arg[0], arg[2])
|
||||
case "+=":
|
||||
if i, e := strconv.Atoi(m.Cap(arg[0])); e == nil && e2 == nil {
|
||||
result = m.Cap(arg[0], fmt.Sprintf("%d", v2+i))
|
||||
} else {
|
||||
result = m.Cap(arg[0], m.Cap(arg[0])+arg[2])
|
||||
}
|
||||
case "+":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%d", v1+v2)
|
||||
} else {
|
||||
result = arg[0] + arg[2]
|
||||
}
|
||||
case "-":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%d", v1-v2)
|
||||
} else {
|
||||
result = strings.Replace(arg[0], arg[1], "", -1)
|
||||
}
|
||||
case "*":
|
||||
result = arg[0]
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%d", v1*v2)
|
||||
}
|
||||
case "/":
|
||||
result = arg[0]
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%d", v1/v2)
|
||||
}
|
||||
case "%":
|
||||
result = arg[0]
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%d", v1%v2)
|
||||
}
|
||||
|
||||
case "<":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%t", v1 < v2)
|
||||
} else {
|
||||
result = fmt.Sprintf("%t", arg[0] < arg[2])
|
||||
}
|
||||
case "<=":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%t", v1 <= v2)
|
||||
} else {
|
||||
result = fmt.Sprintf("%t", arg[0] <= arg[2])
|
||||
}
|
||||
case ">":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%t", v1 > v2)
|
||||
} else {
|
||||
result = fmt.Sprintf("%t", arg[0] > arg[2])
|
||||
}
|
||||
case ">=":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%t", v1 >= v2)
|
||||
} else {
|
||||
result = fmt.Sprintf("%t", arg[0] >= arg[2])
|
||||
}
|
||||
case "==":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%t", v1 == v2)
|
||||
} else {
|
||||
result = fmt.Sprintf("%t", arg[0] == arg[2])
|
||||
}
|
||||
case "!=":
|
||||
if e1 == nil && e2 == nil {
|
||||
result = fmt.Sprintf("%t", v1 != v2)
|
||||
} else {
|
||||
result = fmt.Sprintf("%t", arg[0] != arg[2])
|
||||
}
|
||||
|
||||
case "~":
|
||||
if m, e := regexp.MatchString(arg[2], arg[0]); m && e == nil {
|
||||
result = "true"
|
||||
}
|
||||
case "!~":
|
||||
if m, e := regexp.MatchString(arg[2], arg[0]); !m || e != nil {
|
||||
result = "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
m.Echo(result)
|
||||
|
||||
return
|
||||
}},
|
||||
"exp": &ctx.Command{Name: "exp word", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) > 0 && arg[0] == "{" {
|
||||
msg := m.Spawn()
|
||||
for i := 1; i < len(arg); i++ {
|
||||
key := arg[i]
|
||||
for i += 3; i < len(arg); i++ {
|
||||
if arg[i] == "]" {
|
||||
break
|
||||
}
|
||||
msg.Add("append", key, arg[i])
|
||||
}
|
||||
}
|
||||
m.Echo("%d", msg.Code())
|
||||
return
|
||||
}
|
||||
|
||||
pre := map[string]int{
|
||||
"=": -1,
|
||||
"+": 2, "-": 2,
|
||||
"*": 3, "/": 3, "%": 3,
|
||||
}
|
||||
num, op := []string{arg[0]}, []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.Cmdx("yac.val", num[len(op)-1], op[len(op)-1], num[len(op)])
|
||||
num, op = num[:len(num)-1], op[:len(op)-1]
|
||||
}
|
||||
num, op = append(num, arg[i+1]), append(op, arg[i])
|
||||
}
|
||||
|
||||
for i := len(op) - 1; i >= 0; i-- {
|
||||
num[i] = m.Cmdx("yac.val", num[i], op[i], num[i+1])
|
||||
}
|
||||
|
||||
m.Echo("%s", num[0])
|
||||
return
|
||||
}},
|
||||
"let": &ctx.Command{Name: "let a = exp", Help: "设置变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
switch arg[2] {
|
||||
case "=":
|
||||
m.Cap(arg[1], arg[3])
|
||||
m.Log("stack", " set %v = %v", arg[1], arg[3])
|
||||
case "<-":
|
||||
m.Cap(arg[1], m.Cap("last_msg"))
|
||||
}
|
||||
m.Echo(m.Cap(arg[1]))
|
||||
return
|
||||
}},
|
||||
"var": &ctx.Command{Name: "var a [= exp]", Help: "定义变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if m.Cap(arg[1], arg[1], "", "临时变量"); len(arg) > 1 {
|
||||
switch arg[2] {
|
||||
case "=":
|
||||
m.Cap(arg[1], arg[3])
|
||||
case "<-":
|
||||
m.Cap(arg[1], m.Cap("last_msg"))
|
||||
}
|
||||
}
|
||||
m.Echo(m.Cap(arg[1]))
|
||||
return
|
||||
}},
|
||||
"return": &ctx.Command{Name: "return result...", Help: "结束脚本, result: 返回值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Appends("bio.end", true)
|
||||
m.Result(arg[1:])
|
||||
return
|
||||
}},
|
||||
"com": &ctx.Command{Name: "com", Help: "解析注释", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
return
|
||||
}},
|
||||
|
||||
"if": &ctx.Command{Name: "if exp", Help: "条件语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Push("stack.key", arg[0])
|
||||
m.Push("stack.run", m.Options("stack.run") && kit.Right(arg[1]))
|
||||
return
|
||||
}},
|
||||
"for": &ctx.Command{Name: "for [[express ;] condition]|[index message meta value]",
|
||||
Help: "循环语句, express: 每次循环运行的表达式, condition: 循环条件, index: 索引消息, message: 消息编号, meta: value: ",
|
||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Push("stack.key", arg[0])
|
||||
m.Push("stack.run", m.Options("stack.run") && kit.Right(arg[1]))
|
||||
|
||||
/*
|
||||
if cli, ok := m.Target().Server.(*YAC); m.Assert(ok) {
|
||||
run := m.Caps("parse")
|
||||
defer func() { m.Caps("parse", run) }()
|
||||
|
||||
msg := m
|
||||
if run {
|
||||
if arg[1] == "index" {
|
||||
if code, e := strconv.Atoi(arg[2]); m.Assert(e) {
|
||||
msg = m.Target().Message().Tree(code)
|
||||
run = run && msg != nil && msg.Meta != nil
|
||||
switch len(arg) {
|
||||
case 4:
|
||||
run = run && len(msg.Meta) > 0
|
||||
case 5:
|
||||
run = run && len(msg.Meta[arg[3]]) > 0
|
||||
}
|
||||
}
|
||||
} else {
|
||||
run = run && kit.Right(arg[len(arg)-1])
|
||||
}
|
||||
|
||||
if len(cli.stack) > 0 {
|
||||
if frame := cli.stack[len(cli.stack)-1]; frame.key == "for" && frame.pos == m.Optioni("file_pos") {
|
||||
if arg[1] == "index" {
|
||||
frame.index++
|
||||
if run = run && len(frame.list) > frame.index; run {
|
||||
if len(arg) == 5 {
|
||||
arg[3] = arg[4]
|
||||
}
|
||||
m.Cap(arg[3], frame.list[frame.index])
|
||||
}
|
||||
}
|
||||
frame.run = run
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cli.stack = append(cli.stack, &Frame{pos: m.Optioni("file_pos"), key: key, run: run, index: 0})
|
||||
if m.Capi("level", 1); run && arg[1] == "index" {
|
||||
frame := cli.stack[len(cli.stack)-1]
|
||||
switch len(arg) {
|
||||
case 4:
|
||||
frame.list = []string{}
|
||||
for k, _ := range msg.Meta {
|
||||
frame.list = append(frame.list, k)
|
||||
}
|
||||
case 5:
|
||||
frame.list = msg.Meta[arg[3]]
|
||||
arg[3] = arg[4]
|
||||
}
|
||||
m.Cap(arg[3], arg[3], frame.list[0], "临时变量")
|
||||
}
|
||||
}
|
||||
*/
|
||||
return
|
||||
}},
|
||||
|
||||
"expr": &ctx.Command{Name: "expr arg...", Help: "输出表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Echo("%s", strings.Join(arg[1:], ""))
|
||||
return
|
||||
}},
|
||||
"label": &ctx.Command{Name: "label name", Help: "记录当前脚本的位置, name: 位置名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if cli, ok := m.Target().Server.(*YAC); m.Assert(ok) {
|
||||
if cli.label == nil {
|
||||
cli.label = map[string]string{}
|
||||
}
|
||||
cli.label[arg[1]] = m.Option("file_pos")
|
||||
}
|
||||
return
|
||||
}},
|
||||
"goto": &ctx.Command{Name: "goto label [exp] condition", Help: "向上跳转到指定位置, label: 跳转位置, condition: 跳转条件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if cli, ok := m.Target().Server.(*YAC); m.Assert(ok) {
|
||||
if pos, ok := cli.label[arg[1]]; ok {
|
||||
if !kit.Right(arg[len(arg)-1]) {
|
||||
return
|
||||
}
|
||||
m.Append("file_pos0", pos)
|
||||
}
|
||||
}
|
||||
return
|
||||
}},
|
||||
"else": &ctx.Command{Name: "else", Help: "条件语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
/*
|
||||
if cli, ok := m.Target().Server.(*YAC); m.Assert(ok) {
|
||||
if !m.Caps("parse") {
|
||||
m.Caps("parse", true)
|
||||
} else {
|
||||
if len(cli.stack) == 1 {
|
||||
m.Caps("parse", false)
|
||||
} else {
|
||||
frame := cli.stack[len(cli.stack)-2]
|
||||
m.Caps("parse", !frame.run)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
return
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
|
35
src/toolkit/stmt.go
Normal file
35
src/toolkit/stmt.go
Normal file
@ -0,0 +1,35 @@
|
||||
package kit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Frame struct {
|
||||
Key string
|
||||
Run bool
|
||||
Pos int
|
||||
deep int
|
||||
// list []string
|
||||
}
|
||||
|
||||
func (f *Frame) String(meta string) string {
|
||||
return fmt.Sprintf("%s%s%d %s %t", strings.Repeat("#", f.deep), meta, f.deep, f.Key, f.Run)
|
||||
}
|
||||
|
||||
type Stack struct {
|
||||
fs []*Frame
|
||||
}
|
||||
|
||||
func (s *Stack) Pop() *Frame {
|
||||
f := s.fs[len(s.fs)-1]
|
||||
s.fs = s.fs[:len(s.fs)-1]
|
||||
return f
|
||||
}
|
||||
func (s *Stack) Push(key string, run bool, pos int) *Frame {
|
||||
s.fs = append(s.fs, &Frame{key, run, pos, len(s.fs)})
|
||||
return s.fs[len(s.fs)-1]
|
||||
}
|
||||
func (s *Stack) Peek() *Frame {
|
||||
return s.fs[len(s.fs)-1]
|
||||
}
|
@ -116,18 +116,6 @@ func Format(arg ...interface{}) string {
|
||||
result = append(result, string(val))
|
||||
case []rune:
|
||||
result = append(result, string(val))
|
||||
case []string:
|
||||
result = append(result, val...)
|
||||
// case []interface{}:
|
||||
//
|
||||
// result = append(result, "[")
|
||||
// for i, value := range val {
|
||||
// result = append(result, Format(value))
|
||||
// if i < len(val)-1 {
|
||||
// result = append(result, ",")
|
||||
// }
|
||||
// }
|
||||
// result = append(result, "]")
|
||||
case time.Time:
|
||||
result = append(result, fmt.Sprintf("%s", val.Format("2006-01-02 15:03:04")))
|
||||
case *os.File:
|
||||
@ -210,7 +198,7 @@ func Trans(arg ...interface{}) []string {
|
||||
}
|
||||
case []interface{}:
|
||||
for _, v := range val {
|
||||
ls = append(ls, Format(v))
|
||||
ls = append(ls, Trans(v)...)
|
||||
}
|
||||
default:
|
||||
ls = append(ls, Format(val))
|
||||
|
Loading…
x
Reference in New Issue
Block a user