ADA_Standards 1.1.1

A library to help you handle checks on your ADA projects, especially good to build scripts to check coding standards conformity.
Documentation

ADA_Standards

Rust Latest version Documentation License

A lightweight, regex-based Ada parser in Rust. Extracts packages, procedures, types, and more into an Abstract Syntax Tree (AST) for analysis, linting, and standards-checking.

Features

  • Code Cleaning: Includes a clean_code utility to strip comments while correctly preserving strings and file structure.
  • Comprehensive Extraction: Parses dozens of Ada constructs, including:
    • package (spec and body)
    • procedure and function (spec, body, and is new instantiations)
    • task (spec and body) and entry (spec and body)
    • type and subtype (records, arrays, derived types, etc.)
    • Representation clauses (for ... use at ... and for ... use record)
    • if / elsif / else statements
    • case statements
    • loop, while, and for loops
    • declare blocks
    • Variable declarations (e.g., A, B : Integer := 10;)
  • Intelligent Parsing:
    • Builds an indextree-based AST with correct parent-child hierarchy.
    • Parses procedure/function parameters into a structured Vec<ArgumentData>.
    • Parses if, while, and exit when conditions into a structured ConditionExpr.
    • Populates case nodes with their when clauses.

Getting Started

ADA_Standards is available on crates.io. You can add it to your project with:

cargo add ADA_Standards

Or, add the following to your Cargo.toml, replacing 1.1.1 with the latest version:

[dependencies]

ADA_Standards = "1.1.1" 

...and see the docs for how to use it.

Example

use ADA_Standards::{AST, ASTError};
use std::fs;
use std::path::Path;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. Read Ada source file
    let file_path = "path/to/your/ada_file.adb"; // Try it with blop.ada!
    let code_text = fs::read_to_string(file_path)?;

    // 2. Clean the code (removes comments, preserves strings and layout)
    let cleaned_code = AST::clean_code(&code_text);

    // 3. Extract all nodes from the code
    let nodes = AST::extract_all_nodes(&cleaned_code)?;

    // 4. Create a new AST and build the tree structure
    let mut ast = AST::new(nodes);
    ast.build(&cleaned_code)?; // This runs the end-of-block association

    // 5. Run post-processing to populate details
    ast.populate_cases(&cleaned_code)?;
    ast.populate_simple_loop_conditions(&cleaned_code)?;

    // 6. Analyze the tree!
    println!("Successfully built AST!");
    ast.print_tree();

    // Example: Find the 'estocazz' procedure and list its direct children
    if let Some(estocazz_id) = ast.find_node_by_name_and_type("estocazz", "ProcedureNode") {
        println!("\nChildren of 'estocazz':");
        for child_id in estocazz_id.children(ast.arena()) {
            let child_node = ast.arena().get(child_id).unwrap().get();
            println!(
                "  - {} (Type: {}, Line: {:?})",
                child_node.name,
                child_node.node_type,
                child_node.start_line
            );
        }
    }
    
    Ok(())
}

License

Licensed under

Contribution

You are free to contribute by forking and creating a pull request !

Author

My name is Francesco Abate, I'm a computer engineer with experience in the fields of software and embedded programming, cybersecurity and AI, I am currently working on my mastery of the Rust language and seeking a job in that field!

Feel free to visit my website: Francesco Abate

You can also contact me @ francesco1.abate@yahoo.com or on linkedin