From 1d07e9356bfefec00c3f0e31ef2ffcff0956ef5e Mon Sep 17 00:00:00 2001 From: Zibi Braniecki Date: Wed, 20 Dec 2017 01:39:00 -0800 Subject: [PATCH] Switch to new comments system and remove sections --- src/resolve.rs | 4 +- src/syntax/ast.rs | 25 ++-- src/syntax/parser.rs | 134 +++++++++++----------- tests/fixtures/parser/ftl/03-comments.ftl | 24 ++-- tests/fixtures/parser/ftl/04-sections.ftl | 10 -- tests/fixtures/parser/ftl/05-variants.ftl | 2 +- 6 files changed, 88 insertions(+), 111 deletions(-) delete mode 100644 tests/fixtures/parser/ftl/04-sections.ftl diff --git a/src/resolve.rs b/src/resolve.rs index d0c9688d..e90c73f5 100644 --- a/src/resolve.rs +++ b/src/resolve.rs @@ -74,7 +74,7 @@ impl ResolveValue for ast::Number { } } -impl ResolveValue for ast::Symbol { +impl ResolveValue for ast::VariantName { fn to_value(&self, _env: &Env) -> Option { Some(FluentValue::from(self.name.clone())) } @@ -107,7 +107,7 @@ impl ResolveValue for ast::Expression { if let Some(ref selector) = selector { for variant in variants { match variant.key { - ast::VarKey::Symbol(ref symbol) => { + ast::VarKey::VariantName(ref symbol) => { let key = FluentValue::from(symbol.name.clone()); if key.matches(env.ctx, selector) { return variant.value.to_value(env); diff --git a/src/syntax/ast.rs b/src/syntax/ast.rs index a8a6a2a5..b76bbe4d 100644 --- a/src/syntax/ast.rs +++ b/src/syntax/ast.rs @@ -1,20 +1,13 @@ #[derive(Debug, PartialEq)] pub struct Resource { pub body: Vec, - pub comment: Option, } #[derive(Debug, PartialEq)] pub enum Entry { Message(Message), - Section { - name: Symbol, - comment: Option, - }, Comment(Comment), - Junk { - content: String, - }, + Junk { content: String }, } #[derive(Debug, PartialEq)] @@ -88,7 +81,7 @@ pub struct Variant { #[derive(Debug, PartialEq)] pub enum VarKey { - Symbol(Symbol), + VariantName(VariantName), Number(Number), } @@ -115,19 +108,15 @@ pub struct Number { } #[derive(Debug, PartialEq)] -pub struct Symbol { +pub struct VariantName { pub name: String, } #[derive(Debug, PartialEq)] -pub struct Comment { - pub content: String, -} - -#[derive(Debug, PartialEq)] -pub struct Section { - pub name: String, - pub comment: Option, +pub enum Comment { + Comment { content: String }, + GroupComment { content: String }, + ResourceComment { content: String }, } #[derive(Debug, PartialEq)] diff --git a/src/syntax/parser.rs b/src/syntax/parser.rs index 07be555b..2e534612 100644 --- a/src/syntax/parser.rs +++ b/src/syntax/parser.rs @@ -14,7 +14,6 @@ pub type Result = result::Result; pub fn parse(source: &str) -> result::Result)> { let mut errors = vec![]; - let mut comment = None; let mut ps = ParserStream::new(source.chars()); @@ -26,18 +25,9 @@ pub fn parse(source: &str) -> result::Result if entry_start_pos == 0 { - match entry { - ast::Entry::Comment(c) => { - comment = Some(c); - } - _ => { - entries.push(entry); - } - } - } else { + Ok(entry) => { entries.push(entry); - }, + } Err(mut e) => { let error_pos = ps.get_index(); entries.push(get_junk_entry(&mut ps, source, entry_start_pos)); @@ -51,18 +41,9 @@ pub fn parse(source: &str) -> result::Result(ps: &mut ParserStream) -> Result where I: Iterator, { - let comment = if ps.current_is('/') { + let comment = if ps.current_is('#') { Some(get_comment(ps)?) } else { None }; - if ps.current_is('[') { - return Ok(get_section(ps, comment)?); - } - if ps.is_message_id_start() { - return Ok(get_message(ps, comment)?); + match comment { + None | Some(ast::Comment::Comment { .. }) => { + return Ok(get_message(ps, comment)?); + } + _ => {} + }; } match comment { @@ -90,60 +72,74 @@ where } } -fn get_comment(ps: &mut ParserStream) -> Result +#[derive(PartialEq, Copy, Clone)] +enum CommentLevel { + Comment = 0, + GroupComment = 1, + ResourceComment = 2, +} + +fn get_comment_start(ps: &mut ParserStream, level: &CommentLevel) -> Result<()> where I: Iterator, { - ps.expect_char('/')?; - ps.expect_char('/')?; - ps.take_char_if(' '); - - let mut content = String::new(); - - loop { - while let Some(ch) = ps.take_char(|x| x != '\n') { - content.push(ch); - } + let depth = *level as u8; + for _ in 0..(depth + 1) { + ps.expect_char('#')?; + } - ps.next(); + if !ps.current_is('\n') { + ps.expect_char(' ')?; + } + Ok(()) +} - if ps.current_is('/') { - content.push('\n'); - ps.next(); - ps.expect_char('/')?; - ps.take_char_if(' '); +fn get_comment_level(ps: &mut ParserStream) -> Result +where + I: Iterator, +{ + let mut level = CommentLevel::Comment; + ps.peek(); + if ps.current_peek_is('#') { + ps.peek(); + if ps.current_peek_is('#') { + level = CommentLevel::ResourceComment; } else { - break; + level = CommentLevel::GroupComment; } } - - Ok(ast::Comment { content }) + ps.reset_peek(); + Ok(level) } -fn get_section(ps: &mut ParserStream, comment: Option) -> Result +fn get_comment(ps: &mut ParserStream) -> Result where I: Iterator, { - ps.expect_char('[')?; - ps.expect_char('[')?; - - ps.skip_line_ws(); - - let symb = get_symbol(ps)?; + let level = get_comment_level(ps)?; + get_comment_start(ps, &level)?; - ps.skip_line_ws(); + let mut content = String::new(); - ps.expect_char(']')?; - ps.expect_char(']')?; + loop { + while let Some(ch) = ps.take_char(|x| x != '\n') { + content.push(ch); + } - ps.skip_line_ws(); + ps.next(); - ps.expect_char('\n')?; + if !ps.current_is('#') || level != get_comment_level(ps)? { + break; + } else { + get_comment_start(ps, &level)?; + } + } - Ok(ast::Entry::Section { - name: symb, - comment, - }) + match level { + CommentLevel::Comment => Ok(ast::Comment::Comment { content }), + CommentLevel::GroupComment => Ok(ast::Comment::GroupComment { content }), + CommentLevel::ResourceComment => Ok(ast::Comment::ResourceComment { content }), + } } fn get_message(ps: &mut ParserStream, comment: Option) -> Result @@ -261,12 +257,12 @@ where return Ok(ast::VarKey::Number(get_number(ps)?)); } _ => { - return Ok(ast::VarKey::Symbol(get_symbol(ps)?)); + return Ok(ast::VarKey::VariantName(get_variant_name(ps)?)); } } } else { return error!(ErrorKind::ExpectedField { - field: "Symbol | Number".to_owned(), + field: "VariantName | Number".to_owned(), }); } } @@ -323,7 +319,7 @@ where Ok(variants) } -fn get_symbol(ps: &mut ParserStream) -> Result +fn get_variant_name(ps: &mut ParserStream) -> Result where I: Iterator, { @@ -339,7 +335,7 @@ where name.pop(); } - Ok(ast::Symbol { name }) + Ok(ast::VariantName { name }) } fn get_digits(ps: &mut ParserStream) -> Result diff --git a/tests/fixtures/parser/ftl/03-comments.ftl b/tests/fixtures/parser/ftl/03-comments.ftl index 8c82e61d..de4baa2f 100644 --- a/tests/fixtures/parser/ftl/03-comments.ftl +++ b/tests/fixtures/parser/ftl/03-comments.ftl @@ -1,20 +1,22 @@ -// File comment +### File comment -// Standalone comment +# Standalone comment -// Another standalone comment +# Another standalone comment -//Comment with no leading space +# Comment with a leading space -// Comment with a leading space +## Multi +## Line Section +## +## Comment -//Multi -//Line -//Comment - -//Comment for entity key1 +# Comment for entity key1 key1 = New entity -//Comment for entity key2 +# Comment for entity key2 key2= | Multi line message + +## Group comment +key3 = Message diff --git a/tests/fixtures/parser/ftl/04-sections.ftl b/tests/fixtures/parser/ftl/04-sections.ftl deleted file mode 100644 index 5acc16b9..00000000 --- a/tests/fixtures/parser/ftl/04-sections.ftl +++ /dev/null @@ -1,10 +0,0 @@ -key1 = This entity is standalone - -[[ section1 ]] - -key2 = This entity belongs to section 1 - -// Section comment -[[ menu ]] - -key3 = This entity belongs to section 2 diff --git a/tests/fixtures/parser/ftl/05-variants.ftl b/tests/fixtures/parser/ftl/05-variants.ftl index 7fecb9b1..067cb1db 100644 --- a/tests/fixtures/parser/ftl/05-variants.ftl +++ b/tests/fixtures/parser/ftl/05-variants.ftl @@ -19,7 +19,7 @@ key5 key5 .m = Foo -[[ section ]] +## section key6 = {