-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompute_table.go
140 lines (124 loc) · 3.83 KB
/
compute_table.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package gocyk
import (
"sync"
"github.com/ghigt/gocyk/rtable"
)
// CompleteColumn fills the given column with the correct items depending
// on the string, the position and the grammar.
func (g *GoCYK) completeColumn(s string, c *rtable.Column, pos int) {
for i := pos; i >= 0; i-- {
if i == pos {
item := c.GetItem(i)
item = item.Create()
for _, t := range g.Grammar.GetTokensOfT(s) {
item = item.Add(t)
}
c.SetItem(item, i)
} else {
for l := i; l < pos; l++ {
item := c.GetItem(i)
item = item.Create()
for _, t := range g.Grammar.GetTokensOfNT(
g.Table.GetItem(l, i).GetTokens(),
g.Table.GetItem(pos, l+1).GetTokens()) {
item = item.Add(t)
}
c.SetItem(item, i)
}
}
}
}
// completeColumnFrom recompute the column from a given position of index.
func (g *GoCYK) completeColumnFrom(left <-chan struct{}, right chan<- struct{}, pos, col int) {
c := g.Table.GetColumn(col)
for i := pos; i >= 0; i-- {
if left != nil {
<-left
}
c.SetItem(&rtable.Item{}, i)
for l := i; l < col; l++ {
item := c.GetItem(i)
item = item.Create()
for _, t := range g.Grammar.GetTokensOfNT(
g.Table.GetItem(l, i).GetTokens(),
g.Table.GetItem(col, l+1).GetTokens()) {
item = item.Add(t)
}
c.SetItem(item, i)
}
right <- struct{}{}
}
}
// insertFollowing add a new item at the front of the right-hand of the
// position and recompute the items in the recognition table from
// the given position until the end of the table.
func (g *GoCYK) insertFollowing(pos int) {
var left chan struct{}
var wg sync.WaitGroup
for col := pos + 1; col < g.Table.Size(); col++ {
wg.Add(1)
right := make(chan struct{}, col+1)
go func(left chan struct{}, right chan struct{}, col int, pos int) {
defer wg.Done()
g.Table.GetColumn(col).AddFront(&rtable.Item{})
g.completeColumnFrom(left, right, pos, col)
}(left, right, col, pos)
left = right
}
wg.Wait()
}
// removeFollowing removes the first item of the right-hand of the
// position and computes the rest each item until the end and modify
// it appropriately. It also modifies only from a given position.
func (g *GoCYK) removeFollowing(pos int) {
var left chan struct{}
var wg sync.WaitGroup
for col := pos; col < g.Table.Size(); col++ {
wg.Add(1)
right := make(chan struct{}, col+1)
go func(left chan struct{}, right chan struct{}, col int, pos int) {
defer wg.Done()
g.Table.GetColumn(col).Remove(0)
g.completeColumnFrom(left, right, pos-1, col)
}(left, right, col, pos)
left = right
}
wg.Wait()
}
// completeColumnFrom recompute the column from a given position of index
// (without concurrency).
func (g *GoCYK) completeColumnFromWithoutC(pos, col int) {
c := g.Table.GetColumn(col)
for i := pos; i >= 0; i-- {
c.SetItem(&rtable.Item{}, i)
for l := i; l < col; l++ {
item := c.GetItem(i)
item = item.Create()
for _, t := range g.Grammar.GetTokensOfNT(
g.Table.GetItem(l, i).GetTokens(),
g.Table.GetItem(col, l+1).GetTokens()) {
item = item.Add(t)
}
c.SetItem(item, i)
}
}
}
// insertFollowingWithoutC add a new item at the front of the right-hand of the
// position and recompute the items in the recognition table from
// the given position until the end of the table (without concurrency).
func (g *GoCYK) insertFollowingWithoutC(pos int) {
for col := pos + 1; col < g.Table.Size(); col++ {
g.Table.GetColumn(col).AddFront(&rtable.Item{})
g.completeColumnFromWithoutC(pos, col)
}
}
// removeFollowing removes the first item of the right-hand of the
// position and computes the rest each item until the end and modify
// it appropriately. It also modifies only from a given position
// (without concurrency).
func (g *GoCYK) removeFollowingWithoutC(pos int) {
for col := pos; col < g.Table.Size(); col++ {
g.Table.GetColumn(col).Remove(0)
g.completeColumnFromWithoutC(pos-1, col)
}
}