in src/ct/parser/cfg.go [57:185]
func (g *CFG) BuildTrees(items Items) Trees {
dim := items.Len()
if dim == 0 {
return nil
}
state := make([][]set.Set, dim)
for i := 0; i < dim; i++ {
state[i] = make([]set.Set, dim)
for j := 0; j < dim; j++ {
state[i][j] = set.New()
}
}
children := make([][]map[string]Element, dim)
for i := 0; i < dim; i++ {
children[i] = make([]map[string]Element, dim)
for j := 0; j < dim; j++ {
children[i][j] = map[string]Element{}
}
}
rules := g.rules
k := 0
for i := 0; i < dim; i++ {
term := items[i].typ
if rules.terminalRules[term].Empty() {
continue
}
for A := range rules.terminalRules[term] {
state[k][k].Add(A)
children[k][k][A] = NewUnary(items[i].val).Set(k, k, k)
}
added := true
for added {
added = false
for p, v := range rules.unaryRules {
if A := p.leftNonTerminal; state[k][k][A] {
for B := range v {
if !state[k][k][B] {
state[k][k].Add(B)
children[k][k][B] = p.Set(k, k, k)
added = true
}
}
}
}
}
k++
}
dim = k
for span := 2; span <= dim; span++ {
for begin := 0; begin <= dim-span; begin++ {
end := begin + span - 1
for split := begin; split < end; split++ {
for B := range state[begin][split] {
for C := range state[split+1][end] {
p := NewBinary(B, C)
for A := range rules.binaryRules[p] {
state[begin][end].Add(A)
children[begin][end][A] = p.Set(begin, split, end)
}
}
}
}
foundUnaryDerivation := true
for foundUnaryDerivation {
foundUnaryDerivation = false
for p, v := range rules.unaryRules {
if A := p.leftNonTerminal; state[begin][end][A] {
for B := range v {
if !state[begin][end][B] {
state[begin][end].Add(B)
children[begin][end][B] = p.Set(begin, end, end)
foundUnaryDerivation = true
}
}
}
}
}
}
}
// Build a parse tree stored in the children table:
var iter func(n *Node, p Element)
iter = func(n *Node, p Element) {
node := NewNode(p.leftNonTerminal)
n.left = node
next, ok := children[p.begin][p.split][p.leftNonTerminal]
if ok {
iter(node, next)
}
if p.IsUnary() {
return
}
node = NewNode(p.rightNonTerminal)
n.right = node
next, ok = children[p.split+1][p.end][p.rightNonTerminal]
if ok {
iter(node, next)
}
}
trees := NewTrees()
for k := 0; k < dim; k++ {
score := 1.0 - 0.5*float64(k)/float64(dim)
for i := 0; i <= k; i++ {
if next, ok := children[i][dim+i-k-1]["S"]; ok {
node := NewNode("S")
iter(node, next)
if node.Size() > 1 {
tree := NewTree(node, score)
trees = append(trees, tree)
}
}
}
if !trees.Empty() {
break
}
}
return trees
}