ADA_Standards
A powerful, lightweight regex-based Ada parser written in Rust. Extract packages, procedures, types, control flow, and more from Ada source code into a traversable Abstract Syntax Tree (AST) for analysis, linting, and coding standards enforcement.
โจ Features
Code Preprocessing
- Smart Code Cleaning: Strips comments and string literals while preserving code structure and line numbers
- Tab Normalization: Converts tabs to spaces for consistent parsing
Comprehensive Ada Construct Extraction
- Packages: Specs and bodies, including nested packages
- Subprograms: Procedures and functions (specs, bodies, and generic instantiations)
- Tasks & Entries: Concurrent programming constructs with guard conditions
- Types: Records, arrays, derived types, subtypes, enumerations, and representation clauses
- Control Flow:
if/elsif/else,case,loop,while,for,exit when,declareblocks - Variables: Complete declaration parsing with types and default values
Intelligent Parsing
- Tree-Based AST: Uses
indextreefor efficient parent-child relationships - Structured Parameters: Parses procedure/function arguments into typed
ArgumentDatastructs - Expression Trees: Converts conditions into hierarchical
ConditionExprwith support for:- Binary operators:
and,or,and then,or else,xor - Comparison:
<,>,<=,>=,=,/= - Membership:
in,not in - Unary:
not - Proper precedence and parenthesis handling
- Binary operators:
- Automatic End Association: Matches
endstatements to their corresponding blocks
Analysis-Ready Output
- Precise Location Tracking: Line numbers, character indices, and column positions
- Metadata Capture: Distinguishes specs from bodies, captures type kinds, loop directions, etc.
- Post-Processing: Populate
casealternatives andexit whenconditions after initial parse
๐ฆ Installation
Add to your Cargo.toml:
[]
= "1.2."
Or use cargo:
๐ Quick Start
use ;
use fs;
๐ Usage Examples
Extract Specific Constructs
// Extract only packages
let packages = ASTextract_packages?;
for pkg in &packages
// Extract procedures and functions
let subprograms = ASTextract_procedures_functions?;
// Extract control flow
let loops = ASTextract_simple_loops?;
let while_loops = ASTextract_while_loops?;
let for_loops = ASTextract_for_loops?;
Analyze Conditions
// Parse a condition expression
let condition = ASTparse_condition_expression;
// Access the expression tree
if let Some = &condition.albero
// Access the flat list
for expr in &condition.list
Check Coding Standards
use NodeId;
// Example: Find procedures without documentation comments
Traverse the AST
// Visit all nodes in tree order
for node_id in ast.root_id.descendants
// Find all children of a node
if let Some = ast.find_node_by_name_and_type
// Get parent of a node
if let Some = some_node_id.ancestors.nth
๐ Key Data Structures
NodeData
Represents a single Ada construct with fields like:
name: Identifier (e.g., "MyProcedure")node_type: Type of construct (e.g., "ProcedureNode", "IfStatement")start_line,end_line: Location in sourceis_body: Whether it's a body or specarguments: Parsed parametersconditions: Parsed expressionscases: Case alternatives (forcasestatements)
AST
The main tree structure with methods:
new(): Create from node listbuild(): Construct parent-child relationshipspopulate_cases(): Extractwhenclausespopulate_simple_loop_conditions(): Extractexit whenconditionsfind_node_by_name_and_type(): Search helper
ConditionExpr
Parsed condition with:
list: Flat list of all sub-expressionsalbero: Root of expression tree
๐ Supported Constructs
| Construct | Node Type | Notes |
|---|---|---|
| Package spec/body | PackageNode |
Nested packages supported |
| Procedure spec/body | ProcedureNode |
Generic instantiations |
| Function spec/body | FunctionNode |
Return types parsed |
| Task spec/body | TaskNode |
|
| Entry spec/body | EntryNode |
Guard conditions supported |
| Type declaration | TypeDeclaration |
Records, arrays, derived, enums |
| Subtype | TypeDeclaration |
Category: "subtype" |
| Representation clause | TypeDeclaration |
for...use record, for...use at |
| Variable | VariableDeclaration |
Multiple per line, with defaults |
| If/elsif/else | IfStatement, ElsifStatement, ElseStatement |
|
| Case | CaseStatement |
when clauses extracted |
| Simple loop | SimpleLoop |
exit when parsed |
| While loop | WhileLoop |
Condition parsed |
| For loop | ForLoop |
Range/reverse/discrete types |
| Declare block | DeclareNode |
๐งช Testing
The project includes comprehensive tests:
# Run all tests
# Run with output
# Run specific test
The test suite validates:
- Individual extractors (packages, procedures, loops, etc.)
- Expression parser with complex precedence
- Code cleaning (comments, strings, tabs)
- Full end-to-end parsing of a large Ada file (
blop.ada) - Tree structure verification
๐ฏ Use Cases
- Linting: Check coding standards (naming conventions, documentation, complexity)
- Metrics: Calculate cyclomatic complexity, lines of code, nesting depth
- Refactoring: Identify code smells, unused declarations
- Documentation: Auto-generate interface docs from specs
- Migration: Analyze legacy code for modernization
- Education: Teach Ada syntax and structure
โ๏ธ Architecture
- Regex Extraction: Pattern matching identifies Ada constructs
- Node Creation: Each match becomes a
NodeDatawith metadata - Sorting: Nodes sorted by start position
- Tree Building: Stack-based algorithm establishes parent-child relationships
- End Association: Matches
endstatements to opening blocks - Post-Processing: Populates derived data (cases, conditions)
๐ค Contributing
Contributions are welcome! To contribute:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes with tests
- Run the test suite (
cargo test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please ensure:
- All tests pass
- New features have corresponding tests
- Code follows Rust conventions
- Documentation is updated
๐ License
Licensed under the MIT License. See LICENSE-MIT for details.
๐ค Author
Francesco Abate
- Computer Engineer specializing in software, embedded programming, cybersecurity, and AI
- Currently mastering Rust and seeking opportunities in the field
- Website: https://frontinus.github.io/
- Email: francesco1.abate@yahoo.com
- LinkedIn: Connect with me
๐ Acknowledgments
Built with:
- indextree - Tree data structure
- regex - Pattern matching
- fancy-regex - Advanced regex features
- lazy_static - Static initialization
๐ Further Reading
Note: This is a parser for analysis purposes, not a full Ada compiler. It's designed to be fast and flexible for tooling, but may not handle all edge cases of the Ada language specification.