drawlang-syntax 0.1.2

Lexer, parser, lossless syntax tree, and formatter for the drawlang DSL
Documentation
//! Lexer, parser, lossless-enough syntax tree, and formatter for drawlang.
//!
//! Design requirements (see docs/DESIGN.md):
//! - Error recovery: report *all* errors in a file, never stop at the first.
//! - Every token and node carries a span; diagnostics point at exact source.
//! - Statements carry their comments so `drawlang fmt` round-trips them.

pub mod ast;
pub mod diag;
pub mod fmt;
pub mod lexer;
pub mod parser;
pub mod span;

pub use diag::{Diagnostic, Severity};
pub use span::{SourceFile, Span};

pub struct Parsed {
    pub file: ast::File,
    pub diagnostics: Vec<Diagnostic>,
}

impl Parsed {
    pub fn has_errors(&self) -> bool {
        self.diagnostics
            .iter()
            .any(|d| d.severity == Severity::Error)
    }
}

/// Lex + parse. Always returns an AST (possibly partial) plus every
/// diagnostic found, sorted by source position.
pub fn parse_source(src: &str) -> Parsed {
    let lexed = lexer::lex(src);
    let parsed = parser::parse(src, lexed.tokens);
    let mut diagnostics = lexed.diagnostics;
    diagnostics.extend(parsed.diagnostics);
    diagnostics.sort_by_key(|d| {
        (
            d.primary_span().map(|s| s.start).unwrap_or(usize::MAX),
            d.code,
        )
    });
    Parsed {
        file: parsed.file,
        diagnostics,
    }
}