mirror of
https://shylinux.com/x/ContextOS
synced 2025-04-25 16:58:06 +08:00
opt lex&yac
This commit is contained in:
parent
4f1bc3e305
commit
55fefaf130
@ -133,6 +133,7 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool {
|
||||
}
|
||||
|
||||
if m.Option("prompt", cmd.Cmd().Conf("prompt")); cmd.Has("return") {
|
||||
kit.Log("error", "waht ?????")
|
||||
m.Options("scan_end", true)
|
||||
m.Target().Close(m)
|
||||
}
|
||||
@ -157,8 +158,8 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
"nshell": &ctx.Cache{Name: "nshell", Value: "0", Help: "终端数量"},
|
||||
},
|
||||
Configs: map[string]*ctx.Config{
|
||||
"init.shy": &ctx.Config{Name: "init.shy", Value: "etc/init.shy", Help: "启动脚本"},
|
||||
"exit.shy": &ctx.Config{Name: "exit.shy", Value: "etc/exit.shy", Help: "启动脚本"},
|
||||
"init_shy": &ctx.Config{Name: "init_shy", Value: "etc/init.shy", Help: "启动脚本"},
|
||||
"exit_shy": &ctx.Config{Name: "exit_shy", Value: "etc/exit.shy", Help: "启动脚本"},
|
||||
|
||||
"time_unit": &ctx.Config{Name: "time_unit", Value: "1000", Help: "时间倍数"},
|
||||
"time_close": &ctx.Config{Name: "time_close(open/close)", Value: "open", Help: "时间区间"},
|
||||
@ -620,31 +621,30 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
m.Add("append", "return", arg[1:])
|
||||
return
|
||||
}},
|
||||
"source": &ctx.Command{Name: "source [stdio [init.shy [exit.shy]]]|[filename [async]]|string", Help: "解析脚本, filename: 文件名, async: 异步执行",
|
||||
"source": &ctx.Command{Name: "source [stdio [init_shy [exit_shy]]]|[filename [async]]|string", Help: "解析脚本, filename: 文件名, async: 异步执行",
|
||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if _, ok := m.Source().Server.(*CLI); ok {
|
||||
msg := m.Spawn(c)
|
||||
m.Copy(msg, "target")
|
||||
m.Copy(m.Spawn(c), "target")
|
||||
}
|
||||
m.Cmd("yac.init")
|
||||
m.Cmd("aaa.init")
|
||||
|
||||
if len(arg) == 0 || arg[0] == "stdio" {
|
||||
m.Sess("log", false).Cmd("init")
|
||||
if (len(arg) == 0 || arg[0] == "stdio") && m.Target().Name == "cli" {
|
||||
// 启动终端
|
||||
m.Cmd("yac.init")
|
||||
if m.Start("shy", "shell", "stdio"); m.Cmds("nfs.path", m.Confx("init_shy", arg, 1)) {
|
||||
// msg := m.Spawn().Add("option", "scan_end", "false").Cmd("source", m.Conf("init_shy"))
|
||||
|
||||
if m.Start("shy", "shell", "stdio"); m.Sess("nfs").Cmd("path", m.Confx("init.shy", arg, 1)).Results(0) {
|
||||
msg := m.Spawn().Add("option", "scan_end", "false").Cmd("source", m.Conf("init.shy"))
|
||||
m.Cap("ps_target", msg.Append("last_target"))
|
||||
m.Option("prompt", m.Conf("prompt"))
|
||||
m.Find("nfs.stdio").Cmd("prompt")
|
||||
// m.Cap("ps_target", msg.Append("last_target"))
|
||||
// m.Option("prompt", m.Conf("prompt"))
|
||||
// m.Find("nfs.stdio").Cmd("prompt")
|
||||
}
|
||||
if m.Wait(); m.Sess("nfs").Cmd("path", m.Confx("exit.shy", arg, 2)).Results(0) {
|
||||
m.Spawn().Add("option", "scan_end", "false").Cmd("source", m.Conf("exit.shy"))
|
||||
if m.Wait(); m.Cmds("nfs.path", m.Confx("exit_shy", arg, 2)) {
|
||||
m.Spawn().Add("option", "scan_end", "false").Cmd("source", m.Conf("exit_shy"))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if m.Sess("nfs").Cmd("path", arg[0]).Results(0) && arg[0] != "bench" {
|
||||
// 运行脚本
|
||||
if m.Cmds("nfs.path", arg[0]) && strings.HasSuffix(arg[0], ".shy") {
|
||||
m.Start(fmt.Sprintf("shell%d", m.Capi("nshell", 1)), "shell", arg...)
|
||||
if len(arg) < 2 || arg[1] != "async" {
|
||||
m.Wait()
|
||||
@ -1138,8 +1138,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
return
|
||||
}
|
||||
|
||||
m.Log("what", "wath %v", m.Spawn().Cmd("time"))
|
||||
|
||||
now := int64(m.Sess("cli").Cmd("time").Appendi("timestamp"))
|
||||
begin := now
|
||||
if len(arg) > 0 && arg[0] == "begin" {
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -106,6 +107,12 @@ func (c *Context) Begin(m *Message, arg ...string) *Context {
|
||||
c.requests = append(c.requests, m)
|
||||
m.source.sessions = append(m.source.sessions, m)
|
||||
|
||||
switch v := m.Gdb("context", "begin", c.Name).(type) {
|
||||
case string:
|
||||
kit.Log("error", "fuck %v", v)
|
||||
case nil:
|
||||
}
|
||||
|
||||
m.Log("begin", "%d context %v %v", m.Capi("ncontext", 1), m.Meta["detail"], m.Meta["option"])
|
||||
for k, x := range c.Configs {
|
||||
if x.Hand != nil {
|
||||
@ -124,17 +131,26 @@ func (c *Context) Start(m *Message, arg ...string) bool {
|
||||
if len(arg) > 0 && arg[0] == "sync" {
|
||||
sync, arg = true, arg[1:]
|
||||
}
|
||||
m.Set("detail", arg)
|
||||
if len(arg) > 0 {
|
||||
m.Set("detail", arg)
|
||||
}
|
||||
|
||||
c.requests = append(c.requests, m)
|
||||
m.source.sessions = append(m.source.sessions, m)
|
||||
|
||||
switch v := m.Gdb("context", "start", c.Name).(type) {
|
||||
case string:
|
||||
kit.Log("error", "fuck %v", v)
|
||||
case nil:
|
||||
}
|
||||
|
||||
if m.Hand = true; m.Cap("status") == "start" {
|
||||
return true
|
||||
}
|
||||
|
||||
c.exit = make(chan bool, 2)
|
||||
go m.TryCatch(m, true, func(m *Message) {
|
||||
m.Log(m.Cap("status", "start"), "%d server %v %v", m.root.Capi("nserver", 1), m.Meta["detail"], m.Meta["option"])
|
||||
m.Log(m.Cap("status", "start"), "%d server %v %v", m.Capi("nserver", 1), m.Meta["detail"], m.Meta["option"])
|
||||
|
||||
c.message = m
|
||||
if c.exit <- false; c.Server == nil || c.Server.Start(m, m.Meta["detail"]...) {
|
||||
@ -260,7 +276,7 @@ func (c *Context) BackTrace(m *Message, hand func(m *Message) (stop bool)) *Cont
|
||||
}
|
||||
|
||||
type LOGGER interface {
|
||||
LOG(*Message, string, string)
|
||||
Log(*Message, string, string, ...interface{})
|
||||
}
|
||||
type DEBUG interface {
|
||||
Wait(*Message, ...interface{}) interface{}
|
||||
@ -288,18 +304,17 @@ type Message struct {
|
||||
}
|
||||
|
||||
func (m *Message) Log(action string, str string, arg ...interface{}) *Message {
|
||||
kit.Errorf(fmt.Sprintf("%s %s %s", m.Format(), action, fmt.Sprintf(str, arg...)))
|
||||
return m
|
||||
if action == "error" {
|
||||
kit.Errorf(str, arg...)
|
||||
}
|
||||
|
||||
if l := m.Sess("log", false); l != nil {
|
||||
if log, ok := l.target.Server.(LOGGER); ok {
|
||||
log.LOG(m, action, fmt.Sprintf(str, arg...))
|
||||
log.Log(m, action, str, arg...)
|
||||
return m
|
||||
}
|
||||
}
|
||||
|
||||
if action == "error" {
|
||||
kit.Log("error", fmt.Sprintf("%s %s %s", m.Format(), action, fmt.Sprintf(str, arg...)))
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
func (m *Message) Gdb(arg ...interface{}) interface{} {
|
||||
@ -323,7 +338,7 @@ func (m *Message) Spawn(arg ...interface{}) *Message {
|
||||
|
||||
msg := &Message{
|
||||
time: time.Now(),
|
||||
code: m.root.Capi("nmessage", 1),
|
||||
code: m.Capi("nmessage", 1),
|
||||
source: m.target,
|
||||
target: c,
|
||||
message: m,
|
||||
@ -385,6 +400,15 @@ func (m *Message) Format(arg ...string) string {
|
||||
meta = append(meta, fmt.Sprintf("%v", m.Meta["append"]))
|
||||
case "result":
|
||||
meta = append(meta, fmt.Sprintf("%v", m.Meta["result"]))
|
||||
case "full":
|
||||
meta = append(meta, fmt.Sprintf("%s\n", m.Format("time", "ship")))
|
||||
meta = append(meta, fmt.Sprintf("detail: %s\n", m.Format("detail")))
|
||||
meta = append(meta, fmt.Sprintf("option: %s\n", m.Format("option")))
|
||||
for k, v := range m.Meta {
|
||||
meta = append(meta, fmt.Sprintf(" %s: %v\n", k, v))
|
||||
}
|
||||
meta = append(meta, fmt.Sprintf("append: %s\n", m.Format("append")))
|
||||
meta = append(meta, fmt.Sprintf("result: %s\n", m.Format("result")))
|
||||
}
|
||||
}
|
||||
return strings.Join(meta, " ")
|
||||
@ -478,7 +502,7 @@ func (m *Message) Get(key string, arg ...interface{}) string {
|
||||
}
|
||||
|
||||
index = (index+2)%(len(meta)+2) - 2
|
||||
if index > 0 && index < len(meta) {
|
||||
if index >= 0 && index < len(meta) {
|
||||
return meta[index]
|
||||
}
|
||||
}
|
||||
@ -1018,7 +1042,10 @@ func (m *Message) Match(key string, spawn bool, hand func(m *Message, s *Context
|
||||
context = append(context, m.source)
|
||||
|
||||
for _, s := range context {
|
||||
for c := s; c != nil && !hand(m, s, c, key) && c != c.context; c = c.context {
|
||||
for c := s; c != nil; c = c.context {
|
||||
if hand(m, s, c, key) {
|
||||
return m
|
||||
}
|
||||
}
|
||||
}
|
||||
return m
|
||||
@ -1142,7 +1169,7 @@ func (m *Message) Cmd(args ...interface{}) *Message {
|
||||
m = m.Match(key, true, func(m *Message, s *Context, c *Context, key string) bool {
|
||||
if x, ok := c.Commands[key]; ok && x.Hand != nil {
|
||||
m.TryCatch(m, true, func(m *Message) {
|
||||
m.Log("cmd", "%s:%s %s %v %v", c.Name, s.Name, key, arg, m.Meta["option"])
|
||||
m.Log("cmd", "%s %s %v %v", c.Name, key, arg, m.Meta["option"])
|
||||
|
||||
if args := []string{}; x.Form != nil {
|
||||
for i := 0; i < len(arg); i++ {
|
||||
@ -1166,7 +1193,12 @@ func (m *Message) Cmd(args ...interface{}) *Message {
|
||||
}
|
||||
|
||||
m.Hand = true
|
||||
x.Hand(m, c, key, arg...)
|
||||
switch v := m.Gdb("command", key, arg).(type) {
|
||||
case string:
|
||||
m.Echo(v)
|
||||
case nil:
|
||||
x.Hand(m, c, key, arg...)
|
||||
}
|
||||
})
|
||||
}
|
||||
return m.Hand
|
||||
@ -1245,11 +1277,11 @@ func (m *Message) Confx(key string, args ...interface{}) string {
|
||||
if args = args[1:]; len(args) > 0 {
|
||||
format, args = kit.Format(args[0]), args[1:]
|
||||
}
|
||||
|
||||
arg := []interface{}{format, value}
|
||||
for _, v := range args {
|
||||
args = append(args, v)
|
||||
arg = append(arg, v)
|
||||
}
|
||||
|
||||
return kit.Format(arg...)
|
||||
}
|
||||
func (m *Message) Confs(key string, arg ...interface{}) bool {
|
||||
@ -1318,16 +1350,6 @@ func (m *Message) Capi(key string, arg ...interface{}) int {
|
||||
return n
|
||||
}
|
||||
func (m *Message) Cap(key string, arg ...interface{}) string {
|
||||
if len(arg) == 0 {
|
||||
if val, ok := m.Gdb("cache", "read", key).(string); ok {
|
||||
return val
|
||||
}
|
||||
} else {
|
||||
if val, ok := m.Gdb("cache", "write", key, arg[0]).(string); ok {
|
||||
return val
|
||||
}
|
||||
}
|
||||
|
||||
var cache *Cache
|
||||
m.Match(key, false, func(m *Message, s *Context, c *Context, key string) bool {
|
||||
if x, ok := c.Caches[key]; ok {
|
||||
@ -3157,6 +3179,9 @@ func (ctx *CTX) Begin(m *Message, arg ...string) Server {
|
||||
return ctx
|
||||
}
|
||||
func (ctx *CTX) Start(m *Message, arg ...string) bool {
|
||||
gdb := m.Sess("gdb")
|
||||
gdb.Target().Start(gdb)
|
||||
|
||||
m.Cmd("cli.source", arg)
|
||||
return false
|
||||
}
|
||||
@ -3169,7 +3194,10 @@ func Start(args ...string) bool {
|
||||
args = append(args, os.Args[1:]...)
|
||||
}
|
||||
|
||||
if Index.Begin(Pulse, args...); Index.Start(Pulse, args...) {
|
||||
}
|
||||
ioutil.WriteFile(fmt.Sprintf("bench.pid"), []byte(kit.Format(os.Getpid())), 0666)
|
||||
|
||||
Index.Begin(Pulse, args...)
|
||||
Index.Start(Pulse, args...)
|
||||
Index.Close(Pulse, args...)
|
||||
return false
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package gdb
|
||||
|
||||
import (
|
||||
"contexts/ctx"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
@ -16,7 +18,7 @@ type GDB struct {
|
||||
}
|
||||
|
||||
func (gdb *GDB) Value(m *ctx.Message, arg ...interface{}) bool {
|
||||
if value, ok := kit.Chain(gdb.Configs["debug"].Value, append(arg, "value")).(map[string]interface{}); ok {
|
||||
if value, ok := kit.Chain(gdb.Configs["debug"].Value, kit.Trans(arg, "value")).(map[string]interface{}); ok {
|
||||
if !kit.Right(value["enable"]) {
|
||||
return false
|
||||
}
|
||||
@ -34,25 +36,35 @@ func (gdb *GDB) Value(m *ctx.Message, arg ...interface{}) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
func (gdb *GDB) Wait(m *ctx.Message, arg ...interface{}) interface{} {
|
||||
func (gdb *GDB) Wait(msg *ctx.Message, arg ...interface{}) interface{} {
|
||||
m := gdb.Message()
|
||||
if m.Cap("status") != "start" {
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := len(arg); i > 0; i-- {
|
||||
if gdb.Value(m, arg[:i]...) {
|
||||
if result := kit.Chain(kit.Chain(gdb.Configs["debug"].Value, arg[:i]), []string{"value", "result"}); result != nil {
|
||||
m.Log("error", "done %d %v", len(arg[:i]), arg)
|
||||
return result
|
||||
}
|
||||
if arg[0] == "trace" {
|
||||
m.Log("error", "%s", m.Format("full"))
|
||||
}
|
||||
m.Log("error", "wait %d %v", len(arg[:i]), arg)
|
||||
result := <-gdb.wait
|
||||
m.Log("error", "done %d %v %v", len(arg[:i]), arg, result)
|
||||
return result
|
||||
}
|
||||
}
|
||||
return <-gdb.wait
|
||||
|
||||
return nil
|
||||
}
|
||||
func (gdb *GDB) Goon(result interface{}, arg ...interface{}) {
|
||||
m := gdb.Message()
|
||||
if m.Cap("status") != "start" {
|
||||
return
|
||||
}
|
||||
|
||||
m.Log("error", "goon %v %v", arg, result)
|
||||
gdb.wait <- result
|
||||
}
|
||||
@ -66,70 +78,74 @@ func (gdb *GDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
||||
return s
|
||||
}
|
||||
func (gdb *GDB) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||
gdb.goon = make(chan os.Signal, 10)
|
||||
gdb.wait = make(chan interface{}, 10)
|
||||
m.Log("debug", "pid %d", os.Getpid())
|
||||
|
||||
signal.Notify(gdb.goon, syscall.Signal(19))
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case sig := <-gdb.goon:
|
||||
m.Log("error", "signal %v", sig)
|
||||
gdb.Goon("hello", "cache", "read", "value")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return gdb
|
||||
}
|
||||
func (gdb *GDB) Start(m *ctx.Message, arg ...string) bool {
|
||||
return false
|
||||
gdb.goon = make(chan os.Signal, 10)
|
||||
gdb.wait = make(chan interface{}, 10)
|
||||
m.Log("error", "pid %d", os.Getpid())
|
||||
kit.Log("error", "pid %d", os.Getpid())
|
||||
signal.Notify(gdb.goon, syscall.Signal(19))
|
||||
ioutil.WriteFile(fmt.Sprintf("%s.pid", gdb.Name), []byte(kit.Format(os.Getpid())), 0666)
|
||||
for {
|
||||
select {
|
||||
case sig := <-gdb.goon:
|
||||
m.Log("error", "signal %v", sig)
|
||||
gdb.Goon(nil, "cache", "read", "value")
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (gdb *GDB) Close(m *ctx.Message, arg ...string) bool {
|
||||
switch gdb.Context {
|
||||
case m.Target():
|
||||
case m.Source():
|
||||
}
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
var Index = &ctx.Context{Name: "gdb", Help: "调试中心",
|
||||
Caches: map[string]*ctx.Cache{},
|
||||
Configs: map[string]*ctx.Config{
|
||||
"debug": &ctx.Config{Name: "debug", Value: map[string]interface{}{
|
||||
"value": map[string]interface{}{
|
||||
"enable": true,
|
||||
"debug": &ctx.Config{Name: "debug", Value: map[string]interface{}{"value": map[string]interface{}{"enable": false},
|
||||
"trace": map[string]interface{}{"value": map[string]interface{}{"enable": true}},
|
||||
"context": map[string]interface{}{"value": map[string]interface{}{"enable": false},
|
||||
"begin": map[string]interface{}{"value": map[string]interface{}{"enable": false}},
|
||||
"start": map[string]interface{}{"value": map[string]interface{}{"enable": false}},
|
||||
},
|
||||
"command": map[string]interface{}{
|
||||
"value": map[string]interface{}{
|
||||
"enable": true,
|
||||
},
|
||||
"command": map[string]interface{}{"value": map[string]interface{}{"enable": false},
|
||||
"demo": map[string]interface{}{"value": map[string]interface{}{"enable": true}},
|
||||
},
|
||||
"config": map[string]interface{}{
|
||||
"value": map[string]interface{}{
|
||||
"enable": true,
|
||||
},
|
||||
},
|
||||
"cache": map[string]interface{}{
|
||||
"value": map[string]interface{}{
|
||||
"enable": true,
|
||||
},
|
||||
"read": map[string]interface{}{
|
||||
"value": map[string]interface{}{
|
||||
"enable": true,
|
||||
},
|
||||
"ncontext": map[string]interface{}{
|
||||
"value": map[string]interface{}{
|
||||
"enable": true,
|
||||
"result": "hello",
|
||||
},
|
||||
},
|
||||
"config": map[string]interface{}{"value": map[string]interface{}{"enable": true}},
|
||||
"cache": map[string]interface{}{"value": map[string]interface{}{"enable": false},
|
||||
"read": map[string]interface{}{"value": map[string]interface{}{"enable": false},
|
||||
"ncontext": map[string]interface{}{"value": map[string]interface{}{"enable": false}},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
Commands: map[string]*ctx.Command{},
|
||||
Commands: map[string]*ctx.Command{
|
||||
"demo": &ctx.Command{Name: "wait arg...", Help: "等待调试", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Echo("hello world")
|
||||
return
|
||||
}},
|
||||
"wait": &ctx.Command{Name: "wait arg...", Help: "等待调试", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if gdb, ok := m.Target().Server.(*GDB); m.Assert(ok) {
|
||||
switch v := gdb.Wait(m, arg).(type) {
|
||||
case string:
|
||||
m.Echo(v)
|
||||
case nil:
|
||||
}
|
||||
}
|
||||
return
|
||||
}},
|
||||
"goon": &ctx.Command{Name: "goon arg...", Help: "继续运行", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if gdb, ok := m.Target().Server.(*GDB); m.Assert(ok) {
|
||||
gdb.Goon(arg)
|
||||
}
|
||||
return
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -40,6 +40,9 @@ func (lex *LEX) index(m *ctx.Message, hash string, h string) int {
|
||||
}
|
||||
|
||||
if x, e := strconv.Atoi(h); e == nil {
|
||||
if hash == "nhash" {
|
||||
lex.hash[hash] = x
|
||||
}
|
||||
m.Assert(hash != "npage" || x < m.Capi("npage"))
|
||||
return x
|
||||
}
|
||||
@ -49,7 +52,7 @@ func (lex *LEX) index(m *ctx.Message, hash string, h string) int {
|
||||
}
|
||||
|
||||
which[h] = m.Capi(hash, 1)
|
||||
m.Assert(hash != "npage" || m.Capi("npage") < m.Capi("nlang"))
|
||||
m.Assert(hash != "npage" || m.Capi("npage") < m.Confi("info", "nlang"))
|
||||
return which[h]
|
||||
}
|
||||
func (lex *LEX) charset(c byte) []byte {
|
||||
@ -59,10 +62,11 @@ func (lex *LEX) charset(c byte) []byte {
|
||||
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))
|
||||
|
||||
ss := []int{page}
|
||||
cn := make([]bool, m.Capi("ncell"))
|
||||
cc := make([]byte, 0, m.Capi("ncell"))
|
||||
cn := make([]bool, m.Confi("info", "ncell"))
|
||||
cc := make([]byte, 0, m.Confi("info", "ncell"))
|
||||
sn := make([]bool, m.Capi("nline"))
|
||||
|
||||
points := []*Point{}
|
||||
@ -156,7 +160,7 @@ func (lex *LEX) train(m *ctx.Message, page int, hash int, seed []byte) int {
|
||||
}
|
||||
|
||||
if state.next == 0 {
|
||||
if line == 0 || !m.Confs("compact") {
|
||||
if line == 0 || !m.Confs("info", "compact") {
|
||||
lex.mat = append(lex.mat, make(map[byte]*State))
|
||||
line = m.Capi("nline", 1) - 1
|
||||
sn = append(sn, false)
|
||||
@ -180,12 +184,14 @@ func (lex *LEX) train(m *ctx.Message, page int, hash int, seed []byte) int {
|
||||
}
|
||||
|
||||
for _, s := range ss {
|
||||
if s < m.Capi("nlang") || s >= len(lex.mat) {
|
||||
if s < m.Confi("info", "nlang") || s >= len(lex.mat) {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(lex.mat[s]) == 0 {
|
||||
m.Log("debug", "DEL: %d-%d", m.Capi("nline")-1, m.Capi("nline", 0, s))
|
||||
last := m.Capi("nline") - 1
|
||||
m.Cap("nline", "0")
|
||||
m.Log("debug", "DEL: %d-%d", last, m.Capi("nline", s))
|
||||
lex.mat = lex.mat[:s]
|
||||
}
|
||||
}
|
||||
@ -213,9 +219,11 @@ func (lex *LEX) train(m *ctx.Message, page int, hash int, seed []byte) int {
|
||||
}
|
||||
}
|
||||
|
||||
m.Log("debug", "%s %s npage: %v nhash: %v nseed: %v", "train", "lex", m.Capi("npage"), m.Capi("nhash"), m.Capi("nseed"))
|
||||
return hash
|
||||
}
|
||||
func (lex *LEX) parse(m *ctx.Message, page int, line []byte) (hash int, rest []byte, word []byte) {
|
||||
m.Log("debug", "%s %s page: %v line: %v", "parse", "lex", page, line)
|
||||
|
||||
pos := 0
|
||||
for star, s := 0, page; s != 0 && pos < len(line); pos++ {
|
||||
@ -231,11 +239,11 @@ func (lex *LEX) parse(m *ctx.Message, page int, line []byte) (hash int, rest []b
|
||||
}
|
||||
|
||||
state := lex.mat[s][c]
|
||||
m.Log("debug", "(%d,%d): %v", s, c, state)
|
||||
if state == nil {
|
||||
s, star, pos = star, 0, pos-1
|
||||
continue
|
||||
}
|
||||
m.Log("debug", "GET (%d,%d): %v", s, c, state)
|
||||
|
||||
word = append(word, c)
|
||||
|
||||
@ -256,6 +264,8 @@ func (lex *LEX) parse(m *ctx.Message, page int, line []byte) (hash int, rest []b
|
||||
pos, word = 0, word[:0]
|
||||
}
|
||||
rest = line[pos:]
|
||||
|
||||
m.Log("debug", "%s %s hash: %v word: %v rest: %v", "parse", "lex", hash, word, rest)
|
||||
return
|
||||
}
|
||||
|
||||
@ -268,30 +278,18 @@ func (lex *LEX) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
||||
return s
|
||||
}
|
||||
func (lex *LEX) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||
lex.Caches["ncell"] = &ctx.Cache{Name: "字符上限", Value: "128", Help: "字符集合的最大数量"}
|
||||
lex.Caches["nlang"] = &ctx.Cache{Name: "词法上限", Value: "64", Help: "词法集合的最大数量"}
|
||||
|
||||
lex.Caches["nseed"] = &ctx.Cache{Name: "种子数量", Value: "0", Help: "词法模板的数量"}
|
||||
lex.Caches["npage"] = &ctx.Cache{Name: "集合数量", Value: "0", Help: "词法集合的数量"}
|
||||
lex.Caches["nhash"] = &ctx.Cache{Name: "类型数量", Value: "0", Help: "单词类型的数量"}
|
||||
|
||||
lex.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: "64", Help: "状态机状态的数量"}
|
||||
lex.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: m.Conf("info", "nlang"), Help: "状态机状态的数量"}
|
||||
lex.Caches["nnode"] = &ctx.Cache{Name: "节点数量", Value: "0", Help: "状态机连接的逻辑数量"}
|
||||
lex.Caches["nreal"] = &ctx.Cache{Name: "实点数量", Value: "0", Help: "状态机连接的存储数量"}
|
||||
|
||||
lex.Configs["compact"] = &ctx.Config{Name: "紧凑模式", Value: "true", Help: "词法状态的共用"}
|
||||
|
||||
if len(arg) > 0 {
|
||||
if _, e := strconv.Atoi(arg[0]); e == nil {
|
||||
m.Cap("nlang", arg[0])
|
||||
m.Cap("nline", arg[0])
|
||||
}
|
||||
}
|
||||
|
||||
lex.page = map[string]int{"nil": 0}
|
||||
lex.hash = map[string]int{"nil": 0}
|
||||
|
||||
lex.mat = make([]map[byte]*State, m.Capi("nlang"))
|
||||
lex.mat = make([]map[byte]*State, m.Confi("info", "nlang"))
|
||||
lex.state = make(map[State]*State)
|
||||
|
||||
lex.char = map[byte][]byte{
|
||||
@ -323,6 +321,7 @@ var Index = &ctx.Context{Name: "lex", Help: "词法中心",
|
||||
Configs: map[string]*ctx.Config{
|
||||
"npage": &ctx.Config{Name: "npage", Value: "1", Help: "npage"},
|
||||
"nhash": &ctx.Config{Name: "nhash", Value: "1", Help: "npage"},
|
||||
"info": &ctx.Config{Name: "info", Value: map[string]interface{}{"compact": true, "ncell": 128, "nlang": 64}, Help: "嵌套层级日志的标记"},
|
||||
},
|
||||
Commands: map[string]*ctx.Command{
|
||||
"spawn": &ctx.Command{Name: "spawn", Help: "添加词法规则", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
@ -338,6 +337,8 @@ var Index = &ctx.Context{Name: "lex", Help: "词法中心",
|
||||
if lex.mat[page] == nil {
|
||||
lex.mat[page] = map[byte]*State{}
|
||||
}
|
||||
m.Cap("npage", len(lex.page))
|
||||
m.Cap("nhash", len(lex.hash))
|
||||
|
||||
m.Result(0, lex.train(m, page, hash, []byte(arg[0])))
|
||||
lex.seed = append(lex.seed, &Seed{page, hash, arg[0]})
|
||||
@ -385,7 +386,7 @@ var Index = &ctx.Context{Name: "lex", Help: "词法中心",
|
||||
m.Table()
|
||||
case "mat":
|
||||
for _, v := range lex.mat {
|
||||
for j := byte(0); j < byte(m.Capi("ncell")); j++ {
|
||||
for j := byte(0); j < byte(m.Confi("info", "ncell")); j++ {
|
||||
s := v[j]
|
||||
if s == nil {
|
||||
m.Add("append", fmt.Sprintf("%c", j), "")
|
||||
|
@ -2,42 +2,59 @@ package log
|
||||
|
||||
import (
|
||||
"contexts/ctx"
|
||||
"toolkit"
|
||||
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type LOG struct {
|
||||
out *os.File
|
||||
file map[string]*os.File
|
||||
*ctx.Context
|
||||
}
|
||||
|
||||
func (log *LOG) LOG(msg *ctx.Message, action string, str string) {
|
||||
m := log.Context.Message()
|
||||
func (log *LOG) Value(msg *ctx.Message, arg ...interface{}) map[string]interface{} {
|
||||
args := append(kit.Trans(arg...), "value")
|
||||
|
||||
if m.Confs("silent", action) {
|
||||
return
|
||||
}
|
||||
if msg.Target() == nil {
|
||||
return
|
||||
}
|
||||
if m.Confs("module", fmt.Sprintf("%s.%s", msg.Target().Name, action)) {
|
||||
return
|
||||
}
|
||||
if value, ok := kit.Chain(log.Configs["output"].Value, args).(map[string]interface{}); ok {
|
||||
if kit.Right(value["source"]) && kit.Format(value["source"]) != msg.Source().Name {
|
||||
return nil
|
||||
}
|
||||
|
||||
color := 0
|
||||
if m.Confs("flag_color") && m.Confs("color", action) {
|
||||
color = m.Confi("color", action)
|
||||
if kit.Right(value["target"]) && kit.Format(value["target"]) != msg.Target().Name {
|
||||
return nil
|
||||
}
|
||||
|
||||
// kit.Log("error", "value %v %v", kit.Format(args), kit.Format(value))
|
||||
return value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (log *LOG) Log(msg *ctx.Message, action string, str string, arg ...interface{}) {
|
||||
m := log.Message()
|
||||
m.Capi("nlog", 1)
|
||||
|
||||
date := time.Now().Format(m.Conf("flag_time"))
|
||||
action = fmt.Sprintf("%d %s(%s->%s)", msg.Code(), action, msg.Source().Name, msg.Target().Name)
|
||||
args := kit.Trans(arg...)
|
||||
for _, v := range []string{action, "bench"} {
|
||||
for i := len(args); i >= 0; i-- {
|
||||
if value := log.Value(m, append([]string{v}, args[:i]...)); kit.Right(value) && kit.Right(value["file"]) {
|
||||
name := kit.Format(value["file"])
|
||||
file, ok := log.file[name]
|
||||
if !ok {
|
||||
if f, e := os.Create(name); e == nil {
|
||||
file, log.file[name] = f, f
|
||||
kit.Log("error", "%s log file %s", "open", name)
|
||||
} else {
|
||||
kit.Log("error", "%s log file %s %s", "open", name, e)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if color > 0 {
|
||||
log.out.WriteString(fmt.Sprintf("%s\033[%dm%s %s\033[0m\n", date, color, action, str))
|
||||
} else {
|
||||
log.out.WriteString(fmt.Sprintf("%s%s %s\n", date, action, str))
|
||||
fmt.Fprintln(file, fmt.Sprintf("%d %s %s%s %s%s", m.Capi("nout", 1), msg.Format(kit.Trans(value["meta"])...),
|
||||
kit.Format(value["color_begin"]), action, fmt.Sprintf(str, arg...), kit.Format(value["color_end"])))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,9 +67,7 @@ func (log *LOG) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
||||
return s
|
||||
}
|
||||
func (log *LOG) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||
log.Configs["flag_color"] = &ctx.Config{Name: "flag_color", Value: "true", Help: "模块日志输出颜色"}
|
||||
log.Configs["flag_time"] = &ctx.Config{Name: "flag_time", Value: "2006/01/02 15:04:05 ", Help: "模块日志输出颜色"}
|
||||
log.Configs["bench.log"] = &ctx.Config{Name: "bench.log", Value: "bench.log", Help: "模块日志输出的文件"}
|
||||
log.file = map[string]*os.File{}
|
||||
return log
|
||||
}
|
||||
func (log *LOG) Start(m *ctx.Message, arg ...string) bool {
|
||||
@ -63,63 +78,30 @@ func (log *LOG) Close(m *ctx.Message, arg ...string) bool {
|
||||
case m.Target():
|
||||
case m.Source():
|
||||
}
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
var Pulse *ctx.Message
|
||||
var Index = &ctx.Context{Name: "log", Help: "日志中心",
|
||||
Caches: map[string]*ctx.Cache{
|
||||
"nlog": &ctx.Cache{Name: "nlog", Value: "0", Help: "日志屏蔽类型"},
|
||||
"nlog": &ctx.Cache{Name: "nlog", Value: "0", Help: "日志调用数量"},
|
||||
"nout": &ctx.Cache{Name: "nout", Value: "0", Help: "日志输出数量"},
|
||||
},
|
||||
Configs: map[string]*ctx.Config{
|
||||
"silent": &ctx.Config{Name: "silent", Value: map[string]interface{}{"cb": true, "find": true}, Help: "日志屏蔽类型"},
|
||||
"module": &ctx.Config{Name: "module", Value: map[string]interface{}{
|
||||
"log": map[string]interface{}{"cmd": true},
|
||||
"lex": map[string]interface{}{"cmd": true, "debug": true},
|
||||
"yac": map[string]interface{}{"cmd": true, "debug": true},
|
||||
"matrix1": map[string]interface{}{"cmd": true, "debug": true},
|
||||
}, Help: "日志屏蔽模块"},
|
||||
"color": &ctx.Config{Name: "color", Value: map[string]interface{}{
|
||||
"debug": 0, "error": 31, "check": 31,
|
||||
"cmd": 32, "conf": 33,
|
||||
"search": 35, "find": 35, "cb": 35, "lock": 35,
|
||||
"begin": 36, "start": 36, "close": 36,
|
||||
}, Help: "日志输出颜色"},
|
||||
"log_name": &ctx.Config{Name: "log_name", Value: "dump", Help: "日志屏蔽类型"},
|
||||
"output": &ctx.Config{Name: "output", Value: map[string]interface{}{
|
||||
"error": map[string]interface{}{"value": map[string]interface{}{"file": "error.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
|
||||
"bench": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}}},
|
||||
"begin": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
|
||||
"start": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
|
||||
"cmd": map[string]interface{}{"value": map[string]interface{}{"file": "bench.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[32m", "color_end": "\033[0m"},
|
||||
"lex": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[32m", "color_end": "\033[0m"}},
|
||||
},
|
||||
"debug": map[string]interface{}{"value": map[string]interface{}{"file": "debug.log", "meta": []interface{}{"time", "ship"}}},
|
||||
}, Help: "日志输出配置"},
|
||||
},
|
||||
Commands: map[string]*ctx.Command{
|
||||
"init": &ctx.Command{Name: "init file", Help: "输出日志, level: 日志类型, string: 日志内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if log, ok := m.Target().Server.(*LOG); ok {
|
||||
log.out = m.Sess("nfs").Cmd("open", m.Confx("bench.log", arg, 0)).Optionv("out").(*os.File)
|
||||
log.out.Truncate(0)
|
||||
fmt.Fprintln(log.out, "\n\n")
|
||||
}
|
||||
return
|
||||
}},
|
||||
"log": &ctx.Command{Name: "log level string...", Help: "输出日志, level: 日志类型, string: 日志内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if log, ok := m.Target().Server.(*LOG); m.Assert(ok) && log.out != nil {
|
||||
if m.Confs("silent", arg[0]) {
|
||||
return
|
||||
}
|
||||
msg, ok := m.Optionv("msg").(*ctx.Message)
|
||||
if !ok {
|
||||
msg = m
|
||||
}
|
||||
if m.Confs("module", fmt.Sprintf("%s.%s", msg.Target().Name, arg[0])) {
|
||||
return
|
||||
}
|
||||
color := 0
|
||||
if m.Confs("flag_color") && m.Confs("color", arg[0]) {
|
||||
color = m.Confi("color", arg[0])
|
||||
}
|
||||
date := time.Now().Format(m.Conf("flag_time"))
|
||||
action := fmt.Sprintf("%d %s(%s->%s)", msg.Code(), arg[0], msg.Source().Name, msg.Target().Name)
|
||||
cmd := strings.Join(arg[1:], "")
|
||||
if color > 0 {
|
||||
log.out.WriteString(fmt.Sprintf("%s\033[%dm%s %s\033[0m\n", date, color, action, cmd))
|
||||
} else {
|
||||
log.out.WriteString(fmt.Sprintf("%s%s %s\n", date, action, cmd))
|
||||
}
|
||||
if log, ok := m.Target().Server.(*LOG); m.Assert(ok) {
|
||||
log.Log(m, arg[0], arg[1], arg[2:])
|
||||
}
|
||||
return
|
||||
}},
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
"os/exec"
|
||||
"path"
|
||||
"regexp"
|
||||
"runtime"
|
||||
// "runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -28,8 +28,9 @@ import (
|
||||
)
|
||||
|
||||
type NFS struct {
|
||||
in *os.File
|
||||
out *os.File
|
||||
in *os.File
|
||||
out *os.File
|
||||
|
||||
pages []string
|
||||
width int
|
||||
height int
|
||||
@ -207,6 +208,8 @@ func (nfs *NFS) color(str string, attr ...int) *NFS {
|
||||
return nfs
|
||||
}
|
||||
func (nfs *NFS) print(str string) bool {
|
||||
nfs.out.WriteString(str)
|
||||
return true
|
||||
ls := strings.Split(str, "\n")
|
||||
for i, l := range ls {
|
||||
rest := ""
|
||||
@ -237,6 +240,9 @@ func (nfs *NFS) print(str string) bool {
|
||||
}
|
||||
|
||||
func (nfs *NFS) prompt(arg ...string) string {
|
||||
nfs.out.WriteString("> ")
|
||||
return "> "
|
||||
|
||||
ps := nfs.Option("prompt")
|
||||
if nfs.Caps("windows") {
|
||||
nfs.color(ps)
|
||||
@ -585,34 +591,80 @@ func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||
return nfs
|
||||
}
|
||||
func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
|
||||
if len(arg) > 0 && arg[0] == "scan" {
|
||||
nfs.Caches["ninput"] = &ctx.Cache{Value: "0"}
|
||||
nfs.Caches["noutput"] = &ctx.Cache{Value: "0"}
|
||||
nfs.Configs["input"] = &ctx.Config{Value: []interface{}{}}
|
||||
nfs.Configs["output"] = &ctx.Config{Value: []interface{}{}}
|
||||
|
||||
if nfs.in = m.Optionv("in").(*os.File); m.Has("out") {
|
||||
nfs.out = m.Optionv("out").(*os.File)
|
||||
}
|
||||
|
||||
line, bio := "", bufio.NewScanner(nfs)
|
||||
for nfs.prompt(); !m.Options("scan_end"); nfs.prompt() {
|
||||
for bio.Scan() {
|
||||
if line = line + bio.Text(); !strings.HasSuffix(line, "\\") {
|
||||
break
|
||||
}
|
||||
line = strings.TrimSuffix(line, "\\")
|
||||
}
|
||||
|
||||
m.Confv("input", -2, map[string]interface{}{"time": time.Now().Unix(), "line": line})
|
||||
m.Log("debug", "%s %d %d [%s]", "input", m.Capi("ninput", 1), len(line), line)
|
||||
|
||||
for i := m.Capi("ninput") - 1; i < m.Capi("ninput"); i++ {
|
||||
line = m.Conf("input", []interface{}{i, "line"})
|
||||
|
||||
msg := m.Spawn(m.Source()).Set("detail", line).Set("option", "file_pos", i)
|
||||
m.Back(msg)
|
||||
|
||||
lines := strings.Split(strings.Join(msg.Meta["result"], ""), "\n")
|
||||
for _, line := range lines {
|
||||
if line != "" {
|
||||
m.Log("debug", "%s %d %d [%s]", "output", m.Capi("noutput", 1), len(line), line)
|
||||
m.Confv("output", -2, map[string]interface{}{"time": time.Now().Unix(), "line": line})
|
||||
nfs.print(line)
|
||||
nfs.print("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
line = ""
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
nfs.Message = m
|
||||
if len(arg) > 0 && arg[0] == "scan" {
|
||||
nfs.Caches["windows"] = &ctx.Cache{Name: "windows", Value: "false", Help: "termbox"}
|
||||
nfs.Caches["termbox"] = &ctx.Cache{Name: "termbox", Value: "false", Help: "termbox"}
|
||||
nfs.Caches["cursor_pos"] = &ctx.Cache{Name: "cursor_pos", Value: "1", Help: "termbox"}
|
||||
|
||||
nfs.Configs["color"] = &ctx.Config{Name: "color", Value: "false", Help: "color"}
|
||||
nfs.Configs["fgcolor"] = &ctx.Config{Name: "fgcolor", Value: "9", Help: "fgcolor"}
|
||||
nfs.Configs["bgcolor"] = &ctx.Config{Name: "bgcolor", Value: "9", Help: "bgcolor"}
|
||||
nfs.Configs["pscolor"] = &ctx.Config{Name: "pscolor", Value: "2", Help: "pscolor"}
|
||||
nfs.Configs["statusfgcolor"] = &ctx.Config{Name: "statusfgcolor", Value: "1", Help: "pscolor"}
|
||||
nfs.Configs["statusbgcolor"] = &ctx.Config{Name: "statusbgcolor", Value: "2", Help: "pscolor"}
|
||||
|
||||
// nfs.Caches["windows"] = &ctx.Cache{Name: "windows", Value: "false", Help: "termbox"}
|
||||
// nfs.Caches["termbox"] = &ctx.Cache{Name: "termbox", Value: "false", Help: "termbox"}
|
||||
// nfs.Caches["cursor_pos"] = &ctx.Cache{Name: "cursor_pos", Value: "1", Help: "termbox"}
|
||||
//
|
||||
// nfs.Configs["color"] = &ctx.Config{Name: "color", Value: "false", Help: "color"}
|
||||
// nfs.Configs["fgcolor"] = &ctx.Config{Name: "fgcolor", Value: "9", Help: "fgcolor"}
|
||||
// nfs.Configs["bgcolor"] = &ctx.Config{Name: "bgcolor", Value: "9", Help: "bgcolor"}
|
||||
// nfs.Configs["pscolor"] = &ctx.Config{Name: "pscolor", Value: "2", Help: "pscolor"}
|
||||
// nfs.Configs["statusfgcolor"] = &ctx.Config{Name: "statusfgcolor", Value: "1", Help: "pscolor"}
|
||||
// nfs.Configs["statusbgcolor"] = &ctx.Config{Name: "statusbgcolor", Value: "2", Help: "pscolor"}
|
||||
//
|
||||
nfs.in = m.Optionv("in").(*os.File)
|
||||
bio := bufio.NewScanner(nfs)
|
||||
|
||||
s, e := nfs.in.Stat()
|
||||
m.Assert(e)
|
||||
m.Capi("size", int(s.Size()))
|
||||
|
||||
if m.Cap("stream", arg[1]) == "stdio" {
|
||||
nfs.out = m.Optionv("out").(*os.File)
|
||||
if !m.Caps("windows", runtime.GOOS == "windows") {
|
||||
termbox.Init()
|
||||
defer termbox.Close()
|
||||
nfs.width, nfs.height = termbox.Size()
|
||||
nfs.Cap("termbox", "true")
|
||||
nfs.Conf("color", "true")
|
||||
}
|
||||
// if !m.Caps("windows", runtime.GOOS == "windows") {
|
||||
// termbox.Init()
|
||||
// defer termbox.Close()
|
||||
// nfs.width, nfs.height = termbox.Size()
|
||||
// nfs.Cap("termbox", "true")
|
||||
// nfs.Conf("color", "true")
|
||||
// }
|
||||
// if !m.Options("init.shy") {
|
||||
//
|
||||
// for _, v := range []string{
|
||||
@ -640,8 +692,11 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
|
||||
|
||||
line := ""
|
||||
for nfs.prompt(); !m.Options("scan_end") && bio.Scan(); nfs.prompt() {
|
||||
kit.Log("error", "stdio read %v", "text")
|
||||
text := bio.Text()
|
||||
m.Capi("nread", len(text)+1)
|
||||
kit.Log("error", "stdio read %v", text)
|
||||
continue
|
||||
|
||||
if line += text; len(text) > 0 && text[len(text)-1] == '\\' {
|
||||
line = line[:len(line)-1]
|
||||
@ -669,6 +724,8 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
|
||||
}
|
||||
line = ""
|
||||
}
|
||||
|
||||
kit.Log("error", "stdio read %v", line)
|
||||
if !m.Options("scan_end") {
|
||||
msg := m.Spawn(m.Source()).Set("detail", "return")
|
||||
m.Back(msg)
|
||||
|
@ -41,7 +41,9 @@ func (yac *YAC) name(page int) string {
|
||||
}
|
||||
return fmt.Sprintf("yac%d", page)
|
||||
}
|
||||
func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Point, []*Point) {
|
||||
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)
|
||||
|
||||
ss := []int{page}
|
||||
sn := make([]bool, m.Capi("nline"))
|
||||
points, ends := []*Point{}, []*Point{}
|
||||
@ -58,7 +60,7 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po
|
||||
switch word[i] {
|
||||
case "opt{", "rep{":
|
||||
sn[s] = true
|
||||
num, point, end := yac.train(m, s, 0, word[i+1:])
|
||||
num, point, end := yac.train(m, s, 0, word[i+1:], level+1)
|
||||
n, points = num, append(points, point...)
|
||||
|
||||
for _, x := range end {
|
||||
@ -100,11 +102,10 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po
|
||||
} else {
|
||||
m.Capi("nnode", 1)
|
||||
}
|
||||
m.Log("debug", "GET(%d, %d): %v \033[31m(%s)\033[0m", s, c, state, word[i])
|
||||
if state.next == 0 {
|
||||
state.next = m.Capi("nline", 1) - 1
|
||||
yac.mat = append(yac.mat, map[byte]*State{})
|
||||
for i := 0; i < m.Capi("nlang"); i++ {
|
||||
for i := 0; i < m.Capi("nline"); i++ {
|
||||
yac.mat[state.next][byte(i)] = nil
|
||||
}
|
||||
sn = append(sn, false)
|
||||
@ -113,7 +114,6 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po
|
||||
yac.mat[s][c] = state
|
||||
ends = append(ends, &Point{s, c})
|
||||
points = append(points, &Point{s, c})
|
||||
m.Log("debug", "SET(%d, %d): %v", s, c, state)
|
||||
}
|
||||
}
|
||||
next:
|
||||
@ -127,7 +127,7 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po
|
||||
}
|
||||
}
|
||||
for _, s := range ss {
|
||||
if s < m.Capi("nlang") || s >= len(yac.mat) {
|
||||
if s < m.Confi("info", "nlang") || s >= len(yac.mat) {
|
||||
continue
|
||||
}
|
||||
void := true
|
||||
@ -138,7 +138,9 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po
|
||||
}
|
||||
}
|
||||
if void {
|
||||
m.Log("debug", "DEL: %d-%d", m.Capi("nline")-1, m.Capi("nline", 0, s))
|
||||
last := m.Capi("nline") - 1
|
||||
m.Cap("nline", "0")
|
||||
m.Log("debug", "DEL: %d-%d", last, m.Capi("nline", s))
|
||||
yac.mat = yac.mat[:s]
|
||||
}
|
||||
}
|
||||
@ -165,12 +167,13 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
if m.Confs("debug") {
|
||||
m.Log("debug", "%s\\%d %s(%d): %s", m.Conf("label")[0:level], level, yac.name(page), page, line)
|
||||
}
|
||||
m.Log("debug", "%s %s\\%d %s(%d): %s", "parse", strings.Repeat("#", level), level, yac.name(page), page, line)
|
||||
|
||||
hash, word := 0, []string{}
|
||||
for star, s := 0, page; s != 0 && len(line) > 0; {
|
||||
//解析空白
|
||||
@ -197,8 +200,8 @@ func (yac *YAC) parse(m *ctx.Message, out *ctx.Message, page int, void int, line
|
||||
}
|
||||
}
|
||||
if state == nil { //嵌套语法递归解析
|
||||
for i := 0; i < m.Capi("ncell"); i++ {
|
||||
if x := yac.mat[s][byte(i)]; i < m.Capi("nlang") && x != 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
|
||||
@ -224,9 +227,8 @@ func (yac *YAC) parse(m *ctx.Message, out *ctx.Message, page int, void int, line
|
||||
word = msg.Meta["result"]
|
||||
}
|
||||
}
|
||||
if m.Confs("debug") {
|
||||
m.Log("debug", "%s/%d %s(%d): %v", m.Conf("label")[0:level], level, yac.name(page), page, word)
|
||||
}
|
||||
|
||||
m.Log("debug", "%s %s/%d %s(%d): %v", "parse", strings.Repeat("#", level), level, yac.name(page), page, word)
|
||||
return line, word, hash
|
||||
}
|
||||
|
||||
@ -242,66 +244,18 @@ func (yac *YAC) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
||||
return s
|
||||
}
|
||||
func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||
if len(arg) > 0 && arg[0] == "scan" {
|
||||
return yac
|
||||
}
|
||||
|
||||
yac.Caches["ncell"] = &ctx.Cache{Name: "词法上限", Value: "128", Help: "词法集合的最大数量"}
|
||||
yac.Caches["nlang"] = &ctx.Cache{Name: "语法上限", Value: "32", Help: "语法集合的最大数量"}
|
||||
yac.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: "32", 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.Capi("nlang"))
|
||||
yac.state = map[State]*State{}
|
||||
return yac
|
||||
}
|
||||
func (yac *YAC) Start(m *ctx.Message, arg ...string) (close bool) {
|
||||
if len(arg) > 0 && arg[0] == "scan" {
|
||||
var out *ctx.Message
|
||||
data := make(chan string, 1)
|
||||
next := make(chan bool, 1)
|
||||
close = true
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
// m.Option("scan_end", true)
|
||||
next <- true
|
||||
}
|
||||
}()
|
||||
//加载文件
|
||||
nfs := m.Sess("nfs").Call(func(buf *ctx.Message) *ctx.Message {
|
||||
out = buf
|
||||
data <- buf.Detail(0) + "; "
|
||||
<-next
|
||||
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:])
|
||||
// m.Find("log").Cmd("silent", yac.Context.Name, "debug", true)
|
||||
//解析循环
|
||||
for m.Cap("stream", nfs.Target().Name); !m.Options("scan_end"); next <- true {
|
||||
line := <-data
|
||||
if len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
_, word, _ := yac.parse(m, out, m.Optioni("page"), m.Optioni("void"), line, 1)
|
||||
if len(word) > 0 {
|
||||
word = word[:len(word)-1]
|
||||
if last := len(word) - 1; last >= 0 && len(word[last]) > 0 && word[last][len(word[last])-1] != '\n' {
|
||||
word = append(word, "\n")
|
||||
}
|
||||
}
|
||||
out.Result(0, word)
|
||||
}
|
||||
return true
|
||||
return false
|
||||
}
|
||||
return false
|
||||
return true
|
||||
}
|
||||
func (yac *YAC) Close(m *ctx.Message, arg ...string) bool {
|
||||
switch yac.Context {
|
||||
@ -316,57 +270,76 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
|
||||
"nparse": &ctx.Cache{Name: "nparse", Value: "0", Help: "解析器数量"},
|
||||
},
|
||||
Configs: map[string]*ctx.Config{
|
||||
"compact_lex": &ctx.Config{Name: "compact_lex(true/false)", Value: "true", Help: "调试模式,on:打印,off:不打印)"},
|
||||
"debug": &ctx.Config{Name: "debug", Value: "false", Help: "词法集合的最大数量"},
|
||||
"ncell": &ctx.Config{Name: "词法上限", Value: "128", Help: "词法集合的最大数量"},
|
||||
"nlang": &ctx.Config{Name: "语法上限", Value: "32", Help: "语法集合的最大数量"},
|
||||
"label": &ctx.Config{Name: "嵌套标记", Value: "####################", 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": "str", "hash": "str", "word": []interface{}{"mul{", "\"[^\"]*\"", "'[^']*'", "}"}},
|
||||
map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"mul{", "$", "@", "}", "key"}},
|
||||
|
||||
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"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "for", "word": []interface{}{"for", "index", "exp", "opt{", "exp", "}", "exp"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "label", "word": []interface{}{"label", "exp"}},
|
||||
map[string]interface{}{"page": "stm", "hash": "goto", "word": []interface{}{"goto", "exp", "opt{", "exp", "}", "exp"}},
|
||||
|
||||
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: "嵌套层级日志的标记"},
|
||||
},
|
||||
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) {
|
||||
m.Cmd("train", "void", "void", "[\t ]+")
|
||||
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: "状态机连接的存储数量"}
|
||||
|
||||
m.Cmd("train", "key", "key", "[A-Za-z_][A-Za-z_0-9]*")
|
||||
m.Cmd("train", "num", "num", "mul{", "0", "-?[1-9][0-9]*", "0[0-9]+", "0x[0-9]+", "}")
|
||||
m.Cmd("train", "str", "str", "mul{", "\"[^\"]*\"", "'[^']*'", "}")
|
||||
m.Cmd("train", "exe", "exe", "mul{", "$", "@", "}", "key")
|
||||
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: "语句类型的数量"}
|
||||
|
||||
m.Cmd("train", "op1", "op1", "mul{", "-z", "-n", "}")
|
||||
m.Cmd("train", "op1", "op1", "mul{", "-e", "-f", "-d", "}")
|
||||
m.Cmd("train", "op1", "op1", "mul{", "-", "+", "}")
|
||||
m.Cmd("train", "op2", "op2", "mul{", ":=", "=", "+=", "}")
|
||||
m.Cmd("train", "op2", "op2", "mul{", "+", "-", "*", "/", "%", "}")
|
||||
m.Cmd("train", "op2", "op2", "mul{", "<", "<=", ">", ">=", "==", "!=", "}")
|
||||
m.Cmd("train", "op2", "op2", "mul{", "~", "!~", "}")
|
||||
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"}
|
||||
|
||||
m.Cmd("train", "val", "val", "opt{", "op1", "}", "mul{", "num", "key", "str", "exe", "}")
|
||||
m.Cmd("train", "exp", "exp", "val", "rep{", "op2", "val", "}")
|
||||
m.Cmd("train", "map", "map", "key", ":", "\\[", "rep{", "key", "}", "\\]")
|
||||
m.Cmd("train", "exp", "exp", "\\{", "rep{", "map", "}", "\\}")
|
||||
m.Cmd("train", "val", "val", "opt{", "op1", "}", "(", "exp", ")")
|
||||
yac.mat = make([]map[byte]*State, m.Confi("info", "nlang"))
|
||||
yac.state = map[State]*State{}
|
||||
|
||||
m.Cmd("train", "stm", "var", "var", "key", "opt{", "=", "exp", "}")
|
||||
m.Cmd("train", "stm", "let", "let", "key", "opt{", "=", "exp", "}")
|
||||
m.Cmd("train", "stm", "var", "var", "key", "<-")
|
||||
m.Cmd("train", "stm", "var", "var", "key", "<-", "opt{", "exe", "}")
|
||||
m.Cmd("train", "stm", "let", "let", "key", "<-", "opt{", "exe", "}")
|
||||
|
||||
m.Cmd("train", "stm", "if", "if", "exp")
|
||||
m.Cmd("train", "stm", "else", "else")
|
||||
m.Cmd("train", "stm", "end", "end")
|
||||
m.Cmd("train", "stm", "for", "for", "opt{", "exp", ";", "}", "exp")
|
||||
m.Cmd("train", "stm", "for", "for", "index", "exp", "opt{", "exp", "}", "exp")
|
||||
m.Cmd("train", "stm", "label", "label", "exp")
|
||||
m.Cmd("train", "stm", "goto", "goto", "exp", "opt{", "exp", "}", "exp")
|
||||
|
||||
m.Cmd("train", "stm", "expr", "expr", "rep{", "exp", "}")
|
||||
m.Cmd("train", "stm", "return", "return", "rep{", "exp", "}")
|
||||
|
||||
m.Cmd("train", "word", "word", "mul{", "~", "!", "=", "\\?\\?", "\\?", "<", ">$", ">@", ">", "\\|", "%", "exe", "str", "[a-zA-Z0-9_/\\-.:]+", "}")
|
||||
m.Cmd("train", "cmd", "cmd", "rep{", "word", "}")
|
||||
m.Cmd("train", "exe", "exe", "$", "(", "cmd", ")")
|
||||
|
||||
m.Cmd("train", "line", "line", "opt{", "mul{", "stm", "cmd", "}", "}", "mul{", ";", "\n", "#[^\n]*\n", "}")
|
||||
m.Confm("seed", func(line int, seed map[string]interface{}) {
|
||||
m.Spawn().Cmd("train", seed["page"], seed["hash"], seed["word"])
|
||||
})
|
||||
}
|
||||
return
|
||||
}},
|
||||
"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) {
|
||||
@ -376,10 +349,10 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
|
||||
page = m.Capi("npage", 1)
|
||||
yac.page[arg[0]] = page
|
||||
yac.word[page] = arg[0]
|
||||
m.Assert(page < m.Capi("nlang"), "语法集合过多")
|
||||
m.Assert(page < m.Confi("info", "nlang"), "语法集合过多")
|
||||
|
||||
yac.mat[page] = map[byte]*State{}
|
||||
for i := 0; i < m.Capi("nlang"); i++ {
|
||||
for i := 0; i < m.Confi("info", "nlang"); i++ {
|
||||
yac.mat[page][byte(i)] = nil
|
||||
}
|
||||
}
|
||||
@ -392,10 +365,10 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
|
||||
}
|
||||
|
||||
if yac.lex == nil {
|
||||
yac.lex = m.Sess("lex", "lex").Cmd("spawn")
|
||||
yac.lex = m.Cmd("lex.spawn")
|
||||
}
|
||||
|
||||
yac.train(m, page, hash, arg[2:])
|
||||
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")))
|
||||
}
|
||||
@ -454,7 +427,7 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心",
|
||||
m.Sort("code", "int").Table()
|
||||
case "mat":
|
||||
for _, v := range yac.mat {
|
||||
for j := byte(0); j < byte(m.Capi("ncell")); j++ {
|
||||
for j := byte(0); j < byte(m.Confi("info", "ncell")); j++ {
|
||||
s := v[j]
|
||||
if s == nil {
|
||||
m.Add("append", fmt.Sprintf("%d", j), "")
|
||||
|
@ -22,6 +22,14 @@ func Errorf(str string, args ...interface{}) {
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, str, args...)
|
||||
}
|
||||
func Log(action string, str string, args ...interface{}) {
|
||||
if len(args) == 0 {
|
||||
fmt.Fprintf(os.Stderr, "%s", str)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, str, args...)
|
||||
}
|
||||
fmt.Fprintln(os.Stderr)
|
||||
}
|
||||
|
||||
func Int(arg ...interface{}) int {
|
||||
result := 0
|
||||
@ -57,8 +65,9 @@ func Right(arg ...interface{}) bool {
|
||||
case "", "0", "false", "off", "no", "error: ":
|
||||
result = result || false
|
||||
break
|
||||
default:
|
||||
result = result || true
|
||||
}
|
||||
result = result || true
|
||||
case error:
|
||||
result = result || false
|
||||
default:
|
||||
@ -87,8 +96,8 @@ func Format(arg ...interface{}) string {
|
||||
result = append(result, fmt.Sprintf("%d", int(val)))
|
||||
case time.Time:
|
||||
result = append(result, fmt.Sprintf("%d", val.Format("2006-01-02 15:03:04")))
|
||||
case error:
|
||||
result = append(result, fmt.Sprintf("%v", val))
|
||||
// case error:
|
||||
// result = append(result, fmt.Sprintf("%v", val))
|
||||
default:
|
||||
if b, e := json.Marshal(val); e == nil {
|
||||
result = append(result, string(b))
|
||||
@ -97,10 +106,17 @@ func Format(arg ...interface{}) string {
|
||||
}
|
||||
|
||||
if len(result) > 1 {
|
||||
args := []interface{}{}
|
||||
if n := strings.Count(result[0], "%") - strings.Count(result[0], "%%"); len(result) > n+1 {
|
||||
return fmt.Sprintf(result[0], result[1:n+1]) + strings.Join(result[n+1:], "")
|
||||
for i := 1; i < n+1; i++ {
|
||||
args = append(args, result[i])
|
||||
}
|
||||
return fmt.Sprintf(result[0], args...) + strings.Join(result[n+1:], "")
|
||||
} else if len(result) == n+1 {
|
||||
return fmt.Sprintf(result[0], result[1:])
|
||||
for i := 1; i < len(result); i++ {
|
||||
args = append(args, result[i])
|
||||
}
|
||||
return fmt.Sprintf(result[0], args...)
|
||||
}
|
||||
}
|
||||
return strings.Join(result, "")
|
||||
@ -109,13 +125,17 @@ func Formats(arg ...interface{}) string {
|
||||
result := []string{}
|
||||
for _, v := range arg {
|
||||
switch val := v.(type) {
|
||||
case []interface{}:
|
||||
for _, v := range val {
|
||||
result = append(result, Format(v))
|
||||
}
|
||||
default:
|
||||
if b, e := json.MarshalIndent(val, "", " "); e == nil {
|
||||
result = append(result, string(b))
|
||||
}
|
||||
}
|
||||
}
|
||||
return strings.Join(result, "")
|
||||
return strings.Join(result, " ")
|
||||
}
|
||||
func Trans(arg ...interface{}) []string {
|
||||
ls := []string{}
|
||||
@ -150,7 +170,9 @@ func Trans(arg ...interface{}) []string {
|
||||
ls = append(ls, k, Format(v))
|
||||
}
|
||||
case []interface{}:
|
||||
ls = append(ls, Format(val...))
|
||||
for _, v := range val {
|
||||
ls = append(ls, Format(v))
|
||||
}
|
||||
default:
|
||||
ls = append(ls, Format(val))
|
||||
}
|
||||
@ -294,16 +316,17 @@ func Chain(root interface{}, args ...interface{}) interface{} {
|
||||
for j, key := range keys {
|
||||
index, e := strconv.Atoi(key)
|
||||
|
||||
// Log("error", "chain [%v %v] [%v %v] [%v/%v %v/%v] %v", parent_key, parent_index, key, index, i, len(args), j, len(keys), data)
|
||||
|
||||
var next interface{}
|
||||
switch value := data.(type) {
|
||||
case nil:
|
||||
if j == len(keys)-1 {
|
||||
next = args[i+1]
|
||||
}
|
||||
|
||||
if i == len(args)-1 {
|
||||
return nil
|
||||
}
|
||||
if j == len(keys)-1 {
|
||||
next = args[i+1]
|
||||
}
|
||||
|
||||
if e == nil {
|
||||
data, index = []interface{}{next}, 0
|
||||
@ -359,13 +382,13 @@ func Chain(root interface{}, args ...interface{}) interface{} {
|
||||
}
|
||||
|
||||
if index == -1 {
|
||||
data, index = append([]interface{}{next}, value...), 0
|
||||
value, index = append([]interface{}{next}, value...), 0
|
||||
} else if index == -2 {
|
||||
data, index = append(value, next), len(value)
|
||||
value, index = append(value, next), len(value)
|
||||
} else if j == len(keys)-1 {
|
||||
value[index] = next
|
||||
}
|
||||
next = value[index]
|
||||
data, next = value, value[index]
|
||||
}
|
||||
|
||||
switch p := parent.(type) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user