metrale_grammar/grammar/
parser.rs1use super::builder::{BuilderError, GrammarBuilder};
17use super::data::GrammarData;
18use super::lexer::{EbnfLexer, LexError, Token, TokenType, TokenValue};
19
20#[path = "parser_element.rs"]
21mod element;
22#[path = "parser_macro.rs"]
23mod macros;
24#[path = "parser_quant.rs"]
25mod quant;
26#[path = "parser_repeat.rs"]
27mod repeat;
28#[path = "parser_tagdispatch.rs"]
29mod tagdispatch;
30#[cfg(test)]
31#[path = "parser_tests.rs"]
32mod tests;
33
34pub(super) const MAX_NEST_LAYER: i32 = 1000;
36
37#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
39pub enum ParseError {
40 #[error(transparent)]
42 Lex(#[from] LexError),
43 #[error("EBNF parser error at line {line}, column {column}: {msg}")]
45 Parse {
46 line: i32,
48 column: i32,
50 msg: String,
52 },
53 #[error(transparent)]
55 Builder(#[from] BuilderError),
56}
57
58pub(super) struct EbnfParser {
60 pub(super) builder: GrammarBuilder,
61 pub(super) tokens: Vec<Token>,
62 pub(super) cur: usize,
64 pub(super) cur_rule_name: String,
65 pub(super) root_rule_name: String,
66 pub(super) nest_layer_guard: i32,
67}
68
69impl EbnfParser {
70 pub(super) fn peek(&self, delta: i32) -> &Token {
73 let idx = (self.cur as i32 + delta).clamp(0, self.tokens.len() as i32 - 1) as usize;
74 &self.tokens[idx]
75 }
76
77 pub(super) fn consume(&mut self, cnt: usize) {
79 self.cur = (self.cur + cnt).min(self.tokens.len() - 1);
80 }
81
82 pub(super) fn peek_and_consume(
84 &mut self,
85 ty: TokenType,
86 message: &str,
87 ) -> Result<(), ParseError> {
88 if self.peek(0).ty != ty {
89 return Err(self.parse_error(message, 0));
90 }
91 self.consume(1);
92 Ok(())
93 }
94
95 pub(super) fn parse_error(&self, msg: &str, delta_element: i32) -> ParseError {
97 let t = self.peek(delta_element);
98 ParseError::Parse {
99 line: t.line,
100 column: t.column,
101 msg: msg.to_string(),
102 }
103 }
104
105 fn parse_sequence(&mut self) -> Result<i32, ParseError> {
107 let mut elements: Vec<i32> = Vec::new();
108 loop {
109 elements.push(self.parse_element_with_quantifier()?);
110 if matches!(
111 self.peek(0).ty,
112 TokenType::Pipe
113 | TokenType::RParen
114 | TokenType::LookaheadLParen
115 | TokenType::RuleName
116 | TokenType::EndOfFile
117 ) {
118 break;
119 }
120 }
121 Ok(self.builder.add_sequence(&elements))
122 }
123
124 pub(super) fn parse_choices(&mut self) -> Result<i32, ParseError> {
126 let mut choices: Vec<i32> = vec![self.parse_sequence()?];
127 while self.peek(0).ty == TokenType::Pipe {
128 self.consume(1);
129 choices.push(self.parse_sequence()?);
130 }
131 Ok(self.builder.add_choices(&choices))
132 }
133
134 fn parse_lookahead_assertion(&mut self) -> Result<i32, ParseError> {
136 self.peek_and_consume(
137 TokenType::LookaheadLParen,
138 "Expect (= in lookahead assertion",
139 )?;
140 let result = self.parse_choices()?;
141 self.peek_and_consume(TokenType::RParen, "Expect )")?;
142 Ok(result)
143 }
144
145 fn parse_rule(&mut self) -> Result<(String, i32, i32), ParseError> {
147 if self.peek(0).ty != TokenType::RuleName {
148 return Err(self.parse_error("Expect rule name", 0));
149 }
150 self.cur_rule_name = match &self.peek(0).value {
151 TokenValue::Str(s) => s.clone(),
152 _ => return Err(self.parse_error("Expect rule name", 0)),
153 };
154 self.consume(1);
155 self.peek_and_consume(TokenType::Assign, "Expect ::=")?;
156 let body_id = self.parse_choices()?;
157 let mut lookahead_id = -1;
158 if self.peek(0).ty == TokenType::LookaheadLParen {
159 lookahead_id = self.parse_lookahead_assertion()?;
160 }
161 Ok((self.cur_rule_name.clone(), body_id, lookahead_id))
162 }
163
164 fn init_rule_names(&mut self) -> Result<(), ParseError> {
167 for delta in 0..self.tokens.len() {
168 if self.tokens[delta].ty != TokenType::RuleName {
169 continue;
170 }
171 let name = match &self.tokens[delta].value {
172 TokenValue::Str(s) => s.clone(),
173 _ => continue,
174 };
175 if self.builder.get_rule_id(&name) != -1 {
176 let t = &self.tokens[delta];
177 return Err(ParseError::Parse {
178 line: t.line,
179 column: t.column,
180 msg: format!("Rule \"{name}\" is defined multiple times"),
181 });
182 }
183 self.builder.add_empty_rule(name)?;
184 }
185 if self.builder.get_rule_id(&self.root_rule_name) == -1 {
186 return Err(self.parse_error(
187 &format!(
188 "The root rule with name \"{}\" is not found",
189 self.root_rule_name
190 ),
191 0,
192 ));
193 }
194 Ok(())
195 }
196
197 fn parse(mut self) -> Result<GrammarData, ParseError> {
199 self.init_rule_names()?;
200 while self.peek(0).ty != TokenType::EndOfFile {
201 let (name, body_id, lookahead_id) = self.parse_rule()?;
202 self.builder.update_rule_body_named(&name, body_id)?;
203 self.builder
204 .update_lookahead_assertion_named(&name, lookahead_id)?;
205 }
206 let root = self.root_rule_name.clone();
207 Ok(self.builder.get(&root)?)
208 }
209}
210
211pub fn parse_ebnf(ebnf_string: &str, root_rule_name: &str) -> Result<GrammarData, ParseError> {
217 let tokens = EbnfLexer::tokenize(ebnf_string)?;
218 let parser = EbnfParser {
219 builder: GrammarBuilder::new(),
220 tokens,
221 cur: 0,
222 cur_rule_name: String::new(),
223 root_rule_name: root_rule_name.to_string(),
224 nest_layer_guard: 0,
225 };
226 parser.parse()
227}
228
229pub fn parse_ebnf_default(ebnf_string: &str) -> Result<GrammarData, ParseError> {
231 parse_ebnf(ebnf_string, "root")
232}