|
89 | 89 | //! ); |
90 | 90 | //! ``` |
91 | 91 |
|
| 92 | +use typle::typle; |
| 93 | + |
92 | 94 | use super::*; |
93 | 95 |
|
94 | 96 | trait Operator<'a, I, O, E> |
@@ -404,117 +406,124 @@ pub struct Pratt<Atom, Ops> { |
404 | 406 | pub(crate) ops: Ops, |
405 | 407 | } |
406 | 408 |
|
407 | | -macro_rules! impl_pratt_for_tuple { |
408 | | - () => {}; |
409 | | - ($head:ident $($X:ident)*) => { |
410 | | - impl_pratt_for_tuple!($($X)*); |
411 | | - impl_pratt_for_tuple!(~ $head $($X)*); |
412 | | - }; |
413 | | - (~ $($X:ident)+) => { |
414 | | - #[allow(unused_variables, non_snake_case)] |
415 | | - impl<'a, Atom, $($X),*> Pratt<Atom, ($($X,)*)> { |
416 | | - #[inline] |
417 | | - fn pratt_go<M: Mode, I, O, E>(&self, inp: &mut InputRef<'a, '_, I, E>, min_power: u32) -> PResult<M, O> |
418 | | - where |
419 | | - I: Input<'a>, |
420 | | - E: ParserExtra<'a, I>, |
421 | | - Atom: Parser<'a, I, O, E>, |
422 | | - $($X: Operator<'a, I, O, E>),* |
423 | | - { |
424 | | - let pre_expr = inp.save(); |
425 | | - let mut lhs = 'choice: { |
426 | | - let ($($X,)*) = &self.ops; |
427 | | - |
428 | | - // Prefix unary operators |
429 | | - $( |
430 | | - if $X::IS_PREFIX { |
431 | | - match $X.op_parser().go::<M>(inp) { |
432 | | - Ok(op) => { |
433 | | - match recursive::recurse(|| self.pratt_go::<M, _, _, _>(inp, $X.associativity().left_power())) { |
434 | | - Ok(rhs) => break 'choice M::combine(op, rhs, |op, rhs| { |
435 | | - $X.fold_prefix(op, rhs, &mut MapExtra::new(pre_expr.offset(), inp)) |
436 | | - }), |
437 | | - Err(()) => inp.rewind(pre_expr), |
438 | | - } |
439 | | - }, |
| 409 | +#[typle(Tuple for 1..=26)] |
| 410 | +impl<'a, Atom, T: Tuple> Pratt<Atom, T> { |
| 411 | + #[inline] |
| 412 | + fn pratt_go<M: Mode, I, O, E>( |
| 413 | + &self, |
| 414 | + inp: &mut InputRef<'a, '_, I, E>, |
| 415 | + min_power: u32, |
| 416 | + ) -> PResult<M, O> |
| 417 | + where |
| 418 | + I: Input<'a>, |
| 419 | + E: ParserExtra<'a, I>, |
| 420 | + Atom: Parser<'a, I, O, E>, |
| 421 | + T<_>: Operator<'a, I, O, E>, |
| 422 | + { |
| 423 | + let pre_expr = inp.save(); |
| 424 | + let mut lhs = 'choice: { |
| 425 | + // Prefix unary operators |
| 426 | + for typle_index!(i) in 0..T::LEN { |
| 427 | + if T::<{ i }>::IS_PREFIX { |
| 428 | + let t = &self.ops[[i]]; |
| 429 | + match t.op_parser().go::<M>(inp) { |
| 430 | + Ok(op) => { |
| 431 | + match recursive::recurse(|| { |
| 432 | + self.pratt_go::<M, _, _, _>(inp, t.associativity().left_power()) |
| 433 | + }) { |
| 434 | + Ok(rhs) => { |
| 435 | + break 'choice M::combine(op, rhs, |op, rhs| { |
| 436 | + t.fold_prefix( |
| 437 | + op, |
| 438 | + rhs, |
| 439 | + &mut MapExtra::new(pre_expr.offset(), inp), |
| 440 | + ) |
| 441 | + }) |
| 442 | + } |
440 | 443 | Err(()) => inp.rewind(pre_expr), |
441 | 444 | } |
442 | 445 | } |
443 | | - )* |
444 | | - |
445 | | - self.atom.go::<M>(inp)? |
446 | | - }; |
447 | | - |
448 | | - loop { |
449 | | - let ($($X,)*) = &self.ops; |
450 | | - |
451 | | - let pre_op = inp.save(); |
452 | | - |
453 | | - // Postfix unary operators |
454 | | - $( |
455 | | - let assoc = $X.associativity(); |
456 | | - if $X::IS_POSTFIX && assoc.right_power() >= min_power { |
457 | | - match $X.op_parser().go::<M>(inp) { |
458 | | - Ok(op) => { |
459 | | - lhs = M::combine(lhs, op, |lhs, op| { |
460 | | - $X.fold_postfix(lhs, op, &mut MapExtra::new(pre_expr.offset(), inp)) |
461 | | - }); |
462 | | - continue |
463 | | - }, |
464 | | - Err(()) => inp.rewind(pre_op), |
465 | | - } |
| 446 | + Err(()) => inp.rewind(pre_expr), |
| 447 | + } |
| 448 | + } |
| 449 | + } |
| 450 | + |
| 451 | + self.atom.go::<M>(inp)? |
| 452 | + }; |
| 453 | + |
| 454 | + 'start: loop { |
| 455 | + let pre_op = inp.save(); |
| 456 | + |
| 457 | + // Postfix unary operators |
| 458 | + for typle_index!(i) in 0..T::LEN { |
| 459 | + let t = &self.ops[[i]]; |
| 460 | + let assoc = t.associativity(); |
| 461 | + if T::<{ i }>::IS_POSTFIX && assoc.right_power() >= min_power { |
| 462 | + match t.op_parser().go::<M>(inp) { |
| 463 | + Ok(op) => { |
| 464 | + lhs = M::combine(lhs, op, |lhs, op| { |
| 465 | + t.fold_postfix(lhs, op, &mut MapExtra::new(pre_expr.offset(), inp)) |
| 466 | + }); |
| 467 | + continue 'start; |
466 | 468 | } |
467 | | - )* |
468 | | - |
469 | | - // Infix binary operators |
470 | | - $( |
471 | | - let assoc = $X.associativity(); |
472 | | - if $X::IS_INFIX && assoc.left_power() >= min_power { |
473 | | - match $X.op_parser().go::<M>(inp) { |
474 | | - Ok(op) => match recursive::recurse(|| self.pratt_go::<M, _, _, _>(inp, assoc.right_power())) { |
475 | | - Ok(rhs) => { |
476 | | - lhs = M::combine( |
477 | | - M::combine(lhs, rhs, |lhs, rhs| (lhs, rhs)), |
| 469 | + Err(()) => inp.rewind(pre_op), |
| 470 | + } |
| 471 | + } |
| 472 | + } |
| 473 | + |
| 474 | + // Infix binary operators |
| 475 | + for typle_index!(i) in 0..T::LEN { |
| 476 | + let t = &self.ops[[i]]; |
| 477 | + let assoc = t.associativity(); |
| 478 | + if T::<{ i }>::IS_INFIX && assoc.left_power() >= min_power { |
| 479 | + match t.op_parser().go::<M>(inp) { |
| 480 | + Ok(op) => match recursive::recurse(|| { |
| 481 | + self.pratt_go::<M, _, _, _>(inp, assoc.right_power()) |
| 482 | + }) { |
| 483 | + Ok(rhs) => { |
| 484 | + lhs = M::combine( |
| 485 | + M::combine(lhs, rhs, |lhs, rhs| (lhs, rhs)), |
| 486 | + op, |
| 487 | + |(lhs, rhs), op| { |
| 488 | + t.fold_infix( |
| 489 | + lhs, |
478 | 490 | op, |
479 | | - |(lhs, rhs), op| { |
480 | | - $X.fold_infix(lhs, op, rhs, &mut MapExtra::new(pre_expr.offset(), inp)) |
481 | | - }, |
482 | | - ); |
483 | | - continue |
| 491 | + rhs, |
| 492 | + &mut MapExtra::new(pre_expr.offset(), inp), |
| 493 | + ) |
484 | 494 | }, |
485 | | - Err(()) => inp.rewind(pre_op), |
486 | | - }, |
487 | | - Err(()) => inp.rewind(pre_op), |
| 495 | + ); |
| 496 | + continue 'start; |
488 | 497 | } |
489 | | - } |
490 | | - )* |
491 | | - |
492 | | - inp.rewind(pre_op); |
493 | | - break; |
| 498 | + Err(()) => inp.rewind(pre_op), |
| 499 | + }, |
| 500 | + Err(()) => inp.rewind(pre_op), |
| 501 | + } |
494 | 502 | } |
495 | | - |
496 | | - Ok(lhs) |
497 | 503 | } |
498 | | - } |
499 | 504 |
|
500 | | - #[allow(unused_variables, non_snake_case)] |
501 | | - impl<'a, I, O, E, Atom, $($X),*> ParserSealed<'a, I, O, E> for Pratt<Atom, ($($X,)*)> |
502 | | - where |
503 | | - I: Input<'a>, |
504 | | - E: ParserExtra<'a, I>, |
505 | | - Atom: Parser<'a, I, O, E>, |
506 | | - $($X: Operator<'a, I, O, E>),* |
507 | | - { |
508 | | - fn go<M: Mode>(&self, inp: &mut InputRef<'a, '_, I, E>) -> PResult<M, O> { |
509 | | - self.pratt_go::<M, _, _, _>(inp, 0) |
510 | | - } |
511 | | - |
512 | | - go_extra!(O); |
| 505 | + inp.rewind(pre_op); |
| 506 | + break; |
513 | 507 | } |
514 | | - }; |
| 508 | + |
| 509 | + Ok(lhs) |
| 510 | + } |
515 | 511 | } |
516 | 512 |
|
517 | | -impl_pratt_for_tuple!(A_ B_ C_ D_ E_ F_ G_ H_ I_ J_ K_ L_ M_ N_ O_ P_ Q_ R_ S_ T_ U_ V_ W_ X_ Y_ Z_); |
| 513 | +#[typle(Tuple for 1..=26)] |
| 514 | +impl<'a, I, O, E, Atom, T: Tuple> ParserSealed<'a, I, O, E> for Pratt<Atom, T> |
| 515 | +where |
| 516 | + I: Input<'a>, |
| 517 | + E: ParserExtra<'a, I>, |
| 518 | + Atom: Parser<'a, I, O, E>, |
| 519 | + T<_>: Operator<'a, I, O, E>, |
| 520 | +{ |
| 521 | + fn go<M: Mode>(&self, inp: &mut InputRef<'a, '_, I, E>) -> PResult<M, O> { |
| 522 | + self.pratt_go::<M, _, _, _>(inp, 0) |
| 523 | + } |
| 524 | + |
| 525 | + go_extra!(O); |
| 526 | +} |
518 | 527 |
|
519 | 528 | #[cfg(test)] |
520 | 529 | mod tests { |
|
0 commit comments