Skip to main content

badness_parser/bib/
syntax.rs

1//! `SyntaxKind` — the kinds of CST tokens and nodes — and the rowan `Language`
2//! binding for badness's BibTeX/BibLaTeX surface CST.
3//!
4//! BibTeX is a distinct grammar from LaTeX, so it carries its own kind set and
5//! [`Language`] marker rather than reusing [`crate::syntax`]. The structure
6//! deliberately mirrors that module (`#[repr(u16)]`, tokens first, nodes after,
7//! `ROOT` last + `COUNT`) so the two stay easy to compare.
8
9/// Kinds of tokens (terminals, from the lexer) and nodes (composites, from the
10/// parser) in the BibTeX CST.
11///
12/// Token kinds come first, node kinds after; `ROOT` is kept **last** so
13/// [`rowan::Language::kind_from_raw`] can bounds-check the raw discriminant with
14/// a single comparison. Keep the hidden end marker immediately after `ROOT`.
15#[allow(non_camel_case_types)]
16#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
17#[repr(u16)]
18pub enum SyntaxKind {
19    // --- Tokens (terminals, produced by the lexer) ---
20    AT,         // @
21    L_BRACE,    // {
22    R_BRACE,    // }
23    L_PAREN,    // (
24    R_PAREN,    // )
25    COMMA,      // ,
26    EQ,         // =
27    HASH,       // #  (value concatenation)
28    QUOTE,      // "
29    PERCENT,    // %  (opens a comment only where the grammar says so)
30    WORD,       // a run of identifier / value characters
31    NUMBER,     // a pure-digit run (kept distinct from a macro name)
32    WHITESPACE, // spaces / tabs
33    NEWLINE,    // `\n`, `\r\n`, or `\r`
34    ERROR,      // lexer fallback; the lexer is total, so this is unused today
35
36    // --- Nodes (composites, produced by the parser) ---
37    COMMENT,        // `%` … end of line, where a comment is legal (see grammar)
38    JUNK,           // free text between entries (BibTeX ignores it)
39    ENTRY,          // a regular bibliographic entry: @type{ key, fields }
40    STRING_ENTRY,   // @string{ name = value }
41    PREAMBLE_ENTRY, // @preamble{ value }
42    COMMENT_ENTRY,  // @comment{ … }
43    ENTRY_TYPE,     // the type word following `@`
44    KEY,            // the cite key
45    FIELD,          // name = value
46    FIELD_NAME,     // the field / macro name on the left of `=`
47    VALUE,          // the right-hand side; value pieces separated by `#`
48    BRACE_GROUP,    // { … }  (recursive: may nest BRACE_GROUP)
49    QUOTED,         // " … "  (may contain nested BRACE_GROUP)
50    LITERAL,        // a bare word / number value piece (macro ref or number)
51    ROOT,           // the file root  (keep LAST)
52    #[doc(hidden)]
53    __LAST,
54}
55
56impl SyntaxKind {
57    /// The number of `SyntaxKind` variants. Sound because the enum is
58    /// `#[repr(u16)]` with contiguous discriminants `0..=ROOT` and `ROOT` is kept
59    /// last; used to size kind-indexed tables.
60    pub const COUNT: usize = SyntaxKind::__LAST as usize;
61}
62
63/// The rowan language marker for badness's BibTeX CST.
64#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
65pub enum BibLang {}
66
67impl_rowan_lang!(BibLang, SyntaxKind, "BibTeX");
68
69pub type SyntaxNode = rowan::SyntaxNode<BibLang>;
70pub type SyntaxToken = rowan::SyntaxToken<BibLang>;
71pub type SyntaxElement = rowan::SyntaxElement<BibLang>;