use proc_macro2::{Group, Ident, Literal, Span, TokenStream}; #[derive(Debug)] pub struct Grammar { pub doc: Option, pub visibility: Option, pub name: Ident, pub lifetime_params: Option>, pub args: Vec<(Ident, TokenStream)>, pub items: Vec, pub input_type: TokenStream, } impl Grammar { pub fn iter_rules(&self) -> impl Iterator { self.items.iter().filter_map(|item| match item { Item::Rule(r) => Some(r), _ => None, }) } } #[derive(Debug)] pub enum Item { Use(TokenStream), Rule(Rule), } #[derive(Debug)] pub enum Cache { Simple, Recursive } #[derive(Debug)] pub struct Rule { pub span: Span, pub name: Ident, pub ty_params: Option>, pub params: Vec, pub expr: SpannedExpr, pub ret_type: Option, pub where_clause: Option, pub doc: Option, pub visibility: Option, pub cache: Option, pub no_eof: bool, } #[derive(Debug)] pub struct RuleParam { pub name: Ident, pub ty: RuleParamTy, } #[derive(Debug)] pub enum RuleParamTy { Rust(TokenStream), Rule(TokenStream), } #[derive(Debug, Clone)] pub struct TaggedExpr { pub name: Option, pub expr: SpannedExpr, } #[derive(Debug, Clone)] pub struct SpannedExpr { pub span: Span, pub expr: Expr, } #[derive(Debug, Clone)] pub enum Expr { LiteralExpr(Literal), PatternExpr(Group), RuleExpr(Ident, Vec), MethodExpr(Ident, TokenStream), ChoiceExpr(Vec), OptionalExpr(Box), Repeat { inner: Box, bound: BoundedRepeat, sep: Option> }, PosAssertExpr(Box), NegAssertExpr(Box), ActionExpr(Vec, Option), MatchStrExpr(Box), PositionExpr, QuietExpr(Box), FailExpr(Group), PrecedenceExpr { levels: Vec, }, MarkerExpr(bool), } impl Expr { pub fn at(self, sp: Span) -> SpannedExpr { SpannedExpr { expr: self, span:sp } } } #[derive(Debug, Clone)] pub enum RuleArg { Rust(TokenStream), Peg(SpannedExpr), } #[derive(Debug, Clone)] pub struct PrecedenceLevel { pub operators: Vec, } #[derive(Debug, Clone)] pub struct PrecedenceOperator { pub span: Span, pub elements: Vec, pub action: Group, } #[derive(Debug, Clone)] pub enum BoundedRepeat { None, Plus, Exact(TokenStream), Both(Option, Option), } impl BoundedRepeat { pub fn has_lower_bound(&self) -> bool { match self { BoundedRepeat::None | BoundedRepeat::Both(None, _) => false, BoundedRepeat::Plus | BoundedRepeat::Exact(_) | BoundedRepeat::Both(Some(_), _) => true } } pub fn has_upper_bound(&self) -> bool { match self { BoundedRepeat::None | BoundedRepeat::Plus | BoundedRepeat::Both(_, None) => false, BoundedRepeat::Exact(_) | BoundedRepeat::Both(_, Some(_)) => true } } }