Skip to content

Commit d6e30ce

Browse files
committed
Fix script text should not end if the rbrace ('}') is not the only one in line
According to structurizr dsl parser, the script ends once a line with a single rbrace ('}') is met. See https://github.com/structurizr/java/blob/39bf3d0890afc4caa52cf3302269a12fc2a4236b/structurizr-dsl/src/main/java/com/structurizr/dsl/StructurizrDslParser.java#L208
1 parent 98bf9a4 commit d6e30ce

File tree

2 files changed

+65
-27
lines changed

2 files changed

+65
-27
lines changed

src/main/grammar/StructurizrDSL.flex

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,6 @@ import static nl.dirkgroot.structurizr.dsl.psi.SDTypes.*;
1313
public StructurizrDSLLexer() {
1414
this(null);
1515
}
16-
17-
private void startScript() {
18-
braces = 0;
19-
yybegin(EXPECT_SCRIPT);
20-
}
21-
22-
private void endScript() {
23-
braces = 0;
24-
yybegin(YYINITIAL);
25-
}
26-
%}
27-
28-
%{
29-
private int braces = 0;
3016
%}
3117

3218
%ignorecase
@@ -61,7 +47,7 @@ LineComment=("/"{MultiLineSeparatorsWithSpaces}?"/"|"#") {NonCrLf}*
6147
BlockCommentStart="/"{MultiLineSeparatorsWithSpaces}?"*"
6248
BlockCommentEnd="*"{MultiLineSeparatorsWithSpaces}?"/"
6349

64-
ScriptText=[{NonEOL}--[{}]]+
50+
ScriptText=({EscapeOrMultiLineSeparator}|{NonEOL})
6551

6652
Arrow=-{MultiLineSeparatorsWithSpaces}?>
6753
%%
@@ -85,17 +71,18 @@ Arrow=-{MultiLineSeparatorsWithSpaces}?>
8571
}
8672

8773
<EXPECT_SCRIPT> {
88-
"{" { braces++; }
89-
"}" {
90-
if (braces == 0) {
91-
endScript();
92-
yypushback(1);
93-
return SCRIPT_TEXT;
94-
}
95-
braces--;
96-
}
97-
{CrLf} { }
98-
{ScriptText} { }
74+
{SpaceOrMultiLineSeparator}*\}{SpaceOrMultiLineSeparator}*{CrLf}? {
75+
int rbracePosExclusive = StringUtil.lastIndexOf(yytext(), '}', 0, yylength());
76+
yypushback(yylength() - rbracePosExclusive);
77+
yybegin(EXPECT_NON_COMMENT);
78+
return SCRIPT_TEXT;
79+
}
80+
{ScriptText}*{CrLf} { }
81+
{ScriptText}+ {
82+
// EOF met
83+
yybegin(YYINITIAL);
84+
return SCRIPT_TEXT;
85+
}
9986
}
10087

10188
// STATES
@@ -126,7 +113,7 @@ Arrow=-{MultiLineSeparatorsWithSpaces}?>
126113
}
127114

128115
<EXPECT_SCRIPT_ARGUMENTS> {
129-
"{" { startScript(); return BRACE1; }
116+
"{" { yybegin(EXPECT_SCRIPT); return BRACE1; }
130117
{QuotedText} { return QUOTED_TEXT; }
131118
{UnquotedText} { return UNQUOTED_TEXT; }
132119
[^] { yybegin(YYINITIAL); yypushback(yylength()); }

src/test/kotlin/nl/dirkgroot/structurizr/dsl/lexer/ScriptBlockTest.kt

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,57 @@ class ScriptBlockTest {
5252
)
5353
}
5454

55+
@Test
56+
fun `ends if multiline separator before rbrace`() {
57+
"""
58+
!script kotlin {
59+
some arbitrary code
60+
\
61+
}
62+
""".trimIndent().tokenize() shouldContainExactly listOf(
63+
UNQUOTED_TEXT to "!script",
64+
WHITE_SPACE to " ",
65+
UNQUOTED_TEXT to "kotlin",
66+
WHITE_SPACE to " ",
67+
BRACE1 to "{",
68+
SCRIPT_TEXT to "\n some arbitrary code\n\\\n",
69+
BRACE2 to "}"
70+
)
71+
}
72+
73+
@Test
74+
fun `does not end if the line contains other symbols before rbrace`() {
75+
"""
76+
!script kotlin {
77+
some arbitrary code
78+
test }
79+
""".trimIndent().tokenize() shouldContainExactly listOf(
80+
UNQUOTED_TEXT to "!script",
81+
WHITE_SPACE to " ",
82+
UNQUOTED_TEXT to "kotlin",
83+
WHITE_SPACE to " ",
84+
BRACE1 to "{",
85+
SCRIPT_TEXT to "\n some arbitrary code\ntest }",
86+
)
87+
}
88+
89+
@Test
90+
fun `does not end if the line contains other symbols after rbrace`() {
91+
"""
92+
!script kotlin {
93+
some arbitrary code
94+
} \
95+
test
96+
""".trimIndent().tokenize() shouldContainExactly listOf(
97+
UNQUOTED_TEXT to "!script",
98+
WHITE_SPACE to " ",
99+
UNQUOTED_TEXT to "kotlin",
100+
WHITE_SPACE to " ",
101+
BRACE1 to "{",
102+
SCRIPT_TEXT to "\n some arbitrary code\n} \\\ntest",
103+
)
104+
}
105+
55106
@Test
56107
fun `indented block`() {
57108
"""

0 commit comments

Comments
 (0)