1use serde::Serialize;
4
5use crate::span::Span;
6use crate::token::BuiltinType;
7
8#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
10pub struct Grammar {
11 pub name: String,
12 #[serde(skip)]
13 pub name_span: Span,
14 pub items: Vec<GrammarItem>,
15 #[serde(skip)]
16 pub span: Span,
17}
18
19#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
20#[serde(tag = "kind", rename_all = "snake_case")]
21pub enum GrammarItem {
22 Token(TokenDecl),
23 Rule(RuleDecl),
24 Example(ExampleDecl),
25 Import(ImportDecl),
26}
27
28#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
29pub struct TokenDecl {
30 pub name: String,
31 #[serde(skip)]
32 pub name_span: Span,
33 pub body: TokenBody,
34 pub skip: bool,
35 #[serde(skip)]
36 pub span: Span,
37}
38
39#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
40#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
41pub enum TokenBody {
42 Builtin(BuiltinType),
43 Literal(String),
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
48pub struct RuleDecl {
49 pub name: String,
50 #[serde(skip)]
51 pub name_span: Span,
52 pub body: Expr,
53 #[serde(skip)]
54 pub span: Span,
55}
56
57#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
58#[serde(tag = "kind", rename_all = "snake_case")]
59pub enum Expr {
60 Alt { alts: Vec<Expr> },
62 Seq { items: Vec<Expr> },
64 Match { arms: Vec<Expr> },
66 Repeat {
68 min: Option<u64>,
69 max: Option<u64>,
70 body: Box<Expr>,
71 },
72 Optional { body: Box<Expr> },
74 Ref {
76 name: String,
77 #[serde(skip)]
78 span: Span,
79 },
80 Literal {
82 value: String,
83 #[serde(skip)]
84 span: Span,
85 },
86 Group { body: Box<Expr> },
87}
88
89impl Expr {
90 pub fn seq(mut items: Vec<Expr>) -> Self {
91 match items.len() {
92 0 => Self::Seq { items },
93 1 => items.remove(0),
94 _ => Self::Seq { items },
95 }
96 }
97
98 pub fn alt(mut alts: Vec<Expr>) -> Self {
99 match alts.len() {
100 0 => Self::Alt { alts },
101 1 => alts.remove(0),
102 _ => Self::Alt { alts },
103 }
104 }
105}
106
107#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
108pub struct ExampleDecl {
109 pub label: Option<String>,
110 pub input: String,
111 pub expect: Option<String>,
112 #[serde(skip)]
113 pub span: Span,
114}
115
116#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
117pub struct ImportDecl {
118 pub path: String,
119 #[serde(skip)]
120 pub span: Span,
121}