Architecture
This chapter explains how ROUP is organised internally and where to look when modifying the parser or the public bindings.
High level view
source text
│
▼
lexer (`src/lexer.rs`)
│ ─ token stream with language specific helpers
▼
parser (`src/parser/`)
│ ─ builds an intermediate representation (IR)
▼
IR (`src/ir/`)
│ ├─ used directly by Rust callers
│ └─ converted into the C API data structures
▼
C bindings (`src/c_api.rs`)
The lexer normalises whitespace, line continuations, sentinel comments, and language specific keywords before the parser consumes the token stream. The parser modules mirror the OpenMP structure: directives, clauses, helper enumerations, and validation passes. Rust callers typically work with the IR structures directly, while C and C++ consumers receive stable C structs exposed through the FFI layer.
Unsafe code boundaries
The vast majority of the project uses safe Rust. The only unsafe blocks live
inside src/c_api.rs where pointers cross the FFI boundary. Each function
performs explicit null checks and documents its expectations. When modifying or
adding FFI functions, keep the following rules in mind:
- Convert raw pointers to Rust types as late as possible and convert back only when returning values to the caller.
- Maintain ownership invariants: the caller is responsible for freeing values returned by constructors and must not free borrowed data.
- Update the generated C constants header whenever the exported structs or enums change.
Generated constants and headers
The build script (build.rs) parses portions of src/c_api.rs using syn to
produce src/roup_constants.h (also emitted to OUT_DIR). This keeps the OpenMP
and OpenACC directive/clause tables in sync with the Rust implementation.
Compatibility layers
compat/ompparser/mirrors the original ompparser API, forwarding calls through the ROUP C API and converting the resulting structures back into the expected C++ types. The CMake tests in the ompparser submodule validate parity.compat/accparser/provides the same drop-in experience for accparser with ROUP_ACC_* constants and the upstream ctest suite.
Testing
Integration tests live under tests/ and cover keyword registration, parser
round-trips, language specific behaviour, and helper utilities. Running
cargo test executes the Rust suites, while test.sh orchestrates the full
project matrix including compatibility and documentation builds.