@@ -6,14 +6,17 @@ import (
6
6
"fmt"
7
7
"os"
8
8
"path/filepath"
9
+ "strings"
9
10
)
10
11
11
12
func main () {
13
+ fmt .Println ("Ohm WebAssembly Matcher - Go Implementation" )
12
14
// Parse command line arguments
13
15
wasmFile := flag .String ("wasm" , "test/data/_add.wasm" , "Path to WebAssembly file" )
14
16
inputText := flag .String ("input" , "" , "Input text to match against the grammar" )
15
17
inputFile := flag .String ("file" , "" , "Path to file containing input text to match" )
16
18
startRule := flag .String ("rule" , "" , "Start rule for the grammar (defaults to grammar's start rule)" )
19
+ verbose := flag .Bool ("verbose" , false , "Display verbose information about CST nodes" )
17
20
flag .Parse ()
18
21
19
22
// Create a context
@@ -76,8 +79,81 @@ func main() {
76
79
fmt .Printf ("Error getting CST root: %v\n " , err )
77
80
} else {
78
81
fmt .Printf ("CST root node ID: %d\n " , cstRoot )
82
+
83
+ // Create a CST walker with the matcher
84
+ cstWalker := NewCstWalker (matcher )
85
+
86
+ // Read the CST node
87
+ node , err := cstWalker .GetRawCstNode (cstRoot )
88
+ if err != nil {
89
+ fmt .Printf ("Error reading CST node: %v\n " , err )
90
+ } else {
91
+ fmt .Printf ("CST Node - Count: %d, MatchLen: %d, Type: %d\n " ,
92
+ node .Count , node .MatchLen , node .Type )
93
+
94
+ if len (node .ChildRefs ) > 0 {
95
+ fmt .Printf ("Child references: %v\n " , node .ChildRefs )
96
+ }
97
+
98
+ // Unparse the CST to get the original text
99
+ fmt .Println ("\n Unparsing the CST to reconstruct the input:" )
100
+ unparsedText := unparse (cstWalker , cstRoot , matcher .GetInput ())
101
+ fmt .Printf ("Unparsed text: %q\n " , unparsedText )
102
+ fmt .Printf ("Original input: %q\n " , matcher .GetInput ())
103
+ fmt .Printf ("Match: %v\n " , unparsedText == matcher .GetInput ())
104
+ }
105
+
106
+ // Display more verbose information if requested
107
+ if * verbose {
108
+ fmt .Println ("\n CST node details have been displayed above." )
109
+ fmt .Println ("Node Types:" )
110
+ fmt .Printf (" - Terminal nodes (type %d): Leaf nodes that consume input\n " , NODE_TYPE_TERMINAL )
111
+ fmt .Printf (" - Iteration nodes (type %d): Used for repetition operations\n " , NODE_TYPE_ITER )
112
+ fmt .Printf (" - Non-terminal nodes (type %d): Internal nodes with children\n " , NODE_TYPE_NONTERMINAL )
113
+ fmt .Println ("\n The unparse function reconstructs the original input by collecting text from all terminal nodes in order." )
114
+ }
79
115
}
80
116
} else {
81
117
fmt .Println ("Match failed" )
82
118
}
83
119
}
120
+
121
+ // unparse walks the CST starting from the given node and reconstructs the original text
122
+ // It returns the reconstructed text from the terminal nodes
123
+ func unparse (walker * CstWalker , nodeAddr uint32 , input string ) string {
124
+ var result strings.Builder
125
+ pos := uint32 (0 )
126
+ unparseNode (walker , nodeAddr , & pos , input , & result )
127
+ return result .String ()
128
+ }
129
+
130
+ // unparseNode is a helper function that recursively processes nodes and builds the result
131
+ func unparseNode (walker * CstWalker , nodeAddr uint32 , pos * uint32 , input string , result * strings.Builder ) {
132
+ // Read the current node
133
+ node , err := walker .GetRawCstNode (nodeAddr )
134
+ if err != nil {
135
+ fmt .Printf ("Error reading CST node: %v\n " , err )
136
+ return
137
+ }
138
+
139
+ // Handle terminal nodes - append the consumed text to the result
140
+ if node .Type == NODE_TYPE_TERMINAL {
141
+ if * pos < uint32 (len (input )) && node .MatchLen > 0 {
142
+ end := * pos + node .MatchLen
143
+ if end > uint32 (len (input )) {
144
+ end = uint32 (len (input ))
145
+ }
146
+ matchedText := input [* pos :end ]
147
+ result .WriteString (matchedText )
148
+
149
+ // Update position only after processing terminal nodes
150
+ * pos += node .MatchLen
151
+ }
152
+ return
153
+ }
154
+
155
+ // For all other node types (nonterminal, iteration, etc.), process children recursively
156
+ for _ , childAddr := range node .ChildRefs {
157
+ unparseNode (walker , childAddr , pos , input , result )
158
+ }
159
+ }
0 commit comments