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
|
package grammar
import "fmt"
type slr1Automaton struct {
*lr0Automaton
}
func genSLR1Automaton(lr0 *lr0Automaton, prods *productionSet, follow *followSet) (*slr1Automaton, error) {
for _, state := range lr0.states {
for prodID := range state.reducible {
prod, ok := prods.findByID(prodID)
if !ok {
return nil, fmt.Errorf("reducible production not found: %v", prodID)
}
flw, err := follow.find(prod.lhs)
if err != nil {
return nil, err
}
var reducibleItem *lrItem
for _, item := range state.items {
if item.prod != prodID {
continue
}
reducibleItem = item
break
}
if reducibleItem == nil {
for _, item := range state.emptyProdItems {
if item.prod != prodID {
continue
}
reducibleItem = item
break
}
if reducibleItem == nil {
return nil, fmt.Errorf("reducible item not found; state: %v, production: %v", state.num, prodID)
}
}
if reducibleItem.lookAhead.symbols == nil {
reducibleItem.lookAhead.symbols = map[symbol]struct{}{}
}
for sym := range flw.symbols {
reducibleItem.lookAhead.symbols[sym] = struct{}{}
}
if flw.eof {
reducibleItem.lookAhead.symbols[symbolEOF] = struct{}{}
}
}
}
return &slr1Automaton{
lr0Automaton: lr0,
}, nil
}
|