use serde::Serialize;
use crate::span::Span;
use crate::token::BuiltinType;
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct Grammar {
pub name: String,
#[serde(skip)]
pub name_span: Span,
pub items: Vec<GrammarItem>,
#[serde(skip)]
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum GrammarItem {
Token(TokenDecl),
Rule(RuleDecl),
Example(ExampleDecl),
Import(ImportDecl),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct TokenDecl {
pub name: String,
#[serde(skip)]
pub name_span: Span,
pub body: TokenBody,
pub skip: bool,
#[serde(skip)]
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
pub enum TokenBody {
Builtin(BuiltinType),
Literal(String),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct RuleDecl {
pub name: String,
#[serde(skip)]
pub name_span: Span,
pub body: Expr,
#[serde(skip)]
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum Expr {
Alt { alts: Vec<Expr> },
Seq { items: Vec<Expr> },
Match { arms: Vec<Expr> },
Repeat {
min: Option<u64>,
max: Option<u64>,
body: Box<Expr>,
},
Optional { body: Box<Expr> },
Ref {
name: String,
#[serde(skip)]
span: Span,
},
Literal {
value: String,
#[serde(skip)]
span: Span,
},
Group { body: Box<Expr> },
}
impl Expr {
pub fn seq(mut items: Vec<Expr>) -> Self {
match items.len() {
0 => Self::Seq { items },
1 => items.remove(0),
_ => Self::Seq { items },
}
}
pub fn alt(mut alts: Vec<Expr>) -> Self {
match alts.len() {
0 => Self::Alt { alts },
1 => alts.remove(0),
_ => Self::Alt { alts },
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct ExampleDecl {
pub label: Option<String>,
pub input: String,
pub expect: Option<String>,
#[serde(skip)]
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct ImportDecl {
pub path: String,
#[serde(skip)]
pub span: Span,
}