mirror of
https://shylinux.com/x/icebergs
synced 2025-04-25 17:18:05 +08:00
opt yac
This commit is contained in:
parent
ddf87b921d
commit
bb7f1360e8
@ -9,6 +9,7 @@ import (
|
||||
_ "github.com/shylinux/icebergs/base/gdb"
|
||||
_ "github.com/shylinux/icebergs/base/lex"
|
||||
_ "github.com/shylinux/icebergs/base/log"
|
||||
|
||||
_ "github.com/shylinux/icebergs/base/yac"
|
||||
|
||||
_ "github.com/shylinux/icebergs/base/mdb"
|
||||
|
@ -22,11 +22,10 @@ const LEX = "lex"
|
||||
var Index = &ice.Context{Name: LEX, Help: "词法模块",
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
|
||||
// m.Load()
|
||||
// _lex_load(m)
|
||||
// _lex_load(m.Load())
|
||||
}},
|
||||
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
|
||||
// m.Save()
|
||||
m.Save()
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package lex
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -10,6 +12,35 @@ import (
|
||||
kit "github.com/shylinux/toolkits"
|
||||
)
|
||||
|
||||
type Stream struct {
|
||||
r io.Reader
|
||||
b []byte
|
||||
P int
|
||||
}
|
||||
|
||||
func NewStream(r io.Reader) *Stream {
|
||||
return &Stream{r: r}
|
||||
}
|
||||
func (s *Stream) Scan() bool {
|
||||
if s.P < len(s.b) {
|
||||
return true
|
||||
}
|
||||
buf := make([]byte, 1024)
|
||||
if n, e := s.r.Read(buf); e == nil && n > 0 {
|
||||
s.b = append(s.b, buf[:n]...)
|
||||
}
|
||||
return s.P < len(s.b)
|
||||
}
|
||||
func (s *Stream) Next() {
|
||||
s.P++
|
||||
}
|
||||
func (s *Stream) Char() byte {
|
||||
if s.Scan() {
|
||||
return s.b[s.P]
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Point struct {
|
||||
s int
|
||||
c byte
|
||||
@ -80,7 +111,7 @@ func (mat *Matrix) index(m *ice.Message, hash string, h string) int {
|
||||
return which[h]
|
||||
}
|
||||
func (mat *Matrix) Train(m *ice.Message, npage, nhash string, seed string) int {
|
||||
m.Debug("%s %s page: %v hash: %v seed: %v", TRAIN, LEX, npage, nhash, seed)
|
||||
// m.Debug("%s %s page: %v hash: %v seed: %v", TRAIN, LEX, npage, nhash, seed)
|
||||
|
||||
page := mat.index(m, NPAGE, npage)
|
||||
hash := mat.index(m, NHASH, nhash)
|
||||
@ -147,8 +178,8 @@ func (mat *Matrix) Train(m *ice.Message, npage, nhash string, seed string) int {
|
||||
cc = append(cc, seed[i]) // 普通字符
|
||||
}
|
||||
|
||||
m.Debug("page: \033[31m%d %v\033[0m", len(ss), ss)
|
||||
m.Debug("cell: \033[32m%d %v\033[0m", len(cc), cc)
|
||||
// m.Debug("page: \033[31m%d %v\033[0m", len(ss), ss)
|
||||
// m.Debug("cell: \033[32m%d %v\033[0m", len(cc), cc)
|
||||
|
||||
flag := '\000'
|
||||
if i+1 < len(seed) { // 次数
|
||||
@ -163,7 +194,7 @@ func (mat *Matrix) Train(m *ice.Message, npage, nhash string, seed string) int {
|
||||
if state == nil {
|
||||
state = &State{}
|
||||
}
|
||||
m.Debug("GET(%d,%d): %#v", s, c, state)
|
||||
// m.Debug("GET(%d,%d): %#v", s, c, state)
|
||||
|
||||
if cb(state); state.next == 0 {
|
||||
sn = append(sn, true)
|
||||
@ -175,7 +206,7 @@ func (mat *Matrix) Train(m *ice.Message, npage, nhash string, seed string) int {
|
||||
|
||||
mat.mat[s][c] = state
|
||||
points = append(points, &Point{s, c})
|
||||
m.Debug("SET(%d,%d): %#v", s, c, state)
|
||||
// m.Debug("SET(%d,%d): %#v", s, c, state)
|
||||
}
|
||||
|
||||
for _, s := range ss {
|
||||
@ -231,31 +262,33 @@ func (mat *Matrix) Train(m *ice.Message, npage, nhash string, seed string) int {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.Debug("DEL: %v", trans)
|
||||
// m.Debug("DEL: %v", trans)
|
||||
|
||||
for _, p := range points { // 去尾
|
||||
p.s = trans[p.s]
|
||||
state := mat.mat[p.s][p.c]
|
||||
if state.next = trans[state.next]; state.next == 0 {
|
||||
m.Debug("GET(%d, %d): %#v", p.s, p.c, state)
|
||||
// m.Debug("GET(%d, %d): %#v", p.s, p.c, state)
|
||||
state.hash = hash
|
||||
m.Debug("SET(%d, %d): %#v", p.s, p.c, state)
|
||||
// m.Debug("SET(%d, %d): %#v", p.s, p.c, state)
|
||||
}
|
||||
}
|
||||
|
||||
m.Debug("%s %s npage: %v nhash: %v", "train", "lex", len(mat.page), len(mat.hash))
|
||||
// m.Debug("%s %s npage: %v nhash: %v", TRAIN, LEX, len(mat.page), len(mat.hash))
|
||||
return hash
|
||||
}
|
||||
func (mat *Matrix) Parse(m *ice.Message, npage string, line []byte) (hash int, word []byte, rest []byte) {
|
||||
// m.Debug("%s %s page: %v line: %v", "parse", "lex", npage, line)
|
||||
func (mat *Matrix) Parse(m *ice.Message, npage string, stream *Stream) (hash int, word []byte) {
|
||||
// m.Debug("%s %s page: %v pos: %v", LEX, PARSE, npage, stream.P)
|
||||
page := mat.index(m, NPAGE, npage)
|
||||
|
||||
pos := 0
|
||||
for star, s := 0, page; s != 0 && pos < len(line); pos++ {
|
||||
c := line[pos]
|
||||
if c == '\\' && pos < len(line)-1 { //跳过转义
|
||||
pos++
|
||||
c = mat.char(line[pos])[0]
|
||||
pos := stream.P
|
||||
for star, s := 0, page; stream.Scan() && s != 0; stream.Next() {
|
||||
c := stream.Char()
|
||||
if c == '\\' { //跳过转义
|
||||
if stream.Next(); !stream.Scan() {
|
||||
break
|
||||
}
|
||||
c = mat.char(stream.Char())[0]
|
||||
}
|
||||
if c > 127 { //跳过中文
|
||||
word = append(word, c)
|
||||
@ -264,7 +297,7 @@ func (mat *Matrix) Parse(m *ice.Message, npage string, line []byte) (hash int, w
|
||||
|
||||
state := mat.mat[s][c]
|
||||
if state == nil {
|
||||
s, star, pos = star, 0, pos-1
|
||||
s, star, stream.P = star, 0, stream.P-1
|
||||
continue
|
||||
}
|
||||
// m.Debug("GET (%d,%d): %v", s, c, state)
|
||||
@ -281,11 +314,10 @@ func (mat *Matrix) Parse(m *ice.Message, npage string, line []byte) (hash int, w
|
||||
}
|
||||
|
||||
if hash == 0 {
|
||||
pos, word = 0, word[:0]
|
||||
stream.P, word = pos, word[:0]
|
||||
}
|
||||
rest = line[pos:]
|
||||
|
||||
// m.Debug("%s %s hash: %v word: %v rest: %v", "parse", "lex", hash, word, rest)
|
||||
// m.Debug("%s %s hash: %v word: %v", LEX, PARSE, mat.word[hash], string(word))
|
||||
return
|
||||
}
|
||||
func (mat *Matrix) show(m *ice.Message) {
|
||||
@ -379,10 +411,11 @@ func init() {
|
||||
value = kit.GetMeta(value)
|
||||
mat, _ := value[MATRIX].(*Matrix)
|
||||
|
||||
hash, word, rest := mat.Parse(m, m.Option(NPAGE), []byte(m.Option(kit.MDB_TEXT)))
|
||||
stream := NewStream(bytes.NewBufferString(m.Option(kit.MDB_TEXT)))
|
||||
hash, word := mat.Parse(m, m.Option(NPAGE), stream)
|
||||
m.Push(NHASH, kit.Select(kit.Format("%d", hash), mat.word[hash]))
|
||||
m.Push("word", string(word))
|
||||
m.Push("rest", string(rest))
|
||||
m.Push("rest", string(stream.b[stream.P:]))
|
||||
})
|
||||
m.ProcessInner()
|
||||
}},
|
||||
@ -417,11 +450,10 @@ func init() {
|
||||
return
|
||||
}
|
||||
|
||||
hash, word, rest := mat.Parse(m, arg[1], []byte(arg[2]))
|
||||
hash, word := mat.Parse(m, arg[1], NewStream(bytes.NewBufferString(arg[2])))
|
||||
m.Push(kit.MDB_TIME, m.Time())
|
||||
m.Push(kit.MDB_HASH, mat.word[hash])
|
||||
m.Push("word", string(word))
|
||||
m.Push("rest", string(rest))
|
||||
})
|
||||
}},
|
||||
},
|
||||
|
@ -1,6 +1,7 @@
|
||||
package yac
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -137,7 +138,7 @@ func (mat *Matrix) train(m *ice.Message, page, hash int, word []string, level in
|
||||
default:
|
||||
c, ok := mat.page[word[i]]
|
||||
if !ok {
|
||||
if c, _, _ = mat.lex.Parse(m, mat.name(mat.hand, s), []byte(word[i])); c == 0 {
|
||||
if c, _ = mat.lex.Parse(m, mat.name(mat.hand, s), lex.NewStream(bytes.NewBufferString(word[i]))); c == 0 {
|
||||
// c = mat.lex.Train(m, mat.name(s), fmt.Sprintf("%d", len(mat.mat[s])+1), []byte(word[i]))
|
||||
c = kit.Int(m.Cmdx("lex.matrix", mdb.INSERT, mat.lex_key, mat.name(mat.hand, s), len(mat.mat[s]), word[i]))
|
||||
mat.mat[s] = append(mat.mat[s], nil)
|
||||
@ -211,16 +212,17 @@ func (mat *Matrix) train(m *ice.Message, page, hash int, word []string, level in
|
||||
return len(word), points, ends
|
||||
}
|
||||
|
||||
func (mat *Matrix) Parse(m *ice.Message, rewrite Rewrite, page int, line []byte, level int) (hash int, word []string, rest []byte) {
|
||||
m.Debug("%s %s\\%d %s(%d): %s", PARSE, strings.Repeat("#", level), level, mat.name(mat.hand, page), page, string(line))
|
||||
func (mat *Matrix) Parse(m *ice.Message, rewrite Rewrite, page int, stream *lex.Stream, level int) (hash int, word []string) {
|
||||
// m.Debug("%s %s\\%d %s(%d)", PARSE, strings.Repeat("#", level), level, mat.name(mat.hand, page), page)
|
||||
|
||||
rest = line
|
||||
h, w, r := 0, []byte{}, []byte{}
|
||||
for p, i := 0, page; i > 0 && len(rest) > 0; {
|
||||
begin := stream.P
|
||||
h, w := 0, []byte{}
|
||||
for p, i := 0, page; stream.Scan() && i > 0; {
|
||||
// 解析空白
|
||||
h, w, r = mat.lex.Parse(m, "space", rest)
|
||||
h, w = mat.lex.Parse(m, "space", stream)
|
||||
// 解析单词
|
||||
h, w, r = mat.lex.Parse(m, mat.name(mat.hand, i), r)
|
||||
begin := stream.P
|
||||
h, w = mat.lex.Parse(m, mat.name(mat.hand, i), stream)
|
||||
// 解析状态
|
||||
var s *State
|
||||
if h < len(mat.mat[i]) {
|
||||
@ -228,8 +230,11 @@ func (mat *Matrix) Parse(m *ice.Message, rewrite Rewrite, page int, line []byte,
|
||||
}
|
||||
|
||||
if s != nil { // 全局语法检查
|
||||
if hh, ww, _ := mat.lex.Parse(m, "key", rest); hh == 0 || len(ww) <= len(w) {
|
||||
word, rest = append(word, string(w)), r
|
||||
hold := stream.P
|
||||
stream.P = begin
|
||||
if hh, ww := mat.lex.Parse(m, "key", stream); hh == 0 || len(ww) <= len(w) {
|
||||
stream.P = hold
|
||||
word = append(word, string(w))
|
||||
} else {
|
||||
s = nil
|
||||
}
|
||||
@ -238,14 +243,14 @@ func (mat *Matrix) Parse(m *ice.Message, rewrite Rewrite, page int, line []byte,
|
||||
if s == nil { // 嵌套语法递归解析
|
||||
for j := 1; j < len(mat.mat[i]); j++ {
|
||||
if n := mat.mat[i][j]; j < mat.nlang && n != nil {
|
||||
if _, w, r := mat.Parse(m, rewrite, j, rest, level+1); len(r) != len(rest) {
|
||||
s, word, rest = n, append(word, w...), r
|
||||
if h, w := mat.Parse(m, rewrite, j, stream, level+1); h != 0 {
|
||||
s, word = n, append(word, w...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m.Debug("%s %s|%d GET \033[33m%s\033[0m %#v", PARSE, strings.Repeat("#", level), level, w, s)
|
||||
// m.Debug("%s %s|%d GET \033[33m%s\033[0m %#v", PARSE, strings.Repeat("#", level), level, w, s)
|
||||
}
|
||||
|
||||
//语法切换
|
||||
@ -257,13 +262,13 @@ func (mat *Matrix) Parse(m *ice.Message, rewrite Rewrite, page int, line []byte,
|
||||
}
|
||||
|
||||
if hash == 0 {
|
||||
word, rest = word[:0], line
|
||||
word, stream.P = word[:0], begin
|
||||
} else {
|
||||
hash, word, rest = rewrite(m, mat.word[hash], hash, word, rest)
|
||||
hash, word = rewrite(m, mat.word[hash], hash, word, begin, stream)
|
||||
}
|
||||
|
||||
m.Debug("%s %s/%d %s(%d): %v %v", PARSE, strings.Repeat("#", level), level, mat.hand[hash], hash, word, rest)
|
||||
return hash, word, rest
|
||||
// m.Debug("%s %s/%d %s(%d): %v %v", PARSE, strings.Repeat("#", level), level, mat.hand[hash], hash, word, stream.P)
|
||||
return hash, word
|
||||
}
|
||||
func (mat *Matrix) show(m *ice.Message) {
|
||||
showCol := map[int]bool{} // 有效列
|
||||
@ -304,7 +309,7 @@ func (mat *Matrix) show(m *ice.Message) {
|
||||
m.Status(NLANG, mat.nlang, NCELL, mat.ncell, NPAGE, len(mat.page), NHASH, len(mat.hash))
|
||||
}
|
||||
|
||||
type Rewrite func(m *ice.Message, nhash string, hash int, word []string, rest []byte) (int, []string, []byte)
|
||||
type Rewrite func(m *ice.Message, nhash string, hash int, word []string, begin int, stream *lex.Stream) (int, []string)
|
||||
|
||||
const (
|
||||
NLANG = "nlang"
|
||||
@ -351,6 +356,7 @@ func init() {
|
||||
mat.mat[page] = make([]*State, mat.ncell)
|
||||
}
|
||||
|
||||
m.Option(kit.MDB_TEXT, strings.ReplaceAll(m.Option(kit.MDB_TEXT), "\\", "\\\\"))
|
||||
text := kit.Split(m.Option(kit.MDB_TEXT), " ", " ", " ")
|
||||
mat.train(m, page, hash, text, 1)
|
||||
m.Grow(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), kit.Dict(
|
||||
@ -369,15 +375,16 @@ func init() {
|
||||
value = kit.GetMeta(value)
|
||||
mat, _ := value[MATRIX].(*Matrix)
|
||||
|
||||
for text := []byte(m.Option(kit.MDB_TEXT)); len(text) > 0; {
|
||||
hash, _, rest := mat.Parse(m, func(m *ice.Message, nhash string, hash int, word []string, rest []byte) (int, []string, []byte) {
|
||||
for stream := lex.NewStream(bytes.NewBufferString(m.Option(kit.MDB_TEXT))); stream.Scan(); {
|
||||
hash, _ := mat.Parse(m, func(m *ice.Message, nhash string, hash int, word []string, begin int, stream *lex.Stream) (int, []string) {
|
||||
switch cb := m.Optionv(kit.Keycb(MATRIX)).(type) {
|
||||
case func(string, int, []string, []byte) (int, []string, []byte):
|
||||
return cb(nhash, hash, word, rest)
|
||||
case func(string, int, []string, int, *lex.Stream) (int, []string):
|
||||
return cb(nhash, hash, word, begin, stream)
|
||||
}
|
||||
return hash, word, rest
|
||||
}, mat.index(m, NPAGE, m.Option(NPAGE)), text, 1)
|
||||
if text = rest; hash == 0 {
|
||||
return hash, word
|
||||
}, mat.index(m, NPAGE, m.Option(NPAGE)), stream, 1)
|
||||
|
||||
if hash == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -392,6 +399,7 @@ func init() {
|
||||
m.ProcessInner()
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
|
||||
m.Option(mdb.CACHE_LIMIT, -1)
|
||||
if m.Action(mdb.CREATE); len(arg) == 0 { // 矩阵列表
|
||||
m.Fields(len(arg) == 0, "time,name,npage,nhash")
|
||||
m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), "", mdb.HASH)
|
||||
@ -406,24 +414,10 @@ func init() {
|
||||
return
|
||||
}
|
||||
|
||||
// 词法矩阵
|
||||
m.Richs(m.Prefix(MATRIX), "", arg[0], func(key string, value map[string]interface{}) {
|
||||
value = kit.GetMeta(value)
|
||||
mat, _ := value[MATRIX].(*Matrix)
|
||||
|
||||
if len(arg) == 2 { // 词法矩阵
|
||||
mat.show(m)
|
||||
return
|
||||
}
|
||||
|
||||
hash, word, rest := mat.Parse(m, func(m *ice.Message, nhash string, hash int, word []string, rest []byte) (int, []string, []byte) {
|
||||
m.Debug("\033[32mrun --- %v %v %v\033[0m", nhash, word, rest)
|
||||
return hash, word, rest
|
||||
}, mat.index(m, NPAGE, arg[1]), []byte(arg[2]), 1)
|
||||
|
||||
m.Push(kit.MDB_TIME, m.Time())
|
||||
m.Push(kit.MDB_HASH, mat.word[hash])
|
||||
m.Push("word", kit.Format(word))
|
||||
m.Push("rest", string(rest))
|
||||
value[MATRIX].(*Matrix).show(m)
|
||||
})
|
||||
}},
|
||||
},
|
||||
|
@ -1,21 +1,23 @@
|
||||
package yac
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/cli"
|
||||
"github.com/shylinux/icebergs/base/lex"
|
||||
"github.com/shylinux/icebergs/base/mdb"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
)
|
||||
|
||||
type frame struct {
|
||||
pos int
|
||||
key string
|
||||
skip bool
|
||||
data map[string]string
|
||||
}
|
||||
|
||||
type stack struct {
|
||||
fs []*frame
|
||||
res []string
|
||||
@ -26,6 +28,20 @@ func (s *stack) push(f *frame) *stack {
|
||||
s.fs = append(s.fs, f)
|
||||
return s
|
||||
}
|
||||
func (s *stack) pop() *frame {
|
||||
last := s.fs[len(s.fs)-1]
|
||||
s.fs = s.fs[:len(s.fs)-1]
|
||||
return last
|
||||
}
|
||||
func (s *stack) can_run(nhash string) bool {
|
||||
switch nhash {
|
||||
case "if", "for", "end":
|
||||
return true
|
||||
}
|
||||
|
||||
return !s.fs[len(s.fs)-1].skip
|
||||
}
|
||||
|
||||
func (s *stack) define(key, value string) {
|
||||
if len(s.fs) > 0 {
|
||||
s.fs[len(s.fs)-1].data[key] = value
|
||||
@ -39,31 +55,41 @@ func (s *stack) value(key string) string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
func (s *stack) let(key, value string) string {
|
||||
for i := len(s.fs) - 1; i >= 0; i-- {
|
||||
if val, ok := s.fs[i].data[key]; ok {
|
||||
s.fs[i].data[key] = value
|
||||
return val
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
func (s *stack) echo(arg ...interface{}) {
|
||||
s.res = append(s.res, kit.Simple(arg...)...)
|
||||
}
|
||||
|
||||
func _script_push_stack(m *ice.Message, f *frame) {
|
||||
stack := m.Optionv("stack").(*stack)
|
||||
stack.push(f)
|
||||
func _get_stack(m *ice.Message) *stack {
|
||||
return m.Optionv("stack").(*stack)
|
||||
}
|
||||
func _script_define(m *ice.Message, key, value string) {
|
||||
stack := m.Optionv("stack").(*stack)
|
||||
stack.define(key, value)
|
||||
func _push_stack(m *ice.Message, f *frame) {
|
||||
f.pos = kit.Int(m.Option("begin"))
|
||||
_get_stack(m).push(f)
|
||||
}
|
||||
func _script_runing(m *ice.Message, nhash string) bool {
|
||||
switch nhash {
|
||||
case "if", "for", "end":
|
||||
func _pop_stack(m *ice.Message) *frame {
|
||||
return _get_stack(m).pop()
|
||||
}
|
||||
|
||||
func _exp_true(m *ice.Message, arg string) bool {
|
||||
if arg == "true" {
|
||||
return true
|
||||
}
|
||||
|
||||
stack := m.Optionv("stack").(*stack)
|
||||
return !stack.fs[len(stack.fs)-1].skip
|
||||
}
|
||||
func _script_pop_stack(m *ice.Message) {
|
||||
stack := m.Optionv("stack").(*stack)
|
||||
stack.fs = stack.fs[:len(stack.fs)-1]
|
||||
}
|
||||
func _script_res(m *ice.Message, arg ...interface{}) {
|
||||
stack := m.Optionv("stack").(*stack)
|
||||
stack.res = append(stack.res, kit.Simple(arg...)...)
|
||||
if arg == "false" {
|
||||
return false
|
||||
}
|
||||
if n1, e1 := strconv.ParseInt(arg, 10, 64); e1 == nil {
|
||||
return n1 != 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const SCRIPT = "script"
|
||||
@ -71,24 +97,21 @@ const SCRIPT = "script"
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
|
||||
SCRIPT: {Name: "script name npage text:textarea auto create", Help: "脚本解析", Action: map[string]*ice.Action{
|
||||
mdb.CREATE: {Name: "create name=shy", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
|
||||
mdb.CREATE: {Name: "create name=shy text=etc/yac.txt", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(MATRIX, mdb.CREATE, m.Option(kit.MDB_NAME))
|
||||
for _, p := range [][]string{
|
||||
[]string{"num", "num", "[0-9]+"},
|
||||
[]string{"key", "key", "[abc]+"},
|
||||
[]string{"op2", "op2", "[+\\\\-*/%]"},
|
||||
[]string{"op2", "op2", "[>=<]"},
|
||||
[]string{"val", "val", "mul{ num key }"},
|
||||
[]string{"exp", "exp", "val"},
|
||||
[]string{"exp", "exp", "val op2 val"},
|
||||
[]string{"stm", "var", "var key = exp"},
|
||||
[]string{"stm", "for", "for exp"},
|
||||
[]string{"stm", "if", "if exp"},
|
||||
[]string{"stm", "cmd", "pwd"},
|
||||
[]string{"stm", "end", "end"},
|
||||
[]string{"script", "script", "rep{ stm }"},
|
||||
} {
|
||||
m.Cmdx(MATRIX, mdb.INSERT, m.Option(kit.MDB_NAME), p)
|
||||
if buf, err := ioutil.ReadFile(m.Option(kit.MDB_TEXT)); err == nil {
|
||||
m.Option(kit.MDB_TEXT, string(buf))
|
||||
}
|
||||
|
||||
m.Option(kit.MDB_TEXT, strings.ReplaceAll(m.Option(kit.MDB_TEXT), "\\", "\\\\"))
|
||||
for _, line := range kit.Split(m.Option(kit.MDB_TEXT), "\n", "\n", "\n") {
|
||||
if strings.HasPrefix(strings.TrimSpace(line), "#") {
|
||||
continue
|
||||
}
|
||||
line = strings.ReplaceAll(line, "\\", "\\\\")
|
||||
if list := kit.Split(line, " ", " ", " "); len(list) > 2 {
|
||||
m.Cmdx(MATRIX, mdb.INSERT, m.Option(kit.MDB_NAME), list[0], list[1], strings.Join(list[2:], " "))
|
||||
}
|
||||
}
|
||||
}},
|
||||
"exp": {Name: "exp num op2 num", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
|
||||
@ -101,10 +124,8 @@ func init() {
|
||||
}
|
||||
arg[2] = kit.Select(arg[2], stack.value(arg[2]))
|
||||
|
||||
m.Debug(" %v %v %v", arg[0], arg[1], arg[2])
|
||||
n1, e1 := strconv.ParseInt(arg[0], 10, 64)
|
||||
n2, e2 := strconv.ParseInt(arg[2], 10, 64)
|
||||
m.Debug(" %v %v %v", n1, arg[1], n2)
|
||||
switch arg[1] {
|
||||
case ">":
|
||||
if e1 == nil && e2 == nil {
|
||||
@ -112,6 +133,12 @@ func init() {
|
||||
} else {
|
||||
m.Echo("%t", arg[0] > arg[2])
|
||||
}
|
||||
case "<":
|
||||
if e1 == nil && e2 == nil {
|
||||
m.Echo("%t", n1 < n2)
|
||||
} else {
|
||||
m.Echo("%t", arg[0] < arg[2])
|
||||
}
|
||||
case "+":
|
||||
if e1 == nil && e2 == nil {
|
||||
m.Echo("%d", n1+n2)
|
||||
@ -146,33 +173,27 @@ func init() {
|
||||
m.Echo(arg[0], arg[1], arg[2])
|
||||
}
|
||||
}},
|
||||
"if": {Name: "if exp", Help: "判断", Hand: func(m *ice.Message, arg ...string) {
|
||||
if arg[1] == "true" {
|
||||
_script_push_stack(m, &frame{key: arg[0], skip: false})
|
||||
return
|
||||
}
|
||||
if arg[1] == "false" {
|
||||
_script_push_stack(m, &frame{key: arg[0], skip: true})
|
||||
return
|
||||
}
|
||||
if n1, e1 := strconv.ParseInt(arg[1], 10, 64); e1 == nil {
|
||||
_script_push_stack(m, &frame{key: arg[0], skip: n1 == 0})
|
||||
m.Echo("%t", n1 != 0)
|
||||
} else {
|
||||
_script_push_stack(m, &frame{skip: len(arg[1]) == 0})
|
||||
m.Echo("%t", len(arg[1]) > 0)
|
||||
}
|
||||
}},
|
||||
"var": {Name: "var key = exp", Help: "变量", Hand: func(m *ice.Message, arg ...string) {
|
||||
_script_define(m, arg[1], arg[3])
|
||||
_get_stack(m).define(arg[1], arg[3])
|
||||
}},
|
||||
"for": {Name: "for exp", Help: "循环", Hand: func(m *ice.Message, arg ...string) {
|
||||
"let": {Name: "let key = exp", Help: "变量", Hand: func(m *ice.Message, arg ...string) {
|
||||
_get_stack(m).let(arg[1], arg[3])
|
||||
}},
|
||||
"cmd": {Name: "cmd", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
|
||||
_script_res(m, m.Cmdx(cli.SYSTEM, arg))
|
||||
_get_stack(m).echo(m.Cmdx(cli.SYSTEM, arg))
|
||||
}},
|
||||
"if": {Name: "if exp", Help: "判断", Hand: func(m *ice.Message, arg ...string) {
|
||||
_push_stack(m, &frame{key: arg[0], skip: !_exp_true(m, arg[1])})
|
||||
}},
|
||||
"for": {Name: "for exp", Help: "循环", Hand: func(m *ice.Message, arg ...string) {
|
||||
_push_stack(m, &frame{key: arg[0], skip: !_exp_true(m, arg[1])})
|
||||
}},
|
||||
"end": {Name: "end", Help: "结束", Hand: func(m *ice.Message, arg ...string) {
|
||||
_script_pop_stack(m)
|
||||
frame := _pop_stack(m)
|
||||
if frame.key == "for" && !frame.skip {
|
||||
stream := m.Optionv("stream").(*lex.Stream)
|
||||
stream.P = frame.pos
|
||||
}
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) < 2 {
|
||||
@ -183,13 +204,13 @@ func init() {
|
||||
stack := &stack{}
|
||||
stack.push(&frame{})
|
||||
m.Option("stack", stack)
|
||||
m.Cmdy(MATRIX, PARSE, arg[0], arg[1], arg[2], func(nhash string, hash int, word []string, rest []byte) (int, []string, []byte) {
|
||||
m.Debug("script %v %v", nhash, word)
|
||||
if _, ok := c.Commands[SCRIPT].Action[nhash]; ok && _script_runing(m, nhash) {
|
||||
msg := m.Cmd(SCRIPT, nhash, word)
|
||||
return hash, msg.Resultv(), rest
|
||||
m.Cmdy(MATRIX, PARSE, arg[0], arg[1], arg[2], func(nhash string, hash int, word []string, begin int, stream *lex.Stream) (int, []string) {
|
||||
m.Option("stream", stream)
|
||||
if _, ok := c.Commands[SCRIPT].Action[nhash]; ok && stack.can_run(nhash) {
|
||||
msg := m.Cmd(SCRIPT, nhash, word, ice.Option{"begin", begin})
|
||||
return hash, msg.Resultv()
|
||||
}
|
||||
return hash, word, rest
|
||||
return hash, word
|
||||
})
|
||||
m.Resultv(stack.res)
|
||||
}},
|
||||
|
Loading…
x
Reference in New Issue
Block a user