diff --git a/.gitattributes b/.gitattributes index 0411e5e..2880b6e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ test/fixtures/crlf.ftl eol=crlf +test/fixtures/cr.ftl eol=cr diff --git a/spec/fluent.ebnf b/spec/fluent.ebnf index ad07904..45a57a4 100644 --- a/spec/fluent.ebnf +++ b/spec/fluent.ebnf @@ -19,7 +19,7 @@ Term ::= "-" Identifier blank_inline? "=" blank_inline? Value Att CommentLine ::= ("###" | "##" | "#") ("\u0020" /.*/)? line_end /* Adjacent junk_lines are joined into FTL.Junk during the AST construction. */ -junk_line ::= /.*/ line_end +junk_line ::= /[^\n]*/ ("\u000A" | EOF) /* Attributes of Messages and Terms. */ Attribute ::= line_end blank? "." Identifier blank_inline? "=" blank_inline? Pattern diff --git a/syntax/grammar.mjs b/syntax/grammar.mjs index bfa4e50..2e7898c 100644 --- a/syntax/grammar.mjs +++ b/syntax/grammar.mjs @@ -86,12 +86,14 @@ let CommentLine = defer(() => /* ------------------------------------------------------------------------- */ /* Adjacent junk_lines are joined into FTL.Junk during the AST construction. */ -let junk_line = defer(() => +let junk_line = sequence( - regex(/.*/), - line_end) + regex(/[^\n]*/), + either( + string("\u000A"), + eof())) .map(join) - .chain(into(FTL.Junk))); + .chain(into(FTL.Junk)); /* --------------------------------- */ /* Attributes of Messages and Terms. */ diff --git a/test/fixtures/cr.ftl b/test/fixtures/cr.ftl new file mode 100644 index 0000000..549c662 --- /dev/null +++ b/test/fixtures/cr.ftl @@ -0,0 +1 @@ +### This entire file uses CR as EOL. err01 = Value 01 err02 = Value 02 err03 = Value 03 Continued .title = Title err04 = { "str err05 = { $sel -> } \ No newline at end of file diff --git a/test/fixtures/cr.json b/test/fixtures/cr.json new file mode 100644 index 0000000..afec811 --- /dev/null +++ b/test/fixtures/cr.json @@ -0,0 +1,10 @@ +{ + "type": "Resource", + "body": [ + { + "type": "Junk", + "annotations": [], + "content": "### This entire file uses CR as EOL.\r\rerr01 = Value 01\rerr02 = Value 02\r\rerr03 =\r\r Value 03\r Continued\r\r .title = Title\r\rerr04 = { \"str\r\rerr05 = { $sel -> }\r" + } + ] +} diff --git a/test/fixtures/crlf.ftl b/test/fixtures/crlf.ftl index 7349195..df3a02c 100644 --- a/test/fixtures/crlf.ftl +++ b/test/fixtures/crlf.ftl @@ -1,7 +1,14 @@ + key01 = Value 01 key02 = + Value 02 Continued -# ERROR (Missing value or attributes) -key03 + .title = Title + +# ERROR Unclosed StringLiteral +err03 = { "str + +# ERROR Missing newline after ->. +err04 = { $sel -> } diff --git a/test/fixtures/crlf.json b/test/fixtures/crlf.json index a36838a..6b324cd 100644 --- a/test/fixtures/crlf.json +++ b/test/fixtures/crlf.json @@ -34,17 +34,43 @@ } ] }, - "attributes": [], + "attributes": [ + { + "type": "Attribute", + "id": { + "type": "Identifier", + "name": "title" + }, + "value": { + "type": "Pattern", + "elements": [ + { + "type": "TextElement", + "value": "Title" + } + ] + } + } + ], "comment": null }, { "type": "Comment", - "content": "ERROR (Missing value or attributes)" + "content": "ERROR Unclosed StringLiteral" + }, + { + "type": "Junk", + "annotations": [], + "content": "err03 = { \"str\r\n" + }, + { + "type": "Comment", + "content": "ERROR Missing newline after ->." }, { "type": "Junk", "annotations": [], - "content": "key03\n" + "content": "err04 = { $sel -> }\r\n" } ] }