### Implementing a Minimal TrivialParser Source: https://context7.com/lezer-parser/common/llms.txt Extends the abstract Parser class to create a concrete parser. This example demonstrates a minimal parser that produces a flat, single-node tree. Requires imports from @lezer/common. ```typescript import { Parser, Input, PartialParse, TreeFragment, Tree, NodeSet, NodeType } from "@lezer/common"; // Minimal concrete parser that produces a flat single-node tree const types = [ NodeType.define({ id: 0, name: "" }), NodeType.define({ id: 1, name: "Doc", top: true }), ]; const set = new NodeSet(types); class TrivialParser extends Parser { createParse(input: Input, _fragments: readonly TreeFragment[], ranges: readonly { from: number; to: number }[]): PartialParse { let done = false; return { advance() { if (done) return null; done = true; return new Tree(set.types[1], [], [], input.length); }, get parsedPos() { return done ? input.length : 0; }, stopAt(_pos: number) {}, get stoppedAt() { return null; }, }; } } const parser = new TrivialParser(); // Synchronous full parse const tree = parser.parse("hello world"); console.log(tree.type.name); // "Doc" console.log(tree.length); // 11 // Incremental parse (step by step) const partial = parser.startParse("hello world"); let result: Tree | null = null; while (!(result = partial.advance())) {} console.log(result.type.name); // "Doc" ``` -------------------------------- ### Tree.build Source: https://context7.com/lezer-parser/common/llms.txt Constructs a Tree object from a postfix-ordered numeric buffer. This is the primary way to create a syntax tree from parser output. ```APIDOC ## Tree.build ### Description Constructs a Tree object from a postfix-ordered numeric buffer. This is the primary way to create a syntax tree from parser output. ### Method `Tree.build(options: { buffer: number[], nodeSet: NodeSet, topID: number, length: number })` ### Parameters #### Options - **buffer** (number[]) - Required - The postfix-ordered numeric buffer produced by a Lezer parser. - **nodeSet** (NodeSet) - Required - The NodeSet containing the NodeType definitions. - **topID** (number) - Required - The ID of the top-level node type. - **length** (number) - Required - The total length of the document represented by the tree. ### Request Example ```typescript import { Tree, NodeType, NodeSet } from "@lezer/common"; const types = [ NodeType.define({ id: 0, name: "" }), NodeType.define({ id: 1, name: "Program", top: true }), NodeType.define({ id: 2, name: "Identifier" }), ]; const set = new NodeSet(types); const tree = Tree.build({ buffer: [ 2, 0, 2, 4, // Identifier "id" at 0..2 1, 0, 10, 8, // Program 0..10 (contains the identifier) ], nodeSet: set, topID: 1, length: 10, }); ``` ### Response #### Success Response (Tree) - **Tree** - The constructed syntax tree object. ### Response Example ```typescript console.log(tree.toString()); // "Program(Identifier)" console.log(tree.length); // 10 console.log(tree.type.name); // "Program" console.log(tree.topNode.name); // "Program" ``` ``` -------------------------------- ### Build a Lezer Tree Source: https://context7.com/lezer-parser/common/llms.txt Constructs a syntax tree from a postfix-ordered numeric buffer. Ensure the `NodeSet` and `topID` are correctly configured for your grammar. ```typescript import { Tree, NodeType, NodeSet, NodeProp } from "@lezer/common"; const types = [ NodeType.define({ id: 0, name: "" }), NodeType.define({ id: 1, name: "Program", top: true }), NodeType.define({ id: 2, name: "Identifier" }), ]; const set = new NodeSet(types); // Build a tree from a postfix buffer: // Buffer format per node: [typeId, from, to, endBufferIndex] // "id(0, 10) Program(0, 10)" => const tree = Tree.build({ buffer: [ 2, 0, 2, 4, // Identifier "id" at 0..2 1, 0, 10, 8, // Program 0..10 (contains the identifier) ], nodeSet: set, topID: 1, length: 10, }); console.log(tree.toString()); // "Program(Identifier)" console.log(tree.length); // 10 console.log(tree.type.name); // "Program" console.log(tree.topNode.name); // "Program" // Resolve a node at position 1 (inside Identifier) const node = tree.resolve(1, 0); console.log(node.name); // "Identifier" console.log(node.from, node.to); // 0 2 ``` -------------------------------- ### Parser Source: https://context7.com/lezer-parser/common/llms.txt The Parser is an abstract base class for Lezer parsers. Concrete implementations must implement `createParse`. The base class provides `startParse` for initiating parses (supporting incremental reuse and ranges) and `parse` for completing a parse synchronously. ```APIDOC ## Parser — Abstract base class for all Lezer parsers `Parser` is the abstract superclass that concrete parser implementations (e.g., `LRParser`) must extend by implementing `createParse`. The base class provides `startParse` (which accepts a string or `Input`, optional `TreeFragment[]` for incremental reuse, and optional parse ranges) and `parse` (which drives a parse to completion synchronously). ```typescript import { Parser, Input, PartialParse, TreeFragment, Tree, NodeSet, NodeType } from "@lezer/common"; // Minimal concrete parser that produces a flat single-node tree const types = [ NodeType.define({ id: 0, name: "" }), NodeType.define({ id: 1, name: "Doc", top: true }), ]; const set = new NodeSet(types); class TrivialParser extends Parser { createParse(input: Input, _fragments: readonly TreeFragment[], ranges: readonly { from: number; to: number }[]): PartialParse { let done = false; return { advance() { if (done) return null; done = true; return new Tree(set.types[1], [], [], input.length); }, get parsedPos() { return done ? input.length : 0; }, stopAt(_pos: number) {}, get stoppedAt() { return null; }, }; } } const parser = new TrivialParser(); // Synchronous full parse const tree = parser.parse("hello world"); console.log(tree.type.name); // "Doc" console.log(tree.length); // 11 // Incremental parse (step by step) const partial = parser.startParse("hello world"); let result: Tree | null = null; while (!(result = partial.advance())) {} console.log(result.type.name); // "Doc" ``` ``` -------------------------------- ### Iterate Through a Lezer Tree Source: https://context7.com/lezer-parser/common/llms.txt Performs a depth-first traversal of a syntax tree using enter and leave callbacks. Returning `false` from `enter` skips the subtree. An optional `from`/`to` range limits the visited nodes. ```typescript import { Tree, NodeSet, NodeType, IterMode } from "@lezer/common"; // (using the `tree` built in the Tree example above) const visited: string[] = []; tree.iterate({ enter(node) { visited.push(`enter:${node.name}@${node.from}-${node.to}`); }, leave(node) { visited.push(`leave:${node.name}`); }, }); console.log(visited); // ["enter:Program@0-10", "enter:Identifier@0-2", "leave:Identifier", "leave:Program"] // Skip subtrees by returning false from enter tree.iterate({ enter(node) { if (node.name === "Program") return false; // don't descend visited.push(node.name); }, from: 0, to: 5, }); ``` -------------------------------- ### Tree.iterate Source: https://context7.com/lezer-parser/common/llms.txt Performs a depth-first traversal of the syntax tree, calling enter and leave callbacks for each node. Allows skipping subtrees and limiting the traversal range. ```APIDOC ## Tree.iterate ### Description Performs a depth-first traversal of the syntax tree, calling `enter` before descending into a node and `leave` (if provided) after. Returning `false` from `enter` skips the subtree. An optional `from`/`to` range limits which nodes are visited. ### Method `tree.iterate(options: { enter: (node: SyntaxNode) => boolean | void, leave?: (node: SyntaxNode) => void, from?: number, to?: number })` ### Parameters #### Options - **enter** ((node: SyntaxNode) => boolean | void) - Required - Callback function executed before visiting a node's children. Returning `false` prevents descending into the node's subtree. - **leave** ((node: SyntaxNode) => void) - Optional - Callback function executed after visiting a node's children. - **from** (number) - Optional - The starting position of the range to iterate over. - **to** (number) - Optional - The ending position of the range to iterate over. ### Request Example ```typescript // Assuming 'tree' is a valid Tree object const visited: string[] = []; tree.iterate({ enter(node) { visited.push(`enter:${node.name}@${node.from}-${node.to}`); }, leave(node) { visited.push(`leave:${node.name}`); }, from: 0, to: 5 }); ``` ### Response #### Success Response (void) This method does not return a value, but executes the provided callbacks. ### Response Example ```typescript console.log(visited); // Example output: ["enter:Program@0-10", "enter:Identifier@0-2", "leave:Identifier", "leave:Program"] ``` ``` -------------------------------- ### Mutable Tree Traversal with TreeCursor Source: https://context7.com/lezer-parser/common/llms.txt Provides efficient, mutable traversal of a syntax tree. Use methods like `firstChild()`, `nextSibling()`, and `moveTo()` for navigation. The `iterate()` method allows subtree walks. ```typescript import { Tree, NodeSet, NodeType, IterMode } from "@lezer/common"; // (using `tree` from the Tree example) const cursor = tree.cursor(); // Pre-order traversal with next() do { console.log(`${cursor.name} [${cursor.from}..${cursor.to}]`); } while (cursor.next()); // Program [0..10] // Identifier [0..2] // Navigate directly const c2 = tree.cursorAt(1, 0); // position 1, side 0 console.log(c2.name); // "Identifier" c2.parent(); console.log(c2.name); // "Program" // cursor.iterate() — subtree walk const c3 = tree.cursor(); c3.firstChild(); c3.iterate(node => { console.log("visit", node.name); }); // matchContext: check ancestor names const c4 = tree.cursorAt(1, 0); console.log(c4.matchContext(["Program"])); // true ``` -------------------------------- ### NodeWeakMap Source: https://context7.com/lezer-parser/common/llms.txt NodeWeakMap stores values keyed by syntax nodes using weak references, allowing automatic garbage collection of entries when nodes are no longer referenced. It's useful for caching computed data that should persist across incremental reparses as long as the underlying node is reused. ```APIDOC ## NodeWeakMap — Associate values with syntax tree nodes `NodeWeakMap` stores values keyed by syntax nodes (both `Tree`-backed and `TreeBuffer`-backed), using weak references so entries are automatically reclaimed when tree nodes are garbage-collected. This is useful for caching computed data (e.g., highlight decorations) that should survive incremental reparsing as long as the underlying node is reused. ```typescript import { NodeWeakMap, Tree, NodeSet, NodeType } from "@lezer/common"; const cache = new NodeWeakMap(); const types = [ NodeType.define({ id: 0, name: "" }), NodeType.define({ id: 1, name: "Keyword" }), ]; const set = new NodeSet(types); const tree = Tree.build({ buffer: [1, 0, 5, 4], nodeSet: set, topID: 1, length: 5 }); const node = tree.topNode; cache.set(node, "computed-value"); console.log(cache.get(node)); // "computed-value" // Works via cursor too const cursor = tree.cursor(); cache.cursorSet(cursor, "cursor-value"); console.log(cache.cursorGet(cursor)); // "cursor-value" ``` ``` -------------------------------- ### Using NodeWeakMap for Syntax Node Caching Source: https://context7.com/lezer-parser/common/llms.txt NodeWeakMap associates values with syntax tree nodes using weak references. It's useful for caching computed data that should persist across reparses as long as the node is reused. Ensure @lezer/common is imported. ```typescript import { NodeWeakMap, Tree, NodeSet, NodeType } from "@lezer/common"; const cache = new NodeWeakMap(); const types = [ NodeType.define({ id: 0, name: "" }), NodeType.define({ id: 1, name: "Keyword" }), ]; const set = new NodeSet(types); const tree = Tree.build({ buffer: [1, 0, 5, 4], nodeSet: set, topID: 1, length: 5 }); const node = tree.topNode; cache.set(node, "computed-value"); console.log(cache.get(node)); // "computed-value" // Works via cursor too const cursor = tree.cursor(); cache.cursorSet(cursor, "cursor-value"); console.log(cache.cursorGet(cursor)); // "cursor-value" ``` -------------------------------- ### TreeCursor Source: https://context7.com/lezer-parser/common/llms.txt Provides a mutable pointer for efficient, low-allocation traversal of a syntax tree. Supports navigation through various methods like firstChild, nextSibling, and moveTo. ```APIDOC ## TreeCursor ### Description `TreeCursor` is a mutable pointer into a syntax tree that is far more efficient than allocating `SyntaxNode` objects for each visited node. It exposes `type`, `name`, `from`, and `to` and can move with `firstChild()`, `lastChild()`, `parent()`, `nextSibling()`, `prevSibling()`, `next()`, `prev()`, `moveTo()`, and `enter()`. ### Method `tree.cursor(): TreeCursor` `tree.cursorAt(position: number, side: -1 | 0 | 1): TreeCursor` ### Properties - **type** (NodeType) - The type of the current node. - **name** (string) - The name of the current node. - **from** (number) - The starting position of the current node. - **to** (number) - The ending position of the current node. ### Navigation Methods - **`firstChild()`**: Moves the cursor to the first child of the current node. - **`lastChild()`**: Moves the cursor to the last child of the current node. - **`parent()`**: Moves the cursor to the parent of the current node. - **`nextSibling()`**: Moves the cursor to the next sibling of the current node. - **`prevSibling()`**: Moves the cursor to the previous sibling of the current node. - **`next()`**: Moves the cursor to the next node in a pre-order traversal. - **`prev()`**: Moves the cursor to the previous node in a pre-order traversal. - **`moveTo(node: SyntaxNode)`**: Moves the cursor to a specific `SyntaxNode`. - **`enter(node: SyntaxNode)`**: Moves the cursor to a child node that covers a given position. ### Request Example ```typescript // Assuming 'tree' is a valid Tree object const cursor = tree.cursor(); // Pre-order traversal do { console.log(`${cursor.name} [${cursor.from}..${cursor.to}]`); } while (cursor.next()); // Navigate directly const c2 = tree.cursorAt(1, 0); console.log(c2.name); // "Identifier" c2.parent(); console.log(c2.name); // "Program" ``` ### Response #### Success Response (TreeCursor) - **TreeCursor** - A cursor object positioned within the tree. ### Response Example ```typescript // Output from pre-order traversal example: // Program [0..10] // Identifier [0..2] ``` ``` -------------------------------- ### Managing Tree Fragments for Incremental Reparsing Source: https://context7.com/lezer-parser/common/llms.txt TreeFragment represents reusable parts of a parse tree for incremental reparsing. Use TreeFragment.addTree to create initial fragments and TreeFragment.applyChanges to update them after document edits. Ensure @lezer/common is imported. ```typescript import { TreeFragment, Tree, NodeSet, NodeType, ChangedRange } from "@lezer/common"; const types = [ NodeType.define({ id: 0, name: "" }), NodeType.define({ id: 1, name: "Doc", top: true }), ]; const set = new NodeSet(types); // Simulate a fully parsed tree for a 100-char document const fullTree = new Tree(set.types[1], [], [], 100); let fragments = TreeFragment.addTree(fullTree); console.log(fragments.length); // 1 console.log(fragments[0].from); // 0 console.log(fragments[0].to); // 100 // Apply an edit: replace chars 20..30 with 5 chars (shrinks by 5) const changes: ChangedRange[] = [{ fromA: 20, toA: 30, fromB: 20, toB: 25 }]; const updated = TreeFragment.applyChanges(fragments, changes); // Fragment before the change is preserved; after is trimmed/adjusted console.log(updated[0].from, updated[0].to); // 0 20 // Pass updated fragments to the next parse for node reuse // parser.startParse(newInput, updated) ``` -------------------------------- ### Extend NodeSet with Custom Props Source: https://context7.com/lezer-parser/common/llms.txt Create a new `NodeSet` by extending an existing one with additional properties applied to specific node types. This allows for layering metadata without mutating the original set. ```typescript import { NodeSet, NodeType, NodeProp } from "@lezer/common"; const types = [ NodeType.define({ id: 0, name: "" }), // anonymous/none NodeType.define({ id: 1, name: "Program", top: true }), NodeType.define({ id: 2, name: "Expression" }), NodeType.define({ id: 3, name: "Identifier" }), NodeType.define({ id: 4, name: "Number" }), ]; const baseSet = new NodeSet(types); // Add a "highlight" prop to specific node types const highlight = new NodeProp({ deserialize: s => s }); const extendedSet = baseSet.extend( highlight.add({ Identifier: "variable", Number: "number", }) ); console.log(extendedSet.types[3].prop(highlight)); // "variable" console.log(extendedSet.types[4].prop(highlight)); // "number" console.log(baseSet.types[3].prop(highlight)); // undefined (original unchanged) ``` -------------------------------- ### Define NodeType with Props and Matcher Source: https://context7.com/lezer-parser/common/llms.txt Define custom node types with properties like isolation and highlighting. Use `NodeType.match` to create lookup functions for node properties based on their names. ```typescript import { NodeType, NodeProp, NodeSet } from "@lezer/common"; // Define a custom "isolate" prop for bidi text handling const highlight = new NodeProp({ deserialize: s => s }); const StringNode = NodeType.define({ id: 1, name: "String", props: [[NodeProp.isolate, "auto"], [highlight, "string"]], }); const ErrorNode = NodeType.define({ id: 2, name: "⚠", error: true }); const TopNode = NodeType.define({ id: 3, name: "Program", top: true }); console.log(StringNode.name); // "String" console.log(StringNode.isError); // false console.log(ErrorNode.isError); // true console.log(TopNode.isTop); // true console.log(StringNode.prop(highlight)); // "string" console.log(StringNode.prop(NodeProp.isolate)); // "auto" // NodeType.match: map node names/groups to values const isKeyword = NodeType.match({ "if else for while return": true, }); console.log(isKeyword(StringNode)); // undefined ``` -------------------------------- ### SyntaxNode Source: https://context7.com/lezer-parser/common/llms.txt Represents an immutable reference to a specific node within a syntax tree. Provides access to node properties and navigation methods. ```APIDOC ## SyntaxNode ### Description `SyntaxNode` is an immutable pointer to a specific tree node. Unlike a cursor, a `SyntaxNode` object remains valid after further traversal. It provides `parent`, `firstChild`, `lastChild`, `nextSibling`, `prevSibling`, `getChild()`, `getChildren()`, `enter()`, `resolve()`, `resolveInner()`, `prop()`, and `toTree()`. ### Properties - **name** (string) - The name of the node. - **from** (number) - The starting position of the node. - **to** (number) - The ending position of the node. - **parent** (SyntaxNode | null) - The parent node. - **firstChild** (SyntaxNode | null) - The first child node. - **lastChild** (SyntaxNode | null) - The last child node. - **nextSibling** (SyntaxNode | null) - The next sibling node. - **prevSibling** (SyntaxNode | null) - The previous sibling node. ### Methods - **`getChild(name: string)`**: Returns the first child with the given name. - **`getChildren(name?: string)`**: Returns an array of all child nodes, optionally filtered by name. - **`enter(position: number, side: -1 | 0 | 1)`**: Descends into a child node covering the specified position. - **`resolve(position: number, side: -1 | 0 | 1)`**: Resolves a node at the given position, similar to `Tree.resolve`. - **`resolveInner(position: number, side: -1 | 0 | 1)`**: Resolves the innermost node covering the position. - **`prop(prop: NodeProp)`**: Retrieves a property value associated with the node. - **`toTree()`**: Creates a standalone `Tree` object from the node. ### Request Example ```typescript // Assuming 'tree' is a valid Tree object const top: import("@lezer/common").SyntaxNode = tree.topNode; console.log(top.name); // "Program" console.log(top.firstChild?.name); // "Identifier" // Get a specific child const id = top.getChild("Identifier"); console.log(id?.from, id?.to); // 0 2 // Descend into a child const entered = top.enter(1, 0); console.log(entered?.name); // "Identifier" ``` ### Response #### Success Response (SyntaxNode) - **SyntaxNode** - An immutable reference to a node in the syntax tree. ### Response Example ```typescript // Example output from resolveStack: // Program // Identifier ``` ``` -------------------------------- ### TreeFragment Source: https://context7.com/lezer-parser/common/llms.txt TreeFragment represents a reusable part of a previous parse tree for incremental reparsing. `TreeFragment.addTree` initializes a fragment set from a parse, and `TreeFragment.applyChanges` updates this set to reflect document edits, adjusting fragments that overlap changed ranges. ```APIDOC ## TreeFragment — Incremental parse reuse `TreeFragment` represents a reusable region of a previous parse tree for incremental reparsing. `TreeFragment.addTree` creates an initial fragment set from a completed parse, and `TreeFragment.applyChanges` updates a fragment set to reflect document edits, trimming or splitting fragments that overlap changed ranges. ```typescript import { TreeFragment, Tree, NodeSet, NodeType, ChangedRange } from "@lezer/common"; const types = [ NodeType.define({ id: 0, name: "" }), NodeType.define({ id: 1, name: "Doc", top: true }), ]; const set = new NodeSet(types); // Simulate a fully parsed tree for a 100-char document const fullTree = new Tree(set.types[1], [], [], 100); let fragments = TreeFragment.addTree(fullTree); console.log(fragments.length); // 1 console.log(fragments[0].from); // 0 console.log(fragments[0].to); // 100 // Apply an edit: replace chars 20..30 with 5 chars (shrinks by 5) const changes: ChangedRange[] = [{ fromA: 20, toA: 30, fromB: 20, toB: 25 }]; const updated = TreeFragment.applyChanges(fragments, changes); // Fragment before the change is preserved; after is trimmed/adjusted console.log(updated[0].from, updated[0].to); // 0 20 // Pass updated fragments to the next parse for node reuse // parser.startParse(newInput, updated) ``` ``` -------------------------------- ### Attach Metadata with NodeProp Source: https://context7.com/lezer-parser/common/llms.txt Use `NodeProp` to attach metadata to node types or individual tree nodes. Built-in props like `closedBy` handle common cases, while custom props can be defined with specific deserialization and combination logic. ```typescript import { NodeProp, NodeType, NodeSet } from "@lezer/common"; // Per-type prop: bracket matching const closingBracket = NodeProp.closedBy; // built-in const OpenParen = NodeType.define({ id: 4, name: "(", props: [closingBracket.add({ "(": ")" })], }); console.log(OpenParen.prop(NodeProp.closedBy)); // [")"] // Custom per-type prop with combine (additive) const tagsProp = new NodeProp({ deserialize: s => s.split(","), combine: (a, b) => [...a, ...b], }); const FnNode = NodeType.define({ id: 5, name: "FunctionDeclaration", props: [tagsProp.add({ FunctionDeclaration: ["declaration"] })], }); // Per-node prop (stored on the Tree instance, not the type) const perNodeMeta = new NodeProp({ perNode: true }); ``` -------------------------------- ### Tree.resolve Source: https://context7.com/lezer-parser/common/llms.txt Resolves a node at a specific position within the tree. Useful for finding the most specific node covering a given character offset. ```APIDOC ## Tree.resolve ### Description Resolves a node at a specific position within the tree. Useful for finding the most specific node covering a given character offset. ### Method `tree.resolve(position: number, side: -1 | 0 | 1): SyntaxNode` ### Parameters #### Path Parameters - **position** (number) - Required - The character offset within the tree to resolve. - **side** (-1 | 0 | 1) - Required - Determines which node to return when the position falls exactly on a node boundary. 0 prefers the node starting at the position, -1 prefers the node ending before it, and 1 prefers the node starting at it. ### Response #### Success Response (SyntaxNode) - **SyntaxNode** - The node at the specified position. ### Response Example ```typescript // Assuming 'tree' is a valid Tree object const node = tree.resolve(1, 0); console.log(node.name); // "Identifier" console.log(node.from, node.to); // 0 2 ``` ``` -------------------------------- ### Wrap Parser for Mixed-Language Support Source: https://context7.com/lezer-parser/common/llms.txt Use `parseMixed` to wrap a base parser, enabling support for embedded sublanguages. The `nest` callback determines when and how inner parsers are applied to specific node types. ```typescript import { parseMixed, NestedParse, SyntaxNodeRef, Input, Parser, NodeSet, NodeType, Tree, TreeFragment, PartialParse } from "@lezer/common"; // Assume `htmlParser` and `jsParser` are LRParser instances declare const htmlParser: Parser; declare const jsParser: Parser; // Build a wrapper that embeds JS inside ScriptText nodes const mixedHtmlParser: Parser = Object.assign( Object.create(Object.getPrototypeOf(htmlParser)), { createParse(input: Input, fragments: readonly TreeFragment[], ranges: readonly { from: number; to: number }[]) { return parseMixed((node: SyntaxNodeRef, _input: Input): NestedParse | null => { if (node.name === "ScriptText") { return { parser: jsParser }; } if (node.name === "StyleText") { // overlay: only parse specific sub-ranges return { parser: jsParser, // replace with cssParser in practice overlay: [{ from: node.from, to: node.to }], }; } return null; })(htmlParser.startParse(input, fragments, ranges), input, fragments, ranges); }, } as Pick ); // The resulting tree will have MountedTree props on ScriptText nodes const tree = mixedHtmlParser.parse(""); const cursor = tree.cursor(); do { if (cursor.name === "ScriptText") { const mounted = cursor.tree?.prop(require("@lezer/common").NodeProp.mounted); if (mounted) console.log("Inner JS tree:", mounted.tree.toString()); } } while (cursor.next()); ``` -------------------------------- ### Customize Tree Traversal with IterMode Source: https://context7.com/lezer-parser/common/llms.txt Use `IterMode` bit flags with `cursor()`, `iterate()`, and `enter()` to control which nodes are visited during tree traversal. Flags can be combined using the `|` operator. ```typescript import { Tree, NodeSet, NodeType, IterMode } from "@lezer/common"; const types = [ NodeType.define({ id: 0, name: "" }), NodeType.define({ id: 1, name: "Program", top: true }), NodeType.define({ id: 2, name: "Stmt" }), ]; const set = new NodeSet(types); const tree = Tree.build({ buffer: [2, 0, 5, 4, 2, 6, 10, 4, 1, 0, 10, 12], nodeSet: set, topID: 1, length: 10, }); // Include anonymous wrapper nodes in traversal const cursorWithAnon = tree.cursor(IterMode.IncludeAnonymous); // Exclude buffer-packed nodes, visit only Tree objects const cursorNoBuffers = tree.cursor(IterMode.ExcludeBuffers); // Ignore mounted overlays during iteration const cursorNoMounts = tree.cursor(IterMode.IgnoreMounts); // Combine flags: exclude buffers AND ignore overlays const combined = tree.cursor(IterMode.ExcludeBuffers | IterMode.IgnoreMounts); // Enter a child at position 7, entering bracketed overlays const top = tree.topNode; const child = top.enter(7, 0, IterMode.EnterBracketed); console.log(child?.name); // "Stmt" ``` -------------------------------- ### Immutable Node References with SyntaxNode Source: https://context7.com/lezer-parser/common/llms.txt Represents an immutable pointer to a specific tree node, remaining valid after traversal. Use methods like `getChild()`, `enter()`, and `resolveStack()` for node inspection and descent. ```typescript import { Tree, NodeSet, NodeType, NodeProp } from "@lezer/common"; // (using `tree` from the Tree example) const top: import("@lezer/common").SyntaxNode = tree.topNode; console.log(top.name); // "Program" console.log(top.firstChild?.name); // "Identifier" console.log(top.firstChild?.parent?.name); // "Program" // getChild / getChildren const id = top.getChild("Identifier"); console.log(id?.from, id?.to); // 0 2 // enter: descend into child covering a position const entered = top.enter(1, 0); console.log(entered?.name); // "Identifier" // resolveStack: iterate all nodes covering a position, including overlays for (let iter = tree.resolveStack(1, 0); iter; iter = iter.next!) { console.log(iter.node.name); } // toTree: obtain a standalone Tree from a buffer-backed node const standalone = id!.toTree(); console.log(standalone instanceof Tree); // true ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.