---
name: "ExtUtils::ParseXS::Node"
section: "3perl"
platform: "linux"
package: "perl"
version: "5.44.0-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/ExtUtils::ParseXS::Node/3perl"
---

# ExtUtils::ParseXS::Node(3perl)

Classes for nodes of an Abstract Syntax Tree

## NAME

ExtUtils::ParseXS::Node - Classes for nodes of an Abstract Syntax Tree

## SYNOPSIS

```
    # Create a node to represent the Foo part of an XS file; then
    # top-down parse it into a subtree; then top-down emit the
    # contents of the subtree as C code.
    my $foo = ExtUtils::ParseXS::Node::Foo->new();
    $foo->parse(...)
        or die;
    $foo->as_code(...);
    print STDERR $foo->as_concise(1); # for debugging
```

## DESCRIPTION

This API is currently private and subject to change.

The `"ExtUtils::ParseXS::Node"` class, and its various subclasses, hold the state for the nodes of an Abstract Syntax Tree (AST), which represents the parsed state of an XS file.

Each node is a hash of fields. Which field names are legal varies by the node type. The hash keys and values can be accessed directly: there are no getter/setter methods.

Each node may have a `"kids"` field which points to an array of all the children of that node: this is what provides the tree structure. In addition, some of those kids may also have direct links from fields for quick access. For example, the `"xsub_decl"` child object of an `"xsub"` object can be accessed in either of these ways:

```
    $xsub_object->{kids}[0]
    $xsub_object->{decl}
```

Most object-valued node fields within a tree point only to their direct children; however, both `"INPUT_line"` and `"OUTPUT_line"` have an `"ioparam"` field which points to the `"IO_Param"` object associated with this line, which is located elsewhere in the tree.

The various `"foo_part"` nodes divide the parsing of the main body of an XSUB into sections where different sets of keywords are allowable, and where various bits of code can be conveniently emitted.

### Methods

There are two main methods in addition to `new()`, which are present in all subclasses. First, `parse()` consumes lines from the source to satisfy the construct being parsed. It may itself create objects of lower-level constructs and call parse on them. For example, `Node::xbody::parse()` may create a `"Node::input_part"` node and call `parse()` on it, which will create `"Node::INPUT"` or `"Node::PREINIT"` nodes as appropriate, and so on.

Secondly, `as_code()` descends its sub-tree, outputting the tree as C code.

The `as_concise()` method returns a line-per-node string representation of the node and any children. Most node classes just inherit this method from the base `"Node"` class. It is intended mainly for debugging.

Some nodes also have an `as_boot_code()` method for adding any code to the boot XSUB. This returns two array refs, one containing a list of code lines to be inserted early into the boot XSUB, and a second for later lines.

Finally, in the IO\_Param subclass, `as_code()` is replaced with `"as_input_code"` and `as_output_code()`, since that node may need to generate *two* sets of C code; one to assign a Perl argument to a C variable, and the other to return the value of a variable to Perl.

Note that parsing and code-generation are done as two separate phases; `parse()` should only build a tree and never emit code.

In addition to `$self`, methods may commonly have some of these parameters:

- $pxs

  An `"ExtUtils::ParseXS"` object which contains the overall processing state. In particular, it has warning and croaking methods, and holds the lines read in from the source file for the current paragraph.

- $xsub

  For nodes related to parsing an XSUB, the current `"ExtUtils::ParseXS::xsub"` node being processed.

- $xbody

  For nodes related to parsing an XSUB, the current `"ExtUtils::ParseXS::xbody"` node being processed. Note that in the presence of a `"CASE"` keyword, an XSUB can have multiple bodies.

The `parse()` and `as_code()` methods for some subclasses may have parameters in addition to those.

Some subclasses may also have additional helper methods.

### Class Hierachy

`"Node"` and its sub-classes form the following inheritance hierarchy. Various abstract classes are used by concrete subclasses where the processing and/or fields are similar: for example, `"CODE"`, `"PPCODE"` etc all consume a block of uninterpreted lines from the source file until the next keyword, and emit that code, possibly wrapped in `"#line"` directives. This common behaviour is provided by the `"codeblock"` class.

```
    Node
        XS_file
        preamble
        C_part
        C_part_POD
        C_part_code
        C_part_postamble
        cpp_scope
        global_cpp_line
        BOOT
        TYPEMAP
        pre_boot
        boot_xsub
        xsub
        xsub_decl
        ReturnType
        Param
            IO_Param
        Params
        xbody
        input_part
        init_part
        code_part
        output_part
        cleanup_part
        autocall
        oneline
            MODULE
            REQUIRE
            FALLBACK
            include
                INCLUDE
                INCLUDE_COMMAND
            NOT_IMPLEMENTED_YET
            CASE
            enable
                EXPORT_XSUB_SYMBOLS
                PROTOTYPES
                SCOPE
                VERSIONCHECK
        multiline
            multiline_merged
                C_ARGS
                INTERFACE
                INTERFACE_MACRO
                OVERLOAD
            ATTRS
            PROTOTYPE
            codeblock
                CODE
                CLEANUP
                INIT
                POSTCALL
                PPCODE
                PREINIT
        keylines
            ALIAS
            INPUT
            OUTPUT
        keyline
            ALIAS_line
            INPUT_line
            OUTPUT_line
```

### Abstract Syntax Tree structure

A typical XS file might compile to a tree with a node structure similar to the following. Note that this is unrelated to the inheritance hierarchy shown above. In this example, the XS file includes another file, and has a couple of XSUBs within a `"#if/#else/#endif"`. Note that a `"cpp_scope"` node is the parent of all the nodes within the same branch of an `"#if"`, or in the absence of `"#if"`, within the same file.

```
    XS_file
        preamble
        C_part
            C_part_POD
            C_part_code
        C_part_postamble
        cpp_scope: type="main"
            MODULE
            PROTOTYPES
            BOOT
            TYPEMAP
            INCLUDE
                cpp_scope: type="include"
                    xsub
                        ...
            global_cpp_line: directive="ifdef"
            cpp_scope: type="if"
                xsub
                    ...
            global_cpp_line: directive="else"
            cpp_scope: type="if"
                xsub
                    ...
            global_cpp_line: directive="endif"
            xsub
                ...
        pre_boot
        boot_xsub
```

A typical XSUB might compile to a tree with a structure similar to the following.

```
    xsub
        xsub_decl
            ReturnType
            Params
                Param
                Param
                ...
        CASE   # for when a CASE keyword being present implies multiple
               # bodies; otherwise, just a bare xbody node.
            xbody
                # per-body copy of declaration Params, augmented by
                # data from INPUT and OUTPUT sections
                Params
                    IO_Param
                    IO_Param
                    ...
                input_part
                    INPUT
                        INPUT_line
                        INPUT_line
                        ...
                    PREINIT
                init_part
                    INIT
                code_part
                    CODE
                output_part
                    OUTPUT
                        OUTPUT_line
                        OUTPUT_line
                        ...
                    POSTCALL
                cleanup_part
                    CLEANUP
        CASE
            xbody
                ...
```
