diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/glsl/src/parsers | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/glsl/src/parsers')
-rw-r--r-- | third_party/rust/glsl/src/parsers/nom_helpers.rs | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/third_party/rust/glsl/src/parsers/nom_helpers.rs b/third_party/rust/glsl/src/parsers/nom_helpers.rs new file mode 100644 index 0000000000..8952a261ac --- /dev/null +++ b/third_party/rust/glsl/src/parsers/nom_helpers.rs @@ -0,0 +1,95 @@ +//! Various nom parser helpers. + +use nom::branch::alt; +use nom::bytes::complete::tag; +use nom::character::complete::{anychar, multispace1, newline}; +use nom::combinator::{map, recognize, value}; +use nom::error::{ErrorKind, VerboseError, VerboseErrorKind}; +use nom::multi::fold_many0; +use nom::{Err as NomErr, IResult}; + +pub type ParserResult<'a, O> = IResult<&'a str, O, VerboseError<&'a str>>; + +// A constant parser that just forwards the value it’s parametered with without reading anything +// from the input. Especially useful as “fallback” in an alternative parser. +pub fn cnst<'a, T, E>(t: T) -> impl Fn(&'a str) -> Result<(&'a str, T), E> +where + T: 'a + Clone, +{ + move |i| Ok((i, t.clone())) +} + +// End-of-input parser. +// +// Yields `()` if the parser is at the end of the input; an error otherwise. +pub fn eoi(i: &str) -> ParserResult<()> { + if i.is_empty() { + Ok((i, ())) + } else { + Err(NomErr::Error(VerboseError { + errors: vec![(i, VerboseErrorKind::Nom(ErrorKind::Eof))], + })) + } +} + +// A newline parser that accepts: +// +// - A newline. +// - The end of input. +pub fn eol(i: &str) -> ParserResult<()> { + alt(( + eoi, // this one goes first because it’s very cheap + value((), newline), + ))(i) +} + +// Apply the `f` parser until `g` succeeds. Both parsers consume the input. +pub fn till<'a, A, B, F, G>(f: F, g: G) -> impl Fn(&'a str) -> ParserResult<'a, ()> +where + F: Fn(&'a str) -> ParserResult<'a, A>, + G: Fn(&'a str) -> ParserResult<'a, B>, +{ + move |mut i| loop { + if let Ok((i2, _)) = g(i) { + break Ok((i2, ())); + } + + let (i2, _) = f(i)?; + i = i2; + } +} + +// A version of many0 that discards the result of the parser, preventing allocating. +pub fn many0_<'a, A, F>(f: F) -> impl Fn(&'a str) -> ParserResult<'a, ()> +where + F: Fn(&'a str) -> ParserResult<'a, A>, +{ + move |i| fold_many0(&f, (), |_, _| ())(i) +} + +/// Parse a string until the end of line. +/// +/// This parser accepts the multiline annotation (\) to break the string on several lines. +/// +/// Discard any leading newline. +pub fn str_till_eol(i: &str) -> ParserResult<&str> { + map( + recognize(till(alt((value((), tag("\\\n")), value((), anychar))), eol)), + |i| { + if i.as_bytes().last() == Some(&b'\n') { + &i[0..i.len() - 1] + } else { + i + } + }, + )(i) +} + +// Blank base parser. +// +// This parser succeeds with multispaces and multiline annotation. +// +// Taylor Swift loves it. +pub fn blank_space(i: &str) -> ParserResult<&str> { + recognize(many0_(alt((multispace1, tag("\\\n")))))(i) +} |