diff --git a/spec/fluent.ebnf b/spec/fluent.ebnf index 01d56f7..13a16f2 100644 --- a/spec/fluent.ebnf +++ b/spec/fluent.ebnf @@ -102,8 +102,9 @@ any_char ::= [\\u{9}\\u{20}-\\u{D7FF}\\u{E000}-\\u{FFFD}] * new line. */ special_text_char ::= "{" + | "}" text_char ::= any_char - special_text_char -indented_char ::= text_char - "}" - "[" - "*" - "." +indented_char ::= text_char - "[" - "*" - "." /* String literals * diff --git a/syntax/grammar.mjs b/syntax/grammar.mjs index aa99b7b..e52f2f9 100644 --- a/syntax/grammar.mjs +++ b/syntax/grammar.mjs @@ -397,7 +397,9 @@ let any_char = */ let special_text_char = - string("{"); + either( + string("{"), + string("}")); let text_char = and( @@ -409,7 +411,6 @@ let indented_char = not(string(".")), not(string("*")), not(string("[")), - not(string("}")), text_char); /* -------------------------------------------------------------------------- */ diff --git a/test/fixtures/escaped_characters.ftl b/test/fixtures/escaped_characters.ftl index 3c64fce..5242a4b 100644 --- a/test/fixtures/escaped_characters.ftl +++ b/test/fixtures/escaped_characters.ftl @@ -19,4 +19,4 @@ string-escaped-unicode = {"\\u0041"} ## Literal braces brace-open = An opening {"{"} brace. -brace-close = A closing } brace. +brace-close = A closing {"}"} brace. diff --git a/test/fixtures/escaped_characters.json b/test/fixtures/escaped_characters.json index 6c26f82..26b1974 100644 --- a/test/fixtures/escaped_characters.json +++ b/test/fixtures/escaped_characters.json @@ -259,7 +259,18 @@ "elements": [ { "type": "TextElement", - "value": "A closing } brace." + "value": "A closing " + }, + { + "type": "Placeable", + "expression": { + "type": "StringLiteral", + "value": "}" + } + }, + { + "type": "TextElement", + "value": " brace." } ] }, diff --git a/test/fixtures/placeables.ftl b/test/fixtures/placeables.ftl index c0e515b..7a1b280 100644 --- a/test/fixtures/placeables.ftl +++ b/test/fixtures/placeables.ftl @@ -1,3 +1,15 @@ nested-placeable = {{{1}}} padded-placeable = { 1 } sparse-placeable = { { 1 } } + +# ERROR Unmatched opening brace +unmatched-open1 = { 1 + +# ERROR Unmatched opening brace +unmatched-open2 = {{ 1 } + +# ERROR Unmatched closing brace +unmatched-close1 = 1 } + +# ERROR Unmatched closing brace +unmatched-close2 = { 1 }} diff --git a/test/fixtures/placeables.json b/test/fixtures/placeables.json index c0e7cc9..ff7fac8 100644 --- a/test/fixtures/placeables.json +++ b/test/fixtures/placeables.json @@ -72,6 +72,42 @@ }, "attributes": [], "comment": null + }, + { + "type": "Comment", + "content": "ERROR Unmatched opening brace" + }, + { + "type": "Junk", + "annotations": [], + "content": "unmatched-open1 = { 1\n" + }, + { + "type": "Comment", + "content": "ERROR Unmatched opening brace" + }, + { + "type": "Junk", + "annotations": [], + "content": "unmatched-open2 = {{ 1 }\n" + }, + { + "type": "Comment", + "content": "ERROR Unmatched closing brace" + }, + { + "type": "Junk", + "annotations": [], + "content": "unmatched-close1 = 1 }\n" + }, + { + "type": "Comment", + "content": "ERROR Unmatched closing brace" + }, + { + "type": "Junk", + "annotations": [], + "content": "unmatched-close2 = { 1 }}\n" } ] } diff --git a/test/fixtures/select_expressions.ftl b/test/fixtures/select_expressions.ftl index 3c54f57..859c01a 100644 --- a/test/fixtures/select_expressions.ftl +++ b/test/fixtures/select_expressions.ftl @@ -34,3 +34,8 @@ nested-variant-list = *[two] Value } } + +# ERROR Missing line end after variant list +missing-line-end = + { 1 -> + *[one] One} diff --git a/test/fixtures/select_expressions.json b/test/fixtures/select_expressions.json index 13f5b71..4c78200 100644 --- a/test/fixtures/select_expressions.json +++ b/test/fixtures/select_expressions.json @@ -257,6 +257,15 @@ "type": "Junk", "annotations": [], "content": "nested-variant-list =\n { 1 ->\n *[one] {\n *[two] Value\n }\n }\n" + }, + { + "type": "Comment", + "content": "ERROR Missing line end after variant list" + }, + { + "type": "Junk", + "annotations": [], + "content": "missing-line-end =\n { 1 ->\n *[one] One}\n" } ] }