Skip to main content

Module parser

Module parser 

Source
Expand description

Core parser implementation for Perl source. Recursive descent Perl parser.

Consumes tokens from perl-lexer and produces AST nodes with error recovery. The parser handles operator precedence, quote-like operators, and heredocs, while tracking recursion depth to prevent stack overflows on malformed input.

§IDE-Friendly Error Recovery

This parser uses an IDE-friendly error recovery model:

  • Returns Ok(ast) with ERROR nodes for most parse failures (recovered errors)
  • Returns Err only for catastrophic failures (recursion limits, etc.)

This means result.is_err() is not the correct way to check for parse errors. Instead, check for ERROR nodes in the AST or use parser.errors():

let mut parser = Parser::new(code);
match parser.parse() {
    Err(_) => println!("Catastrophic parse failure"),
    Ok(ast) => {
        // Check for recovered errors via ERROR nodes
        if ast.to_sexp().contains("ERROR") {
            println!("Parse errors recovered: {:?}", parser.errors());
        }
    }
}

§Why IDE-Friendly?

Traditional compilers return Err on any syntax error. This prevents:

  • Code completion in incomplete code
  • Go-to-definition while typing
  • Hover information in files with errors

By returning partial ASTs with ERROR nodes, editors can provide useful features even when code is incomplete or contains errors.

§Performance

  • Time complexity: O(n) for typical token streams
  • Space complexity: O(n) for AST storage with bounded recursion memory usage
  • Optimizations: Fast-path parsing and efficient recovery to maintain performance
  • Benchmarks: ~150µs–1ms for typical files; low ms for large file inputs
  • Large-scale notes: Tuned to scale for large workspaces (50GB PST-style scans)

§Usage

use perl_parser_core::Parser;

let mut parser = Parser::new("my $var = 42; sub hello { print $var; }");
let ast = parser.parse();

Structs§

Parser
Parser state for a single Perl source input.