accparser is a standalone OpenACC 3.4 directive parser for C, C++, and
Fortran. It separates the directive envelope and OpenACC structure from opaque
host-language expressions, then produces an owning, value-semantic typed AST.
Invalid input produces diagnostics and never produces a partial AST.
The build requires CMake 3.20 or later, ANTLR 4, and the ANTLR 4 C++ runtime. On Ubuntu or Debian:
sudo apt update
sudo apt install -y antlr4 libantlr4-runtime-dev build-essential cmakecmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build
cd build
ctest --output-on-failureThe regression suite includes focused positive and negative parser tests, concurrent parsing, semantic parse-print-parse checks, and pragmas extracted from OpenACCV-V.
Optional hardening configurations are available:
cmake -S . -B build-asan -DCMAKE_BUILD_TYPE=Debug \
-DACCPARSER_ENABLE_ASAN_UBSAN=ON
cmake -S . -B build-tsan -DCMAKE_BUILD_TYPE=Debug \
-DACCPARSER_ENABLE_TSAN=ONWith Clang, -DACCPARSER_BUILD_FUZZER=ON also builds parser_fuzz. A seed
corpus is provided in tests/fuzz_corpus.
Include OpenACCParser.h; public headers do not expose generated ANTLR types.
The caller specifies the base language and source form explicitly:
#include"OpenACCParser.h"
openacc::ParseResult result = openacc::parseDirective(
"#pragma acc parallel loop gang vector private(a)",
{openacc::Language::Cxx, openacc::InputForm::CPragma});
if (!result.succeeded()) {
for (const openacc::Diagnostic &diagnostic : result.diagnostics) {
// diagnostic.code, diagnostic.message, and diagnostic.range are available.
}
return;
}
std::string canonical = openacc::formatDirective(*result.directive);Supported input forms are a directive body, a C/C++ #pragma, a C/C++
_Pragma operator, and free- or fixed-form Fortran sentinels. The formatter can
emit any selected envelope through openacc::PrintOptions; by default it emits
#pragma for C/C++ and a free-form sentinel for Fortran.
The AST owns its data and uses clause-specific types. For example, copyin,
copyout, and create have distinct modifier enums, device-specific clauses
are partitioned into explicit groups, lists are nonempty by construction, and
host fragments are distinguished as conditions, integer expressions, variable
references, routine names, and other semantic categories.
The public API is openacc::parseDirective, which is reentrant, requires the
caller to state the source language and envelope explicitly, and returns
structured diagnostics without heap-transfer or sentinel-based failure modes.