diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /third_party/rust/fluent-syntax/src/parser/mod.rs | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/fluent-syntax/src/parser/mod.rs')
-rw-r--r-- | third_party/rust/fluent-syntax/src/parser/mod.rs | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/third_party/rust/fluent-syntax/src/parser/mod.rs b/third_party/rust/fluent-syntax/src/parser/mod.rs new file mode 100644 index 0000000000..52edfdc37a --- /dev/null +++ b/third_party/rust/fluent-syntax/src/parser/mod.rs @@ -0,0 +1,278 @@ +//! Fluent Translation List parsing utilities +//! +//! FTL resources can be parsed using one of two methods: +//! * [`parse`] - parses an input into a complete Abstract Syntax Tree representation with all source information preserved. +//! * [`parse_runtime`] - parses an input into a runtime optimized Abstract Syntax Tree +//! representation with comments stripped. +//! +//! # Example +//! +//! ``` +//! use fluent_syntax::parser; +//! use fluent_syntax::ast; +//! +//! let ftl = r#" +//! #### Resource Level Comment +//! +//! ## This is a message comment +//! hello-world = Hello World! +//! +//! "#; +//! +//! let resource = parser::parse(ftl) +//! .expect("Failed to parse an FTL resource."); +//! +//! assert_eq!( +//! resource.body[0], +//! ast::Entry::ResourceComment( +//! ast::Comment { +//! content: vec![ +//! "Resource Level Comment" +//! ] +//! } +//! ) +//! ); +//! assert_eq!( +//! resource.body[1], +//! ast::Entry::Message( +//! ast::Message { +//! id: ast::Identifier { +//! name: "hello-world" +//! }, +//! value: Some(ast::Pattern { +//! elements: vec![ +//! ast::PatternElement::TextElement { +//! value: "Hello World!" +//! }, +//! ] +//! }), +//! attributes: vec![], +//! comment: Some( +//! ast::Comment { +//! content: vec!["This is a message comment"] +//! } +//! ) +//! } +//! ), +//! ); +//! ``` +//! +//! # Error Recovery +//! +//! In both modes the parser is lenient, attempting to recover from errors. +//! +//! The [`Result`] return the resulting AST in both scenarios, and in the +//! error scenario a vector of [`ParserError`] elements is returned as well. +//! +//! Any unparsed parts of the input are returned as [`ast::Entry::Junk`] elements. +#[macro_use] +mod errors; +#[macro_use] +mod macros; +mod comment; +mod core; +mod expression; +mod helper; +mod pattern; +mod runtime; +mod slice; + +use crate::ast; +pub use errors::{ErrorKind, ParserError}; +pub use slice::Slice; + +/// Parser result always returns an AST representation of the input, +/// and if parsing errors were encountered, a list of [`ParserError`] elements +/// is also returned. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// key1 = Value 1 +/// +/// g@Rb@ge = #2y ds +/// +/// key2 = Value 2 +/// +/// "#; +/// +/// let (resource, errors) = parser::parse_runtime(ftl) +/// .expect_err("Resource should contain errors."); +/// +/// assert_eq!( +/// errors, +/// vec![ +/// parser::ParserError { +/// pos: 18..19, +/// slice: Some(17..35), +/// kind: parser::ErrorKind::ExpectedToken('=') +/// } +/// ] +/// ); +/// +/// assert_eq!( +/// resource.body[0], +/// ast::Entry::Message( +/// ast::Message { +/// id: ast::Identifier { +/// name: "key1" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Value 1" +/// }, +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// } +/// ), +/// ); +/// +/// assert_eq!( +/// resource.body[1], +/// ast::Entry::Junk { +/// content: "g@Rb@ge = #2y ds\n\n" +/// } +/// ); +/// +/// assert_eq!( +/// resource.body[2], +/// ast::Entry::Message( +/// ast::Message { +/// id: ast::Identifier { +/// name: "key2" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Value 2" +/// }, +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// } +/// ), +/// ); +/// ``` +pub type Result<S> = std::result::Result<ast::Resource<S>, (ast::Resource<S>, Vec<ParserError>)>; + +/// Parses an input into a complete Abstract Syntax Tree representation with +/// all source information preserved. +/// +/// This mode is intended for tooling, linters and other scenarios where +/// complete representation, with comments, is preferred over speed and memory +/// utilization. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// #### Resource Level Comment +/// +/// ## This is a message comment +/// hello-world = Hello World! +/// +/// "#; +/// +/// let resource = parser::parse(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource.body[0], +/// ast::Entry::ResourceComment( +/// ast::Comment { +/// content: vec![ +/// "Resource Level Comment" +/// ] +/// } +/// ) +/// ); +/// assert_eq!( +/// resource.body[1], +/// ast::Entry::Message( +/// ast::Message { +/// id: ast::Identifier { +/// name: "hello-world" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Hello World!" +/// }, +/// ] +/// }), +/// attributes: vec![], +/// comment: Some( +/// ast::Comment { +/// content: vec!["This is a message comment"] +/// } +/// ) +/// } +/// ), +/// ); +/// ``` +pub fn parse<'s, S>(input: S) -> Result<S> +where + S: Slice<'s>, +{ + core::Parser::new(input).parse() +} + +/// Parses an input into an Abstract Syntax Tree representation with comments stripped. +/// +/// This mode is intended for runtime use of Fluent. It currently strips all +/// comments improving parsing performance and reducing the size of the AST tree. +/// +/// # Example +/// +/// ``` +/// use fluent_syntax::parser; +/// use fluent_syntax::ast; +/// +/// let ftl = r#" +/// #### Resource Level Comment +/// +/// ## This is a message comment +/// hello-world = Hello World! +/// +/// "#; +/// +/// let resource = parser::parse_runtime(ftl) +/// .expect("Failed to parse an FTL resource."); +/// +/// assert_eq!( +/// resource.body[0], +/// ast::Entry::Message( +/// ast::Message { +/// id: ast::Identifier { +/// name: "hello-world" +/// }, +/// value: Some(ast::Pattern { +/// elements: vec![ +/// ast::PatternElement::TextElement { +/// value: "Hello World!" +/// }, +/// ] +/// }), +/// attributes: vec![], +/// comment: None, +/// } +/// ), +/// ); +/// ``` +pub fn parse_runtime<'s, S>(input: S) -> Result<S> +where + S: Slice<'s>, +{ + core::Parser::new(input).parse_runtime() +} |