1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-25 16:58:06 +08:00

opt lex&yac

This commit is contained in:
shaoying 2019-01-07 09:30:29 +08:00
parent 4f1bc3e305
commit 55fefaf130
8 changed files with 422 additions and 344 deletions

View File

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

View File

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

View File

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

View File

@ -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), "")

View File

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

View File

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

View File

@ -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), "")

View File

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