,
+ location: Location<'static>,
}
impl<'a, 'b, I: Input<'a>, O, E: ParserExtra<'a, I>> Recursive {
.expect("Recursive parser used before being defined"),
}
}
+
+ #[inline(always)]
+ fn with_left_recursive_check<'a, I, E, R>(
+ &self,
+ inp: &mut InputRef<'a, '_, I, E>,
+ f: impl FnOnce(&mut InputRef<'a, '_, I, E>) -> R,
+ ) -> R
+ where
+ I: Input<'a>,
+ E: ParserExtra<'a, I>,
+ {
+ // TODO: Don't use address, since this might not be constant?
+ #[cfg(debug_assertions)]
+ let key = (
+ inp.offset().offset,
+ RefC::as_ptr(&self.parser()) as *const () as usize,
+ );
+
+ #[cfg(debug_assertions)]
+ if inp.memos.insert(key, None).is_some() {
+ panic!("Recursive parser defined at {} is left-recursive. Consider using `.memoized()` or restructuring this parser to be right-recursive.", self.location);
+ }
+
+ let res = f(inp);
+
+ #[cfg(debug_assertions)]
+ inp.memos.remove(&key);
+
+ res
+ }
}
impl {
@@ -160,6 +193,7 @@ impl {
RecursiveInner::Owned(x) => RecursiveInner::Owned(x.clone()),
RecursiveInner::Unowned(x) => RecursiveInner::Unowned(x.clone()),
},
+ location: self.location,
}
}
}
@@ -182,15 +216,17 @@ where
{
#[inline]
fn go