Skip to content

Modules and External Parsers

Sinfolke edited this page Oct 25, 2026 · 1 revision

Modules and External Parsers

ISPA can split a grammar into modules and call another generated parser. This is useful when one language embeds another.

Grammar modules

A file can declare its module and output namespace:

module main -> demo;

Pass --dir grammar-directory to scan imported grammar modules. Imports such as import std.collections; and Python helper imports such as import py {sep_seq_to_list} from ast; are used in the standard library. The installed std package contains std.names, std.separators, std.comments, std.literals, and std.collections. See parser/stdlibs/README.md in the repository for their definitions.

Call another generated parser

import extern python ispa_python as python;
expr: @ python.expr {@};

Bind an existing parser with --dep python parser/python/bootstrapped/PyRawParser. ISPA reads PREFIX.ispa-export for exported symbols, plus PREFIX.h or PREFIX.py for the public API. For C++, compile and link the dependency's implementation separately and add its header directory to your include path. For Python, put its module on PYTHONPATH.

With --no-dep, ISPA discovers external modules under --dir and generates each dependency beside the host. Nested dependencies are generated before consumers; cycles are diagnosed. Explicit --dep bindings can supply prebuilt dependencies while --no-dep generates the rest. Installed package manifests can also supply dependency bindings automatically.

External calls currently require LL and lazy tokenization. The imported span is re-lexed with the dependency's lexer, then the host lexer resumes at the returned source position. Eager tokenization rejects external calls.

Clone this wiki locally