parser.rs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. use crate::{pkg_length::PkgLength, AmlContext, AmlError};
  2. use alloc::vec::Vec;
  3. use core::marker::PhantomData;
  4. pub type ParseResult<'a, 'c, R> =
  5. Result<(&'a [u8], &'c mut AmlContext, R), (&'a [u8], &'c mut AmlContext, AmlError)>;
  6. pub trait Parser<'a, 'c, R>: Sized
  7. where
  8. 'c: 'a,
  9. {
  10. fn parse(&self, input: &'a [u8], context: &'c mut AmlContext) -> ParseResult<'a, 'c, R>;
  11. fn map<F, A>(self, map_fn: F) -> Map<'a, 'c, Self, F, R, A>
  12. where
  13. F: Fn(R) -> Result<A, AmlError>,
  14. {
  15. Map { parser: self, map_fn, _phantom: PhantomData }
  16. }
  17. fn map_with_context<F, A>(self, map_fn: F) -> MapWithContext<'a, 'c, Self, F, R, A>
  18. where
  19. F: Fn(R, &'c mut AmlContext) -> (Result<A, AmlError>, &'c mut AmlContext),
  20. {
  21. MapWithContext { parser: self, map_fn, _phantom: PhantomData }
  22. }
  23. fn discard_result(self) -> DiscardResult<'a, 'c, Self, R> {
  24. DiscardResult { parser: self, _phantom: PhantomData }
  25. }
  26. /// Try parsing with `self`. If it succeeds, return its result. If it returns `AmlError::WrongParser`, try
  27. /// parsing with `other`, returning the result of that parser in all cases. Other errors from the first
  28. /// parser are propagated without attempting the second parser. To chain more than two parsers using
  29. /// `or`, see the `choice!` macro.
  30. fn or<OtherParser>(self, other: OtherParser) -> Or<'a, 'c, Self, OtherParser, R>
  31. where
  32. OtherParser: Parser<'a, 'c, R>,
  33. {
  34. Or { p1: self, p2: other, _phantom: PhantomData }
  35. }
  36. fn then<NextParser, NextR>(self, next: NextParser) -> Then<'a, 'c, Self, NextParser, R, NextR>
  37. where
  38. NextParser: Parser<'a, 'c, NextR>,
  39. {
  40. Then { p1: self, p2: next, _phantom: PhantomData }
  41. }
  42. /// `feed` takes a function that takes the result of this parser (`self`) and creates another
  43. /// parser, which is then used to parse the next part of the stream. This sounds convoluted,
  44. /// but is useful for when the next parser's behaviour depends on a property of the result of
  45. /// the first (e.g. the first parser might parse a length `n`, and the second parser then
  46. /// consumes `n` bytes).
  47. fn feed<F, P2, R2>(self, producer_fn: F) -> Feed<'a, 'c, Self, P2, F, R, R2>
  48. where
  49. P2: Parser<'a, 'c, R2>,
  50. F: Fn(R) -> P2,
  51. {
  52. Feed { parser: self, producer_fn, _phantom: PhantomData }
  53. }
  54. }
  55. impl<'a, 'c, F, R> Parser<'a, 'c, R> for F
  56. where
  57. 'c: 'a,
  58. F: Fn(&'a [u8], &'c mut AmlContext) -> ParseResult<'a, 'c, R>,
  59. {
  60. fn parse(&self, input: &'a [u8], context: &'c mut AmlContext) -> ParseResult<'a, 'c, R> {
  61. self(input, context)
  62. }
  63. }
  64. /// The identity parser - returns the stream and context unchanged. Useful for producing parsers
  65. /// that produce a result without parsing anything by doing: `id().map(|()| Ok(foo))`.
  66. pub fn id<'a, 'c>() -> impl Parser<'a, 'c, ()>
  67. where
  68. 'c: 'a,
  69. {
  70. move |input: &'a [u8], context: &'c mut AmlContext| Ok((input, context, ()))
  71. }
  72. pub fn take<'a, 'c>() -> impl Parser<'a, 'c, u8>
  73. where
  74. 'c: 'a,
  75. {
  76. move |input: &'a [u8], context: &'c mut AmlContext| match input.first() {
  77. Some(&byte) => Ok((&input[1..], context, byte)),
  78. None => Err((input, context, AmlError::UnexpectedEndOfStream)),
  79. }
  80. }
  81. pub fn take_u16<'a, 'c>() -> impl Parser<'a, 'c, u16>
  82. where
  83. 'c: 'a,
  84. {
  85. move |input: &'a [u8], context: &'c mut AmlContext| {
  86. if input.len() < 2 {
  87. return Err((input, context, AmlError::UnexpectedEndOfStream));
  88. }
  89. Ok((&input[2..], context, input[0] as u16 + ((input[1] as u16) << 8)))
  90. }
  91. }
  92. pub fn take_u32<'a, 'c>() -> impl Parser<'a, 'c, u32>
  93. where
  94. 'c: 'a,
  95. {
  96. move |input: &'a [u8], context: &'c mut AmlContext| {
  97. if input.len() < 4 {
  98. return Err((input, context, AmlError::UnexpectedEndOfStream));
  99. }
  100. Ok((
  101. &input[4..],
  102. context,
  103. input[0] as u32 + ((input[1] as u32) << 8) + ((input[2] as u32) << 16) + ((input[3] as u32) << 24),
  104. ))
  105. }
  106. }
  107. pub fn take_u64<'a, 'c>() -> impl Parser<'a, 'c, u64>
  108. where
  109. 'c: 'a,
  110. {
  111. move |input: &'a [u8], context: &'c mut AmlContext| {
  112. if input.len() < 8 {
  113. return Err((input, context, AmlError::UnexpectedEndOfStream));
  114. }
  115. Ok((
  116. &input[8..],
  117. context,
  118. input[0] as u64
  119. + ((input[1] as u64) << 8)
  120. + ((input[2] as u64) << 16)
  121. + ((input[3] as u64) << 24)
  122. + ((input[4] as u64) << 32)
  123. + ((input[5] as u64) << 40)
  124. + ((input[6] as u64) << 48)
  125. + ((input[7] as u64) << 56),
  126. ))
  127. }
  128. }
  129. pub fn take_n<'a, 'c>(n: u32) -> impl Parser<'a, 'c, &'a [u8]>
  130. where
  131. 'c: 'a,
  132. {
  133. move |input: &'a [u8], context| {
  134. if (input.len() as u32) < n {
  135. return Err((input, context, AmlError::UnexpectedEndOfStream));
  136. }
  137. let (result, new_input) = input.split_at(n as usize);
  138. Ok((new_input, context, result))
  139. }
  140. }
  141. pub fn take_to_end_of_pkglength<'a, 'c>(length: PkgLength) -> impl Parser<'a, 'c, &'a [u8]>
  142. where
  143. 'c: 'a,
  144. {
  145. move |input: &'a [u8], context| {
  146. let bytes_to_take = (input.len() as u32) - length.end_offset;
  147. take_n(bytes_to_take).parse(input, context)
  148. }
  149. }
  150. pub fn n_of<'a, 'c, P, R>(parser: P, n: usize) -> impl Parser<'a, 'c, Vec<R>>
  151. where
  152. 'c: 'a,
  153. P: Parser<'a, 'c, R>,
  154. {
  155. // TODO: can we write this more nicely?
  156. move |mut input, mut context| {
  157. let mut results = Vec::with_capacity(n);
  158. for _ in 0..n {
  159. let (new_input, new_context, result) = match parser.parse(input, context) {
  160. Ok((input, context, result)) => (input, context, result),
  161. Err((_, context, err)) => return Err((input, context, err)),
  162. };
  163. results.push(result);
  164. input = new_input;
  165. context = new_context;
  166. }
  167. Ok((input, context, results))
  168. }
  169. }
  170. pub fn consume<'a, 'c, F>(condition: F) -> impl Parser<'a, 'c, u8>
  171. where
  172. 'c: 'a,
  173. F: Fn(u8) -> bool,
  174. {
  175. move |input: &'a [u8], context: &'c mut AmlContext| match input.first() {
  176. Some(&byte) if condition(byte) => Ok((&input[1..], context, byte)),
  177. Some(&byte) => Err((input, context, AmlError::UnexpectedByte(byte))),
  178. None => Err((input, context, AmlError::UnexpectedEndOfStream)),
  179. }
  180. }
  181. pub fn comment_scope<'a, 'c, P, R>(scope_name: &'a str, parser: P) -> impl Parser<'a, 'c, R>
  182. where
  183. 'c: 'a,
  184. R: core::fmt::Debug,
  185. P: Parser<'a, 'c, R>,
  186. {
  187. move |input, context| {
  188. #[cfg(feature = "debug_parser")]
  189. log::trace!("--> {}", scope_name);
  190. // Return if the parse fails, so we don't print the tail. Makes it easier to debug.
  191. let (new_input, context, result) = parser.parse(input, context)?;
  192. #[cfg(feature = "debug_parser")]
  193. log::trace!("<-- {}", scope_name);
  194. Ok((new_input, context, result))
  195. }
  196. }
  197. pub fn comment_scope_verbose<'a, 'c, P, R>(scope_name: &'a str, parser: P) -> impl Parser<'a, 'c, R>
  198. where
  199. 'c: 'a,
  200. R: core::fmt::Debug,
  201. P: Parser<'a, 'c, R>,
  202. {
  203. move |input, context| {
  204. #[cfg(feature = "debug_parser_verbose")]
  205. log::trace!("--> {}", scope_name);
  206. // Return if the parse fails, so we don't print the tail. Makes it easier to debug.
  207. let (new_input, context, result) = parser.parse(input, context)?;
  208. #[cfg(feature = "debug_parser_verbose")]
  209. log::trace!("<-- {}", scope_name);
  210. Ok((new_input, context, result))
  211. }
  212. }
  213. pub struct Or<'a, 'c, P1, P2, R>
  214. where
  215. 'c: 'a,
  216. P1: Parser<'a, 'c, R>,
  217. P2: Parser<'a, 'c, R>,
  218. {
  219. p1: P1,
  220. p2: P2,
  221. _phantom: PhantomData<(&'a R, &'c ())>,
  222. }
  223. impl<'a, 'c, P1, P2, R> Parser<'a, 'c, R> for Or<'a, 'c, P1, P2, R>
  224. where
  225. 'c: 'a,
  226. P1: Parser<'a, 'c, R>,
  227. P2: Parser<'a, 'c, R>,
  228. {
  229. fn parse(&self, input: &'a [u8], context: &'c mut AmlContext) -> ParseResult<'a, 'c, R> {
  230. match self.p1.parse(input, context) {
  231. Ok(parse_result) => Ok(parse_result),
  232. Err((_, context, AmlError::WrongParser)) => self.p2.parse(input, context),
  233. Err((_, context, err)) => Err((input, context, err)),
  234. }
  235. }
  236. }
  237. pub struct Map<'a, 'c, P, F, R, A>
  238. where
  239. 'c: 'a,
  240. P: Parser<'a, 'c, R>,
  241. F: Fn(R) -> Result<A, AmlError>,
  242. {
  243. parser: P,
  244. map_fn: F,
  245. _phantom: PhantomData<(&'a (R, A), &'c ())>,
  246. }
  247. impl<'a, 'c, P, F, R, A> Parser<'a, 'c, A> for Map<'a, 'c, P, F, R, A>
  248. where
  249. 'c: 'a,
  250. P: Parser<'a, 'c, R>,
  251. F: Fn(R) -> Result<A, AmlError>,
  252. {
  253. fn parse(&self, input: &'a [u8], context: &'c mut AmlContext) -> ParseResult<'a, 'c, A> {
  254. match self.parser.parse(input, context) {
  255. Ok((new_input, context, result)) => match (self.map_fn)(result) {
  256. Ok(result_value) => Ok((new_input, context, result_value)),
  257. Err(err) => Err((input, context, err)),
  258. },
  259. Err(result) => Err(result),
  260. }
  261. }
  262. }
  263. pub struct MapWithContext<'a, 'c, P, F, R, A>
  264. where
  265. 'c: 'a,
  266. P: Parser<'a, 'c, R>,
  267. F: Fn(R, &'c mut AmlContext) -> (Result<A, AmlError>, &'c mut AmlContext),
  268. {
  269. parser: P,
  270. map_fn: F,
  271. _phantom: PhantomData<(&'a (R, A), &'c ())>,
  272. }
  273. impl<'a, 'c, P, F, R, A> Parser<'a, 'c, A> for MapWithContext<'a, 'c, P, F, R, A>
  274. where
  275. 'c: 'a,
  276. P: Parser<'a, 'c, R>,
  277. F: Fn(R, &'c mut AmlContext) -> (Result<A, AmlError>, &'c mut AmlContext),
  278. {
  279. fn parse(&self, input: &'a [u8], context: &'c mut AmlContext) -> ParseResult<'a, 'c, A> {
  280. match self.parser.parse(input, context) {
  281. Ok((new_input, context, result)) => match (self.map_fn)(result, context) {
  282. (Ok(result_value), context) => Ok((new_input, context, result_value)),
  283. (Err(err), context) => Err((input, context, err)),
  284. },
  285. Err(result) => Err(result),
  286. }
  287. }
  288. }
  289. pub struct DiscardResult<'a, 'c, P, R>
  290. where
  291. 'c: 'a,
  292. P: Parser<'a, 'c, R>,
  293. {
  294. parser: P,
  295. _phantom: PhantomData<(&'a R, &'c ())>,
  296. }
  297. impl<'a, 'c, P, R> Parser<'a, 'c, ()> for DiscardResult<'a, 'c, P, R>
  298. where
  299. 'c: 'a,
  300. P: Parser<'a, 'c, R>,
  301. {
  302. fn parse(&self, input: &'a [u8], context: &'c mut AmlContext) -> ParseResult<'a, 'c, ()> {
  303. self.parser.parse(input, context).map(|(new_input, new_context, _)| (new_input, new_context, ()))
  304. }
  305. }
  306. pub struct Then<'a, 'c, P1, P2, R1, R2>
  307. where
  308. 'c: 'a,
  309. P1: Parser<'a, 'c, R1>,
  310. P2: Parser<'a, 'c, R2>,
  311. {
  312. p1: P1,
  313. p2: P2,
  314. _phantom: PhantomData<(&'a (R1, R2), &'c ())>,
  315. }
  316. impl<'a, 'c, P1, P2, R1, R2> Parser<'a, 'c, (R1, R2)> for Then<'a, 'c, P1, P2, R1, R2>
  317. where
  318. 'c: 'a,
  319. P1: Parser<'a, 'c, R1>,
  320. P2: Parser<'a, 'c, R2>,
  321. {
  322. fn parse(&self, input: &'a [u8], context: &'c mut AmlContext) -> ParseResult<'a, 'c, (R1, R2)> {
  323. self.p1.parse(input, context).and_then(|(next_input, context, result_a)| {
  324. self.p2
  325. .parse(next_input, context)
  326. .map(|(final_input, context, result_b)| (final_input, context, (result_a, result_b)))
  327. })
  328. }
  329. }
  330. pub struct Feed<'a, 'c, P1, P2, F, R1, R2>
  331. where
  332. 'c: 'a,
  333. P1: Parser<'a, 'c, R1>,
  334. P2: Parser<'a, 'c, R2>,
  335. F: Fn(R1) -> P2,
  336. {
  337. parser: P1,
  338. producer_fn: F,
  339. _phantom: PhantomData<(&'a (R1, R2), &'c ())>,
  340. }
  341. impl<'a, 'c, P1, P2, F, R1, R2> Parser<'a, 'c, R2> for Feed<'a, 'c, P1, P2, F, R1, R2>
  342. where
  343. 'c: 'a,
  344. P1: Parser<'a, 'c, R1>,
  345. P2: Parser<'a, 'c, R2>,
  346. F: Fn(R1) -> P2,
  347. {
  348. fn parse(&self, input: &'a [u8], context: &'c mut AmlContext) -> ParseResult<'a, 'c, R2> {
  349. let (input, context, first_result) = self.parser.parse(input, context)?;
  350. // We can now produce the second parser, and parse using that.
  351. let second_parser = (self.producer_fn)(first_result);
  352. second_parser.parse(input, context)
  353. }
  354. }
  355. /// Takes a number of parsers, and tries to apply each one to the input in order. Returns the
  356. /// result of the first one that succeeds, or fails if all of them fail.
  357. pub(crate) macro choice {
  358. () => {
  359. id().map(|()| Err(AmlError::WrongParser))
  360. },
  361. ($first_parser: expr) => {
  362. $first_parser
  363. .or(id().map(|()| Err(AmlError::WrongParser)))
  364. },
  365. ($first_parser: expr, $($other_parser: expr),*) => {
  366. $first_parser
  367. $(
  368. .or($other_parser)
  369. )*
  370. .or(id().map(|()| Err(AmlError::WrongParser)))
  371. }
  372. }
  373. /// This encapsulates an unfortunate hack we sometimes need to use, where the type checker gets
  374. /// caught in an infinite loop of parser types. This occurs when an object can indirectly contain
  375. /// itself, and so the parser type will contain its own type. This works by breaking the cycle of
  376. /// `impl Parser` chains that build up, by effectively creating a "concrete" closure type.
  377. ///
  378. /// You can try using this hack if you are writing a parser and end up with an error of the form:
  379. /// `error[E0275]: overflow evaluating the requirement 'impl Parser<{a type}>'
  380. /// help: consider adding a a '#![recursion_limit="128"] attribute to your crate`
  381. /// Note: Increasing the recursion limit will not fix the issue, as the cycle will just continue
  382. /// until you either hit the new recursion limit or `rustc` overflows its stack.
  383. pub(crate) macro make_parser_concrete($parser: expr) {
  384. |input, context| ($parser).parse(input, context)
  385. }
  386. /// Helper macro for use within `map_with_context` as an alternative to "trying" an expression.
  387. ///
  388. /// ### Example
  389. /// Problem: `expr?` won't work because the expected return type is `(Result<R, AmlError>, &mut AmlContext)`
  390. /// Solution: use `try_with_context!(context, expr)` instead.
  391. pub(crate) macro try_with_context($context: expr, $expr: expr) {
  392. match $expr {
  393. Ok(result) => result,
  394. Err(err) => return (Err(err), $context),
  395. }
  396. }
  397. #[cfg(test)]
  398. mod tests {
  399. use super::*;
  400. use crate::test_utils::*;
  401. #[test]
  402. fn test_take_n() {
  403. let mut context = AmlContext::new();
  404. check_err!(take_n(1).parse(&[], &mut context), AmlError::UnexpectedEndOfStream, &[]);
  405. check_err!(take_n(2).parse(&[0xf5], &mut context), AmlError::UnexpectedEndOfStream, &[0xf5]);
  406. check_ok!(take_n(1).parse(&[0xff], &mut context), &[0xff], &[]);
  407. check_ok!(take_n(1).parse(&[0xff, 0xf8], &mut context), &[0xff], &[0xf8]);
  408. check_ok!(take_n(2).parse(&[0xff, 0xf8], &mut context), &[0xff, 0xf8], &[]);
  409. }
  410. #[test]
  411. fn test_take_ux() {
  412. let mut context = AmlContext::new();
  413. check_err!(take_u16().parse(&[0x34], &mut context), AmlError::UnexpectedEndOfStream, &[0x34]);
  414. check_ok!(take_u16().parse(&[0x34, 0x12], &mut context), 0x1234, &[]);
  415. check_err!(take_u32().parse(&[0x34, 0x12], &mut context), AmlError::UnexpectedEndOfStream, &[0x34, 0x12]);
  416. check_ok!(take_u32().parse(&[0x34, 0x12, 0xf4, 0xc3, 0x3e], &mut context), 0xc3f41234, &[0x3e]);
  417. check_err!(take_u64().parse(&[0x34], &mut context), AmlError::UnexpectedEndOfStream, &[0x34]);
  418. check_ok!(
  419. take_u64().parse(&[0x34, 0x12, 0x35, 0x76, 0xd4, 0x43, 0xa3, 0xb6, 0xff, 0x00], &mut context),
  420. 0xb6a343d476351234,
  421. &[0xff, 0x00]
  422. );
  423. }
  424. }