This repository has been archived by the owner on Jul 17, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathastNode.go
82 lines (73 loc) · 1.84 KB
/
astNode.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
package c2
import (
"fmt"
"github.com/pkg/errors"
"github.com/tjbrockmeyer/c2/c2gram"
"strings"
)
type ASTNode struct {
symbol c2gram.Symbol
up *ASTNode
down []*ASTNode
production *c2gram.Production
token *Token
file string
row int
column int
// The constructed data for this symbol.
Data interface{}
}
func (n *ASTNode) Traverse() error {
hasActions := n.production != nil && n.production.Actions != nil
if n.down != nil {
for i, down := range n.down {
if hasActions {
if action, ok := n.production.Actions[i]; ok {
if err := action(n); err != nil {
return err
}
}
}
if err := down.Traverse(); err != nil {
return err
}
}
}
if hasActions {
if action, ok := n.production.Actions[len(n.production.RHS)]; ok {
if err := action(n); err != nil {
return err
}
}
}
return nil
}
func (n ASTNode) Symbol() c2gram.Symbol {
return n.symbol
}
// Go to the symbol above this one in the tree.
// This does not come without risks.
func (n ASTNode) Up() *ASTNode {
return n.up
}
// For a production, this will contain the symbols that make up the production rule.
func (n ASTNode) Down(i int) *ASTNode {
return n.down[i]
}
// Get the location of the symbol in code.
func (n ASTNode) Loc() (file string, row, column int) {
return n.file, n.row, n.column
}
func (n ASTNode) NewError(reason string) error {
return errors.Errorf("[Error] In %v: At %v:%v | %v", n.file, n.row, n.column, reason)
}
func (n ASTNode) ToString(symbols []c2gram.Symbol) string {
if n.token != nil {
return fmt.Sprint("TOKEN: ", n.symbol.Name(), "\tLEXEME: ", n.token.lexeme)
}
rhs := make([]string, 0, len(n.production.RHS))
for _, sym := range n.production.RHS {
rhs = append(rhs, symbols[sym].Name())
}
return fmt.Sprint("SYMBOL:\t", n.symbol.Name(), " ::= ", strings.Join(rhs, " "))
}