|
1 | 1 | // Generated from trgen <version> |
2 | 2 |
|
3 | 3 | import { ATNSimulator } from 'antlr4ng'; |
| 4 | +import { BaseErrorListener } from 'antlr4ng'; |
4 | 5 | import { CharStream } from 'antlr4ng'; |
5 | 6 | import { CommonTokenStream } from 'antlr4ng'; |
6 | 7 | import { ConsoleErrorListener } from 'antlr4ng'; |
7 | | -import { BaseErrorListener } from 'antlr4ng'; |
| 8 | +import { ErrorNode } from 'antlr4ng'; |
8 | 9 | //import { InputStream } from 'antlr4ng'; |
| 10 | +import { Parser } from 'antlr4ng'; |
| 11 | +import { ParserRuleContext } from 'antlr4ng'; |
| 12 | +import { ParseTree } from 'antlr4ng'; |
9 | 13 | import { Recognizer } from 'antlr4ng'; |
10 | 14 | import { RecognitionException } from 'antlr4ng'; |
| 15 | +import { TerminalNode } from 'antlr4ng'; |
11 | 16 | import { Token } from 'antlr4ng'; |
| 17 | +import { Trees } from 'antlr4ng'; |
| 18 | +import { escapeWhitespace } from 'antlr4ng'; |
12 | 19 | import { readFileSync } from 'fs'; |
13 | 20 | import { writeFileSync } from 'fs'; |
14 | 21 | import { openSync } from 'fs'; |
15 | 22 | import { readSync } from 'fs'; |
16 | 23 | import { writeSync } from 'fs'; |
17 | 24 | import { closeSync } from 'fs'; |
18 | 25 | import { readFile } from 'fs/promises' |
| 26 | +import { isToken } from 'antlr4ng'; |
19 | 27 |
|
20 | 28 | <tool_grammar_tuples: {x | import { <x.GrammarAutomName> \} from './<x.GrammarAutomName>.js'; |
21 | 29 | } > |
@@ -221,5 +229,55 @@ function DoParse(str: CharStream, input_name: string, row_number: number) { |
221 | 229 | } |
222 | 230 | } |
223 | 231 |
|
| 232 | +function toStringTree(tree: ParseTree, recog?: Parser | null): string { |
| 233 | + var sb = new StringBuilder(); |
| 234 | + let ruleNames = recog.ruleNames; |
| 235 | + toStringTree2(sb, tree, 0, ruleNames); |
| 236 | + return sb.toString(); |
| 237 | +} |
| 238 | + |
| 239 | +function toStringTree2(sb: StringBuilder, tree: ParseTree, indent: number, ruleNames: string[] | null): void { |
| 240 | + let s = getNodeText(tree, ruleNames); |
| 241 | + s = escapeWhitespace(s!, false); |
| 242 | + const c = tree.getChildCount(); |
| 243 | + if (c === 0) { |
| 244 | + for (let i = 0; i \< indent; ++i) sb.Append(" "); |
| 245 | + sb.Append(s); sb.AppendLine(""); |
| 246 | + return; |
| 247 | + } |
| 248 | + for (let i = 0; i \< indent; ++i) sb.Append(" "); |
| 249 | + sb.Append(s); sb.AppendLine(""); |
| 250 | + for (let i = 0; i \< c; i++) { |
| 251 | + toStringTree2(sb, tree.getChild(i)!, indent+1, ruleNames); |
| 252 | + } |
| 253 | +} |
| 254 | + |
| 255 | +function getNodeText(t: ParseTree, ruleNames: string[] | null, recog?: Parser | null): string | undefined { |
| 256 | + if (ruleNames !== null) { |
| 257 | + if (t instanceof ParserRuleContext) { |
| 258 | + const context = t.ruleContext; |
| 259 | + const altNumber = context.getAltNumber(); |
| 260 | + // use const value of ATN.INVALID_ALT_NUMBER to avoid circular dependency |
| 261 | + if (altNumber !== 0) { |
| 262 | + return ruleNames[t.ruleIndex] + ":" + altNumber; |
| 263 | + } |
| 264 | + |
| 265 | + return ruleNames[t.ruleIndex]; |
| 266 | + } else if (t instanceof ErrorNode) { |
| 267 | + return t.toString(); |
| 268 | + } else if (t instanceof TerminalNode) { |
| 269 | + if (t.symbol !== null) { |
| 270 | + return t.symbol.text; |
| 271 | + } |
| 272 | + } |
| 273 | + } |
| 274 | + const payload = t.getPayload(); |
| 275 | + if (isToken(payload)) { |
| 276 | + return payload.text; |
| 277 | + } |
| 278 | + |
| 279 | + return String(t.getPayload()); |
| 280 | +} |
| 281 | + |
224 | 282 |
|
225 | 283 | main() |
0 commit comments