aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyo Nihei <nihei.dev@gmail.com>2021-08-05 19:29:33 +0900
committerRyo Nihei <nihei.dev@gmail.com>2021-08-05 19:29:33 +0900
commit2bf3786801cd6727e3f28d0a6aeb7ec375eb1aa7 (patch)
tree7178d034fad04dfd6668137c7797dd40ab3dc9fa
parentAdd --cst option to the parse command (diff)
downloadurubu-2bf3786801cd6727e3f28d0a6aeb7ec375eb1aa7.tar.gz
urubu-2bf3786801cd6727e3f28d0a6aeb7ec375eb1aa7.tar.xz
Avoid the growth of slices when constructing trees
-rw-r--r--driver/parser.go30
1 files changed, 25 insertions, 5 deletions
diff --git a/driver/parser.go b/driver/parser.go
index 3cc8a9a..cdcaf14 100644
--- a/driver/parser.go
+++ b/driver/parser.go
@@ -173,24 +173,44 @@ func (p *Parser) Parse() error {
var cst *Node
if p.makeAST {
act := p.gram.ASTAction.Entries[prodNum]
- children := []*Node{}
+ var children []*Node
if act != nil {
+ // Count the number of children in advance to avoid frequent growth in a slice for children.
+ {
+ l := 0
+ for _, e := range act {
+ if e > 0 {
+ l++
+ } else {
+ offset := e*-1 - 1
+ l += len(handle[offset].ast.Children)
+ }
+ }
+
+ children = make([]*Node, l)
+ }
+
+ p := 0
for _, e := range act {
if e > 0 {
offset := e - 1
- children = append(children, handle[offset].ast)
+ children[p] = handle[offset].ast
+ p++
} else {
offset := e*-1 - 1
for _, c := range handle[offset].ast.Children {
- children = append(children, c)
+ children[p] = c
+ p++
}
}
}
} else {
// If an alternative has no AST action, a driver generates
// a node with the same structure as a CST.
- for _, f := range handle {
- children = append(children, f.ast)
+
+ children = make([]*Node, len(handle))
+ for i, f := range handle {
+ children[i] = f.ast
}
}