Crate gramma

Source
Expand description

This library provides macros for defining context-free grammar-ish parsers in terms of Rust types.

§Abstract Syntax Tree

A grammar is defined by the abstract syntax tree (AST) that it produces.

ASTs are made up of two kinds of components:

  • Tokens
  • Rule

§Token

A token (in some contexts called a terminal or symbol) is the basic unit of a grammar. It’s defined by either an exact string match or a regular language.

§Rule

§Example

use gramma::{
    ast::InfixChain,
    define_rule,
    define_token,
    display_tree,
    parse_tree,
};

define_token!(
    #[pattern(exact = "(")]
    pub struct LeftParen;
    #[pattern(exact = ")")]
    pub struct RightParen;
    #[pattern(exact = "[")]
    pub struct LeftBracket;
    #[pattern(exact = "]")]
    pub struct RightBracket;
    #[pattern(exact = "+")]
    pub struct Plus;
    #[pattern(exact = "-")]
    pub struct Minus;
    #[pattern(exact = ",")]
    pub struct Comma;
    #[pattern(regex = r"[a-zA-Z_]\w*")]
    pub struct Ident;
    #[pattern(matcher = ascii_digit().repeat(1..))]
    pub struct Number;
    #[pattern(regex = r"\s*")]
    pub struct Whitespace;
);

define_rule!(
    #[transform(ignore_around<Whitespace>)]
    pub enum BaseExpr {
        Parens {
            l_paren: LeftParen,
            expr: Box<Expr>,
            r_paren: RightParen,
        },
        List {
            l_bracket: LeftBracket,
            #[transform(delimited<Comma>)]
            exprs: Vec<Expr>,
            #[transform(ignore_before<Whitespace>)]
            r_bracket: RightBracket,
        },
        Ident { ident: Ident },
        Number { number: Number },
    }

    #[transform(ignore_around<Whitespace>)]
    pub enum Op {
        Plus { plus: Plus },
        Minus { minus: Minus },
    }

    pub struct Expr {
        binary_ops: InfixChain<BaseExpr, Op>,
    }
);

let src = "
    a - (b + c) + [1, 2]
";

let expr = parse_tree::<Expr, 1>(src).unwrap();
let display = format!("{:#}", display_tree(src, &expr));

assert_eq!(display, r#"Expr -> (
    <Ident "a">,
    { "-", {
        "(",
        Expr -> (
            <Ident "b">,
            { "+", <Ident "c"> },
        ),
        ")",
    } },
    { "+", {
        "[",
        [
            Expr -> <Number "1">,
            Expr -> <Number "2">,
        ],
        "]",
    } },
)"#);

Re-exports§

pub use ast::display_tree;
pub use ast::parse_tree;
pub use ast::Rule;
pub use parse::ParseError;
pub use token::Token;

Modules§

ast
error
parse
string_matcher
This module provides a domain-specific language for defining regular grammars. These can be composed to form token patterns.
token

Macros§

define_rule
Define AST rules by declaring structs and enums.
define_string_pattern
define_token
string_matcher
Creates a StringMatcher from the given StringPattern. Approximately a shorthand for &string_pattern!(pattern).matcher().
string_pattern
Compose a StringPattern. All predefined patterns in the patterns module are brought into scope.