oxilean_parse/tactic_parser/
tacticparser_parsing.rs1use crate::{ParseError, ParseErrorKind, Span, Token, TokenKind};
8
9use super::types::{CalcStep, CaseArm, ConvSide, RewriteRule, TacticExpr};
10
11use super::tacticparser_type::TacticParser;
12
13impl<'a> TacticParser<'a> {
14 pub fn new(tokens: &'a [Token]) -> Self {
16 Self { tokens, pos: 0 }
17 }
18 pub fn parse_by_block(&mut self) -> Result<TacticExpr, ParseError> {
20 if !self.check_keyword("by") {
21 return Err(ParseError::new(
22 ParseErrorKind::InvalidSyntax("expected 'by'".to_string()),
23 self.current_span(),
24 ));
25 }
26 self.advance();
27 if self.check_op("{") {
28 self.parse_brace_block()
29 } else {
30 self.parse_seq()
31 }
32 }
33 pub(super) fn parse_seq(&mut self) -> Result<TacticExpr, ParseError> {
34 let mut left = self.parse_all_goals()?;
35 while self.check_op(";") {
36 self.advance();
37 let right = self.parse_all_goals()?;
38 left = TacticExpr::Seq(Box::new(left), Box::new(right));
39 }
40 Ok(left)
41 }
42 #[allow(dead_code)]
43 pub(super) fn parse_all_goals(&mut self) -> Result<TacticExpr, ParseError> {
44 let mut left = self.parse_alt()?;
45 while self.check_op("<;>") {
46 self.advance();
47 let right = self.parse_alt()?;
48 left = TacticExpr::AllGoals(Box::new(left), Box::new(right));
49 }
50 Ok(left)
51 }
52 pub(super) fn parse_alt(&mut self) -> Result<TacticExpr, ParseError> {
53 let mut left = self.parse_primary()?;
54 while self.check_op("<|>") {
55 self.advance();
56 let right = self.parse_primary()?;
57 left = TacticExpr::Alt(Box::new(left), Box::new(right));
58 }
59 Ok(left)
60 }
61 pub(super) fn parse_primary(&mut self) -> Result<TacticExpr, ParseError> {
62 if self.check_op("{") {
63 return self.parse_brace_block();
64 }
65 if self.check_keyword("repeat") {
66 self.advance();
67 let inner = self.parse_primary()?;
68 return Ok(TacticExpr::Repeat(Box::new(inner)));
69 }
70 if self.check_keyword("try") {
71 self.advance();
72 let inner = self.parse_primary()?;
73 return Ok(TacticExpr::Try(Box::new(inner)));
74 }
75 if self.check_keyword("focus") {
76 self.advance();
77 let n = self.expect_nat()?;
78 let inner = self.parse_primary()?;
79 return Ok(TacticExpr::Focus(n, Box::new(inner)));
80 }
81 if self.check_keyword("all") {
82 self.advance();
83 let inner = self.parse_primary()?;
84 return Ok(TacticExpr::All(Box::new(inner)));
85 }
86 if self.check_keyword("any") {
87 self.advance();
88 let inner = self.parse_primary()?;
89 return Ok(TacticExpr::Any(Box::new(inner)));
90 }
91 if self.check_keyword("intro") {
92 return self.parse_intro();
93 }
94 if self.check_keyword("intros") {
95 return self.parse_intros();
96 }
97 if self.check_keyword("apply") {
98 return self.parse_apply();
99 }
100 if self.check_keyword("exact") {
101 return self.parse_exact();
102 }
103 if self.check_keyword("generalize") {
104 return self.parse_generalize();
105 }
106 if self.check_keyword("obtain") {
107 return self.parse_obtain();
108 }
109 if self.check_keyword("rcases") {
110 return self.parse_rcases();
111 }
112 if self.check_keyword("first") {
113 return self.parse_first();
114 }
115 if self.check_keyword("tauto") {
116 return self.parse_tauto();
117 }
118 if self.check_keyword("ac_rfl") {
119 return self.parse_ac_rfl();
120 }
121 if self.check_keyword("rewrite") || self.check_keyword("rw") {
122 return self.parse_rewrite();
123 }
124 if self.check_keyword("simp") {
125 return self.parse_simp();
126 }
127 if self.check_keyword("cases") {
128 return self.parse_cases();
129 }
130 if self.check_keyword("induction") {
131 return self.parse_induction();
132 }
133 if self.check_keyword("have") {
134 return self.parse_have();
135 }
136 if self.check_keyword("let") {
137 return self.parse_let();
138 }
139 if self.check_keyword("show") {
140 return self.parse_show();
141 }
142 if self.check_keyword("suffices") {
143 return self.parse_suffices();
144 }
145 if self.check_keyword("calc") {
146 return self.parse_calc();
147 }
148 if self.check_keyword("conv_lhs") {
149 self.advance();
150 self.expect_op("=>")?;
151 let inner = self.parse_primary()?;
152 return Ok(TacticExpr::Conv(ConvSide::Lhs, Box::new(inner)));
153 }
154 if self.check_keyword("conv_rhs") {
155 self.advance();
156 self.expect_op("=>")?;
157 let inner = self.parse_primary()?;
158 return Ok(TacticExpr::Conv(ConvSide::Rhs, Box::new(inner)));
159 }
160 if self.check_keyword("conv") {
161 return self.parse_conv();
162 }
163 if self.check_keyword("omega") {
164 self.advance();
165 return Ok(TacticExpr::Omega);
166 }
167 if self.check_keyword("ring") {
168 self.advance();
169 return Ok(TacticExpr::Ring);
170 }
171 if self.check_keyword("decide") {
172 self.advance();
173 return Ok(TacticExpr::Decide);
174 }
175 if self.check_keyword("norm_num") {
176 self.advance();
177 return Ok(TacticExpr::NormNum);
178 }
179 if self.check_keyword("constructor") {
180 self.advance();
181 return Ok(TacticExpr::Constructor);
182 }
183 if self.check_keyword("left") {
184 self.advance();
185 return Ok(TacticExpr::Left);
186 }
187 if self.check_keyword("right") {
188 self.advance();
189 return Ok(TacticExpr::Right);
190 }
191 if self.check_keyword("existsi") || self.check_keyword("use") {
192 return self.parse_existsi();
193 }
194 if self.check_keyword("clear") {
195 return self.parse_clear();
196 }
197 if self.check_keyword("revert") {
198 return self.parse_revert();
199 }
200 if self.check_keyword("subst") {
201 return self.parse_subst();
202 }
203 if self.check_keyword("contradiction") {
204 self.advance();
205 return Ok(TacticExpr::Contradiction);
206 }
207 if self.check_keyword("exfalso") {
208 self.advance();
209 return Ok(TacticExpr::Exfalso);
210 }
211 if self.check_keyword("by_contra") {
212 return self.parse_by_contra();
213 }
214 if self.check_keyword("assumption") {
215 self.advance();
216 return Ok(TacticExpr::Assumption);
217 }
218 if self.check_keyword("trivial") {
219 self.advance();
220 return Ok(TacticExpr::Trivial);
221 }
222 if self.check_keyword("rfl") {
223 self.advance();
224 return Ok(TacticExpr::Rfl);
225 }
226 let name = self.expect_ident()?;
227 if self.check_op("(") {
228 self.advance();
229 let mut args = Vec::new();
230 while !self.check_op(")") {
231 args.push(self.expect_ident()?);
232 if !self.check_op(",") {
233 break;
234 }
235 self.advance();
236 }
237 self.expect_op(")")?;
238 Ok(TacticExpr::WithArgs(name, args))
239 } else {
240 Ok(TacticExpr::Basic(name))
241 }
242 }
243 pub(super) fn parse_intro(&mut self) -> Result<TacticExpr, ParseError> {
245 self.advance();
246 let mut names = Vec::new();
247 while let Some(token) = self.current() {
248 match &token.kind {
249 TokenKind::Ident(s) if !self.is_tactic_terminator(s) => {
250 names.push(s.clone());
251 self.advance();
252 }
253 TokenKind::Underscore => {
254 names.push("_".to_string());
255 self.advance();
256 }
257 _ => break,
258 }
259 }
260 Ok(TacticExpr::Intro(names))
261 }
262 pub(super) fn parse_rewrite_args(&mut self) -> Result<Vec<RewriteRule>, ParseError> {
264 self.expect_op("[")?;
265 let mut rules = Vec::new();
266 if self.check_op("]") {
267 self.advance();
268 return Ok(rules);
269 }
270 loop {
271 let reverse = if self.check_op("<-") {
272 self.advance();
273 true
274 } else {
275 false
276 };
277 let lemma = self.expect_ident()?;
278 rules.push(RewriteRule { lemma, reverse });
279 if !self.check_op(",") {
280 break;
281 }
282 self.advance();
283 }
284 self.expect_op("]")?;
285 Ok(rules)
286 }
287 pub(super) fn parse_simp_lemma_list(&mut self) -> Result<Vec<String>, ParseError> {
289 if !self.check_op("[") {
290 return Ok(Vec::new());
291 }
292 self.advance();
293 let mut lemmas = Vec::new();
294 if self.check_op("]") {
295 self.advance();
296 return Ok(lemmas);
297 }
298 loop {
299 if self.check_op("*") {
300 lemmas.push("*".to_string());
301 self.advance();
302 } else if self.check_op("-") {
303 self.advance();
304 let name = self.expect_ident()?;
305 lemmas.push(format!("-{}", name));
306 } else {
307 let name = self.expect_ident()?;
308 lemmas.push(name);
309 }
310 if !self.check_op(",") {
311 break;
312 }
313 self.advance();
314 }
315 self.expect_op("]")?;
316 Ok(lemmas)
317 }
318 pub(super) fn parse_simp_config(&mut self) -> Result<Vec<(String, String)>, ParseError> {
320 if !self.check_op("{") {
321 return Ok(Vec::new());
322 }
323 self.advance();
324 let mut config = Vec::new();
325 if self.check_op("}") {
326 self.advance();
327 return Ok(config);
328 }
329 loop {
330 let key = self.expect_ident()?;
331 self.expect_op(":=")?;
332 let val = self.expect_ident()?;
333 config.push((key, val));
334 if !self.check_op(",") {
335 break;
336 }
337 self.advance();
338 }
339 self.expect_op("}")?;
340 Ok(config)
341 }
342 pub(super) fn parse_cases(&mut self) -> Result<TacticExpr, ParseError> {
344 self.advance();
345 let target = self.expect_ident()?;
346 let arms = if self.check_keyword("with") {
347 self.advance();
348 self.parse_case_arms()?
349 } else {
350 Vec::new()
351 };
352 Ok(TacticExpr::Cases(target, arms))
353 }
354 pub(super) fn parse_induction(&mut self) -> Result<TacticExpr, ParseError> {
356 self.advance();
357 let target = self.expect_ident()?;
358 let arms = if self.check_keyword("with") {
359 self.advance();
360 self.parse_case_arms()?
361 } else {
362 Vec::new()
363 };
364 Ok(TacticExpr::Induction(target, arms))
365 }
366 pub(super) fn parse_case_arms(&mut self) -> Result<Vec<CaseArm>, ParseError> {
368 let mut arms = Vec::new();
369 while self.check_op("|") {
370 self.advance();
371 let name = self.expect_ident()?;
372 let mut bindings = Vec::new();
373 while !self.check_op("=>") && !self.at_end() {
374 if let Some(token) = self.current() {
375 if let TokenKind::Ident(s) = &token.kind {
376 bindings.push(s.clone());
377 self.advance();
378 } else if token.kind == TokenKind::Underscore {
379 bindings.push("_".to_string());
380 self.advance();
381 } else {
382 break;
383 }
384 } else {
385 break;
386 }
387 }
388 self.expect_op("=>")?;
389 let tactic = self.parse_seq()?;
390 arms.push(CaseArm {
391 name,
392 bindings,
393 tactic,
394 });
395 }
396 Ok(arms)
397 }
398 pub(super) fn parse_have(&mut self) -> Result<TacticExpr, ParseError> {
400 self.advance();
401 let name = self.expect_ident()?;
402 let ty = if self.check_op(":") {
403 self.advance();
404 let t = self.expect_ident()?;
405 Some(t)
406 } else {
407 None
408 };
409 if self.check_op(":=") {
410 self.advance();
411 }
412 let body = if self.check_keyword("by") {
413 self.parse_by_block()?
414 } else {
415 self.parse_primary()?
416 };
417 Ok(TacticExpr::Have(name, ty, Box::new(body)))
418 }
419 pub(super) fn parse_suffices(&mut self) -> Result<TacticExpr, ParseError> {
421 self.advance();
422 let name = self.expect_ident()?;
423 if self.check_op(":") {
424 self.advance();
425 let _ty = self.expect_ident()?;
426 }
427 let body = if self.check_keyword("by") {
428 self.parse_by_block()?
429 } else {
430 self.parse_primary()?
431 };
432 Ok(TacticExpr::Suffices(name, Box::new(body)))
433 }
434 pub(super) fn parse_calc_steps(&mut self) -> Result<Vec<CalcStep>, ParseError> {
436 let mut steps = Vec::new();
437 while self.check_op("_") || self.check_keyword("_") {
438 self.advance();
439 let relation = self.expect_ident()?;
440 let rhs = self.expect_ident()?;
441 self.expect_op(":=")?;
442 let justification = if self.check_keyword("by") {
443 self.parse_by_block()?
444 } else {
445 self.parse_primary()?
446 };
447 steps.push(CalcStep {
448 relation,
449 rhs,
450 justification,
451 });
452 }
453 Ok(steps)
454 }
455 pub(super) fn parse_conv(&mut self) -> Result<TacticExpr, ParseError> {
457 self.advance();
458 let side = if self.check_keyword("lhs") {
459 self.advance();
460 ConvSide::Lhs
461 } else if self.check_keyword("rhs") {
462 self.advance();
463 ConvSide::Rhs
464 } else {
465 ConvSide::Lhs
466 };
467 self.expect_op("=>")?;
468 let inner = self.parse_primary()?;
469 Ok(TacticExpr::Conv(side, Box::new(inner)))
470 }
471 #[allow(dead_code)]
473 pub(super) fn parse_first(&mut self) -> Result<TacticExpr, ParseError> {
474 self.advance();
475 let mut tactics = Vec::new();
476 while self.check_op("|") {
477 self.advance();
478 tactics.push(self.parse_primary()?);
479 }
480 if tactics.is_empty() {
481 tactics.push(self.parse_primary()?);
482 }
483 Ok(TacticExpr::First(tactics))
484 }
485 #[allow(dead_code)]
487 pub(super) fn parse_intros(&mut self) -> Result<TacticExpr, ParseError> {
488 self.advance();
489 let mut names = Vec::new();
490 while let Some(token) = self.current() {
491 match &token.kind {
492 TokenKind::Ident(s) if !self.is_tactic_terminator(s) => {
493 names.push(s.clone());
494 self.advance();
495 }
496 TokenKind::Underscore => {
497 names.push("_".to_string());
498 self.advance();
499 }
500 _ => break,
501 }
502 }
503 Ok(TacticExpr::Intros(names))
504 }
505 #[allow(dead_code)]
507 pub(super) fn parse_obtain(&mut self) -> Result<TacticExpr, ParseError> {
508 self.advance();
509 let name = self.expect_ident()?;
510 let body = if self.check_op(",") || self.check_op("=>") {
511 self.advance();
512 self.parse_primary()?
513 } else {
514 self.parse_primary()?
515 };
516 Ok(TacticExpr::Obtain(name, Box::new(body)))
517 }
518 #[allow(dead_code)]
520 pub(super) fn parse_rcases(&mut self) -> Result<TacticExpr, ParseError> {
521 self.advance();
522 let target = self.expect_ident()?;
523 let mut patterns = Vec::new();
524 if self.check_keyword("with") {
525 self.advance();
526 while self.check_op("|") {
527 self.advance();
528 let pat = self.expect_ident()?;
529 patterns.push(pat);
530 if self.check_op("=>") {
531 self.advance();
532 let _ = self.parse_primary();
533 }
534 }
535 }
536 Ok(TacticExpr::Rcases(target, patterns))
537 }
538 pub(super) fn parse_brace_block(&mut self) -> Result<TacticExpr, ParseError> {
540 self.expect_op("{")?;
541 let mut tactics = Vec::new();
542 while !self.check_op("}") && !self.at_end() {
543 let t = self.parse_seq()?;
544 tactics.push(t);
545 let _ = self.consume_op(";");
546 }
547 self.expect_op("}")?;
548 Ok(TacticExpr::Block(tactics))
549 }
550 pub(super) fn parse_ident_list(&mut self) -> Result<Vec<String>, ParseError> {
552 let mut names = Vec::new();
553 while let Some(token) = self.current() {
554 if let TokenKind::Ident(s) = &token.kind {
555 if self.is_tactic_terminator(s) {
556 break;
557 }
558 names.push(s.clone());
559 self.advance();
560 } else {
561 break;
562 }
563 }
564 Ok(names)
565 }
566 pub(super) fn expect_ident(&mut self) -> Result<String, ParseError> {
567 if let Some(token) = self.current() {
568 if let TokenKind::Ident(s) = &token.kind {
569 let result = s.clone();
570 self.advance();
571 return Ok(result);
572 }
573 }
574 Err(ParseError::new(
575 ParseErrorKind::InvalidSyntax("expected identifier".to_string()),
576 self.current_span(),
577 ))
578 }
579 pub(super) fn expect_nat(&mut self) -> Result<usize, ParseError> {
580 if let Some(token) = self.current() {
581 if let TokenKind::Nat(n) = &token.kind {
582 let result = *n as usize;
583 self.advance();
584 return Ok(result);
585 }
586 }
587 Err(ParseError::new(
588 ParseErrorKind::InvalidSyntax("expected number".to_string()),
589 self.current_span(),
590 ))
591 }
592 pub(super) fn expect_op(&mut self, op: &str) -> Result<(), ParseError> {
593 if self.check_op(op) {
594 self.advance();
595 Ok(())
596 } else {
597 Err(ParseError::new(
598 ParseErrorKind::InvalidSyntax(format!("expected '{}'", op)),
599 self.current_span(),
600 ))
601 }
602 }
603 pub(super) fn current_span(&self) -> Span {
604 if let Some(token) = self.current() {
605 token.span.clone()
606 } else {
607 Span::new(0, 0, 0, 0)
608 }
609 }
610}