palladium/macros/
parser.rs1use crate::errors::{CompileError, Result};
5use crate::lexer::Token;
6
7#[derive(Debug, Clone, PartialEq)]
9pub enum PatternElement {
10 Literal(Token),
12 Variable { name: String, kind: CaptureKind },
14 Repetition {
16 pattern: Vec<PatternElement>,
17 separator: Option<Token>,
18 kind: RepetitionKind,
19 },
20}
21
22#[derive(Debug, Clone, PartialEq)]
24pub enum CaptureKind {
25 Expr,
27 Stmt,
29 Type,
31 Pat,
33 Ident,
35 Lit,
37 Tt,
39}
40
41#[derive(Debug, Clone, PartialEq)]
43pub enum RepetitionKind {
44 ZeroOrMore,
46 OneOrMore,
48 ZeroOrOne,
50}
51
52pub struct PatternParser {
54 tokens: Vec<Token>,
55 pos: usize,
56}
57
58impl PatternParser {
59 pub fn new(tokens: Vec<Token>) -> Self {
60 Self { tokens, pos: 0 }
61 }
62
63 pub fn parse_pattern(&mut self) -> Result<Vec<PatternElement>> {
65 let mut elements = Vec::new();
66
67 while !self.is_at_end() {
68 elements.push(self.parse_element()?);
69 }
70
71 Ok(elements)
72 }
73
74 fn parse_element(&mut self) -> Result<PatternElement> {
76 if self.check_token(&Token::Dollar) {
77 self.parse_capture_or_repetition()
78 } else {
79 let token = self.advance()?;
81 Ok(PatternElement::Literal(token))
82 }
83 }
84
85 fn parse_capture_or_repetition(&mut self) -> Result<PatternElement> {
87 self.consume(Token::Dollar)?;
88
89 if self.check_token(&Token::LeftParen) {
90 self.parse_repetition()
92 } else {
93 self.parse_capture()
95 }
96 }
97
98 fn parse_capture(&mut self) -> Result<PatternElement> {
100 let name = self.expect_ident()?;
101 self.consume(Token::Colon)?;
102 let kind = self.parse_capture_kind()?;
103
104 Ok(PatternElement::Variable { name, kind })
105 }
106
107 fn parse_capture_kind(&mut self) -> Result<CaptureKind> {
109 let kind_name = self.expect_ident()?;
110
111 match kind_name.as_str() {
112 "expr" => Ok(CaptureKind::Expr),
113 "stmt" => Ok(CaptureKind::Stmt),
114 "type" => Ok(CaptureKind::Type),
115 "pat" => Ok(CaptureKind::Pat),
116 "ident" => Ok(CaptureKind::Ident),
117 "lit" => Ok(CaptureKind::Lit),
118 "tt" => Ok(CaptureKind::Tt),
119 _ => Err(CompileError::Generic(format!(
120 "Unknown capture kind: {}",
121 kind_name
122 ))),
123 }
124 }
125
126 fn parse_repetition(&mut self) -> Result<PatternElement> {
128 self.consume(Token::LeftParen)?;
129
130 let mut pattern = Vec::new();
132 while !self.check_token(&Token::RightParen) {
133 pattern.push(self.parse_element()?);
134 }
135
136 self.consume(Token::RightParen)?;
137
138 let separator = if self.check_token(&Token::Comma) || self.check_token(&Token::Semicolon) {
140 Some(self.advance()?)
141 } else {
142 None
143 };
144
145 let kind = if self.check_token(&Token::Star) {
147 self.advance()?;
148 RepetitionKind::ZeroOrMore
149 } else if self.check_token(&Token::Plus) {
150 self.advance()?;
151 RepetitionKind::OneOrMore
152 } else if self.check_token(&Token::Question) {
153 self.advance()?;
154 RepetitionKind::ZeroOrOne
155 } else {
156 return Err(CompileError::Generic(
157 "Expected repetition operator (*, +, or ?)".to_string(),
158 ));
159 };
160
161 Ok(PatternElement::Repetition {
162 pattern,
163 separator,
164 kind,
165 })
166 }
167
168 fn is_at_end(&self) -> bool {
170 self.pos >= self.tokens.len()
171 }
172
173 fn check_token(&self, expected: &Token) -> bool {
175 if self.is_at_end() {
176 false
177 } else {
178 std::mem::discriminant(&self.tokens[self.pos]) == std::mem::discriminant(expected)
179 }
180 }
181
182 fn consume(&mut self, expected: Token) -> Result<()> {
184 if self.check_token(&expected) {
185 self.advance()?;
186 Ok(())
187 } else {
188 Err(CompileError::Generic(format!(
189 "Expected {:?}, found {:?}",
190 expected,
191 self.current()
192 )))
193 }
194 }
195
196 fn advance(&mut self) -> Result<Token> {
198 if self.is_at_end() {
199 Err(CompileError::Generic("Unexpected end of input".to_string()))
200 } else {
201 let token = self.tokens[self.pos].clone();
202 self.pos += 1;
203 Ok(token)
204 }
205 }
206
207 fn current(&self) -> Option<&Token> {
209 if self.is_at_end() {
210 None
211 } else {
212 Some(&self.tokens[self.pos])
213 }
214 }
215
216 fn expect_ident(&mut self) -> Result<String> {
218 match self.advance()? {
219 Token::Identifier(name) => Ok(name),
220 other => Err(CompileError::Generic(format!(
221 "Expected identifier, found {:?}",
222 other
223 ))),
224 }
225 }
226}