1
0
forked from x/ContextOS

mac pro lex&yac 整理了一下词法解析与语法解析代码

This commit is contained in:
shaoying 2018-02-03 09:32:47 +08:00
parent a2395ddb2c
commit 55548aee0f
3 changed files with 109 additions and 130 deletions

View File

@ -11,46 +11,38 @@ context: 通过提供自由的模块,简洁的接口,动态的结构,让
* 编程: 接口与框架
* 测试: 语句与表达式
## 接口设计CCC(command, config, cache)
* 服务管理server
* 模块管理context
* 消息管理message
* 命令管理command
* 配置管理config
* 缓存管理cache
## 接口设计
* 功能树: Caches Configs Commands
* 消息树: Request History Session
### Context
### Context功能树
* Cap() Conf() Cmd()
* Spawn() Begin() Start() Close()
### Message
* Request[] History[] Session[]
* detail[] option[] result[] append[]
### Conbine
* Context Master Owner
* Search() Choice() Assert() Figure()
### Message消息树
* Detail() Option() Result() Append()
* Req() His() Sess()
## 模块设计
* ctx cli aaa web
* nfs tcp mdb ssh
* lex yac log gdb
* 应用层 ctx cli aaa web
* 控制层 lex yac log gdb
* 数据层 tcp nfs ssh mdb
### Core
### 应用层
* ctx: 模块中心
* cli: 管理中心
* aaa: 认证中心
* web: 应用中心
### Base
* nfs: 存储中心
* tcp: 网络中心
* mdb: 数据中心
* ssh: 集群中心
### Draw
* lex: 词法解析
* yac: 语法解析
### 控制层
* lex: 词法中心
* yac: 语法中心
* log: 日志中心
* gdb: 调试中心
### 数据层
* tcp: 网络中心
* nfs: 存储中心
* ssh: 集群中心
* mdb: 数据中心

View File

@ -26,26 +26,24 @@ type LEX struct {
page map[string]int
hash map[string]int
char map[byte][]byte
state map[State]*State
mat []map[byte]*State
state map[State]*State
char map[byte][]byte
*ctx.Message
*ctx.Context
}
func (lex *LEX) index(hash string, h string) int {
if x, e := strconv.Atoi(h); e == nil {
return x
which := lex.page
if hash == "nhash" {
which = lex.hash
}
which := lex.page
switch hash {
case "npage":
which = lex.page
case "nhash":
which = lex.hash
if x, e := strconv.Atoi(h); e == nil {
lex.Assert(hash != "npage" || x < lex.Capi("npage"))
return x
}
if x, ok := which[h]; ok {
@ -53,6 +51,7 @@ func (lex *LEX) index(hash string, h string) int {
}
which[h] = lex.Capi(hash, 1)
lex.Assert(hash != "npage" || lex.Capi("npage") < lex.Capi("nlang"))
return which[h]
}
@ -65,10 +64,10 @@ func (lex *LEX) charset(c byte) []byte {
func (lex *LEX) train(page int, hash int, seed []byte) int {
ss := []int{page}
cn := make([]bool, lex.Capi("ncell"))
c := make([]byte, 0, lex.Capi("ncell"))
cc := make([]byte, 0, lex.Capi("ncell"))
sn := make([]bool, lex.Capi("nline"))
s := []int{page}
points := []*Point{}
@ -84,8 +83,8 @@ func (lex *LEX) train(page int, hash int, seed []byte) int {
for ; seed[p] != ']'; p++ {
if seed[p] == '\\' {
p++
for _, s := range lex.charset(seed[p]) {
cn[s] = true
for _, c := range lex.charset(seed[p]) {
cn[c] = true
}
continue
}
@ -95,8 +94,8 @@ func (lex *LEX) train(page int, hash int, seed []byte) int {
if begin > end {
begin, end = end, begin
}
for i := begin; i <= end; i++ {
cn[i] = true
for c := begin; c <= end; c++ {
cn[c] = true
}
p += 2
continue
@ -105,29 +104,29 @@ func (lex *LEX) train(page int, hash int, seed []byte) int {
cn[seed[p]] = true
}
for i := 0; i < len(cn); i++ {
if (set && cn[i]) || (!set && !cn[i]) {
c = append(c, byte(i))
for c := 0; c < len(cn); c++ {
if (set && cn[c]) || (!set && !cn[c]) {
cc = append(cc, byte(c))
}
cn[i] = false
cn[c] = false
}
case '.':
for i := 0; i < len(cn); i++ {
c = append(c, byte(i))
for c := 0; c < len(cn); c++ {
cc = append(cc, byte(c))
}
case '\\':
p++
for _, s := range lex.charset(seed[p]) {
c = append(c, s)
for _, c := range lex.charset(seed[p]) {
cc = append(cc, c)
}
default:
c = append(c, seed[p])
cc = append(cc, seed[p])
}
lex.Log("debug", nil, "page: \033[31m%d %v\033[0m", len(s), s)
lex.Log("debug", nil, "cell: \033[32m%d %v\033[0m", len(c), c)
lex.Log("debug", nil, "page: \033[31m%d %v\033[0m", len(ss), ss)
lex.Log("debug", nil, "cell: \033[32m%d %v\033[0m", len(cc), cc)
flag := '\000'
if p+1 < len(seed) {
@ -138,29 +137,30 @@ func (lex *LEX) train(page int, hash int, seed []byte) int {
}
}
for i := 0; i < len(s); i++ {
for line, j := 0, byte(0); int(j) < len(c); j++ {
for _, s := range ss {
line := 0
for _, c := range cc {
state := &State{}
if lex.mat[s[i]][c[j]] != nil {
*state = *lex.mat[s[i]][c[j]]
if lex.mat[s][c] != nil {
*state = *lex.mat[s][c]
} else {
lex.Capi("nnode", 1)
}
lex.Log("debug", nil, "GET(%d,%d): %v", s[i], c[j], state)
lex.Log("debug", nil, "GET(%d,%d): %v", s, c, state)
switch flag {
case '+':
state.star = true
case '*':
state.star = true
sn[s[i]] = true
sn[s] = true
case '?':
sn[s[i]] = true
sn[s] = true
}
if state.next == 0 {
if line == 0 || !lex.Caps("compact") {
if line == 0 || !lex.Confs("compact") {
lex.mat = append(lex.mat, make(map[byte]*State))
line = lex.Capi("nline", 1) - 1
sn = append(sn, false)
@ -169,54 +169,50 @@ func (lex *LEX) train(page int, hash int, seed []byte) int {
}
sn[state.next] = true
lex.mat[s[i]][c[j]] = state
points = append(points, &Point{s[i], c[j]})
lex.Log("debug", nil, "SET(%d,%d): %v(%s,%s)", s[i], c[j], state, lex.Cap("nnode"), lex.Cap("nreal"))
lex.mat[s][c] = state
points = append(points, &Point{s, c})
lex.Log("debug", nil, "SET(%d,%d): %v(%s,%s)", s, c, state, lex.Cap("nnode"), lex.Cap("nreal"))
}
}
c, s = c[:0], s[:0]
for i := 0; i < len(sn); i++ {
if sn[i] {
s = append(s, i)
cc, ss = cc[:0], ss[:0]
for s, b := range sn {
if sn[s] = false; b {
ss = append(ss, s)
}
sn[i] = false
}
}
for _, n := range s {
if n < lex.Capi("nlang") || n >= len(lex.mat) {
for _, s := range ss {
if s < lex.Capi("nlang") || s >= len(lex.mat) {
continue
}
if len(lex.mat[n]) == 0 {
lex.Log("debug", nil, "DEL: %d %d", lex.Capi("nline")-1, lex.Capi("nline", 0, n))
lex.mat = lex.mat[:n]
if len(lex.mat[s]) == 0 {
lex.Log("debug", nil, "DEL: %d-%d", lex.Capi("nline")-1, lex.Capi("nline", 0, s))
lex.mat = lex.mat[:s]
}
}
for _, n := range s {
for _, s := range ss {
for _, p := range points {
state := &State{}
*state = *lex.mat[p.s][p.c]
if state.next == n {
if state.next == s {
lex.Log("debug", nil, "GET(%d, %d): %v", p.s, p.c, state)
if state.next >= len(lex.mat) {
if state.hash = hash; state.next >= len(lex.mat) {
state.next = 0
}
if hash > 0 {
state.hash = hash
}
lex.mat[p.s][p.c] = state
lex.Log("debug", nil, "SET(%d, %d): %v", p.s, p.c, state)
}
if x, ok := lex.state[*state]; ok {
lex.mat[p.s][p.c] = x
} else {
lex.state[*state] = state
lex.mat[p.s][p.c] = state
if x, ok := lex.state[*state]; !ok {
lex.state[*state] = lex.mat[p.s][p.c]
lex.Capi("nreal", 1)
} else {
lex.mat[p.s][p.c] = x
}
}
}
@ -224,7 +220,7 @@ func (lex *LEX) train(page int, hash int, seed []byte) int {
return hash
}
func (lex *LEX) parse(page int, line []byte) (hash int, word []byte, rest []byte) {
func (lex *LEX) parse(page int, line []byte) (hash int, rest []byte, word []byte) {
pos := 0
for star, s := 0, page; s != 0 && pos < len(line); pos++ {
@ -237,23 +233,19 @@ func (lex *LEX) parse(page int, line []byte) (hash int, word []byte, rest []byte
state := lex.mat[s][c]
lex.Log("debug", nil, "(%d,%d): %v", s, c, state)
if state == nil && star != 0 {
s, star = star, 0
state = lex.mat[s][c]
lex.Log("debug", nil, "(%d,%d): %v", s, c, state)
}
if state == nil {
break
}
if state, ok := lex.mat[star][c]; !ok || state == nil || !state.star {
star = 0
}
if state.star {
star = s
s, star, pos = star, 0, pos-1
continue
}
word = append(word, c)
if state.star {
star = s
} else if _, ok := lex.mat[star][c]; !ok {
star = 0
}
if s, hash = state.next, state.hash; s == 0 {
s, star = star, 0
}
@ -278,11 +270,10 @@ func (lex *LEX) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
}
func (lex *LEX) Begin(m *ctx.Message, arg ...string) ctx.Server {
if lex.Context == Index {
if lex.Message = m; lex.Context == Index {
Pulse = m
}
lex.Context.Master(nil)
lex.Message = m
lex.Caches["ncell"] = &ctx.Cache{Name: "字符上限", Value: "128", Help: "字符上限"}
lex.Caches["nlang"] = &ctx.Cache{Name: "集合上限", Value: "32", Help: "集合上限"}
@ -295,7 +286,7 @@ func (lex *LEX) Begin(m *ctx.Message, arg ...string) ctx.Server {
lex.Caches["nnode"] = &ctx.Cache{Name: "节点数量", Value: "0", Help: "节点数量"}
lex.Caches["nreal"] = &ctx.Cache{Name: "实点数量", Value: "0", Help: "实点数量"}
lex.Caches["compact"] = &ctx.Cache{Name: "紧凑模式", Value: "true", Help: "实点数量"}
lex.Configs["compact"] = &ctx.Config{Name: "紧凑模式", Value: "true", Help: "实点数量"}
return lex
}

View File

@ -29,24 +29,24 @@ type YAC struct {
hash map[string]int
hand map[int]string
state map[State]*State
mat []map[byte]*State
state map[State]*State
*ctx.Message
*ctx.Context
}
func (yac *YAC) name(page int) string {
name, ok := yac.word[page]
if !ok {
name = fmt.Sprintf("yac%d", page)
if name, ok := yac.word[page]; ok {
return name
}
return name
return fmt.Sprintf("yac%d", page)
}
func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Point, []*Point) {
sn := make([]bool, yac.Capi("nline"))
ss := []int{page}
sn := make([]bool, yac.Capi("nline"))
points := []*Point{}
ends := []*Point{}
@ -91,18 +91,13 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po
fallthrough
default:
x, ok := yac.page[word[i]]
if !ok {
lex := yac.Sess("lex").Cmd("parse", word[i], yac.name(s))
if lex.Gets("result") {
x = lex.Geti("result")
} else {
x = len(yac.mat[s])
lex.Cmd("train", word[i], x, yac.name(s))
if x = yac.Sess("lex").Cmd("parse", word[i], yac.name(s)).Resulti(0); x == 0 {
x = yac.Sess("lex").Cmd("train", word[i], len(yac.mat[s]), yac.name(s)).Resulti(0)
}
}
c := byte(x)
state := &State{}
if yac.mat[s][c] != nil {
*state = *yac.mat[s][c]
@ -139,30 +134,31 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po
}
}
for _, n := range ss {
if n < yac.Capi("nlang") || n >= len(yac.mat) {
for _, s := range ss {
if s < yac.Capi("nlang") || s >= len(yac.mat) {
continue
}
void := true
for _, x := range yac.mat[n] {
for _, x := range yac.mat[s] {
if x != nil {
void = false
break
}
}
if void {
yac.Log("debug", nil, "DEL: %d %d", yac.Capi("nline")-1, yac.Capi("nline", 0, n))
yac.mat = yac.mat[:n]
yac.Log("debug", nil, "DEL: %d-%d", yac.Capi("nline")-1, yac.Capi("nline", 0, s))
yac.mat = yac.mat[:s]
}
}
for _, n := range ss {
for _, s := range ss {
for _, p := range points {
state := &State{}
*state = *yac.mat[p.s][p.c]
if state.next == n {
if state.next == s {
yac.Log("debug", nil, "GET(%d, %d): %v", p.s, p.c, state)
if state.next >= len(yac.mat) {
state.next = 0
@ -170,15 +166,15 @@ func (yac *YAC) train(m *ctx.Message, page, hash int, word []string) (int, []*Po
if hash > 0 {
state.hash = hash
}
yac.mat[p.s][p.c] = state
yac.Log("debug", nil, "SET(%d, %d): %v", p.s, p.c, state)
}
if x, ok := yac.state[*state]; ok {
yac.mat[p.s][p.c] = x
} else {
yac.state[*state] = state
yac.mat[p.s][p.c] = state
if x, ok := yac.state[*state]; !ok {
yac.state[*state] = yac.mat[p.s][p.c]
yac.Capi("nreal", 1)
} else {
yac.mat[p.s][p.c] = x
}
}
}