Skip to content

Commit

Permalink
Fix nested escaped brackets (OpenDreamProject#1555)
Browse files Browse the repository at this point in the history
* Fix nested escaped brackets

* Put `DM_ConstantString` in correct alphabetic order

* Update DMCompiler/Compiler/DM/DMParserHelper.cs
  • Loading branch information
wixoaGit authored Dec 17, 2023
1 parent 4801639 commit 577e789
Show file tree
Hide file tree
Showing 10 changed files with 322 additions and 338 deletions.
4 changes: 4 additions & 0 deletions Content.Tests/DMProject/Tests/Text/NestedEscapedBracket.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Issue #700

/proc/RunTest()
ASSERT("[ "\[" ]" == @"[")
49 changes: 11 additions & 38 deletions DMCompiler/Compiler/DM/DMLexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ protected override Token ParseNextToken() {
string tokenText = preprocToken.Text;
switch (preprocToken.Text[0]) {
case '"':
case '{': token = CreateToken(TokenType.DM_String, tokenText, preprocToken.Value); break;
case '{': token = CreateToken(TokenType.DM_ConstantString, tokenText, preprocToken.Value); break;
case '\'': token = CreateToken(TokenType.DM_Resource, tokenText, preprocToken.Value); break;
case '@': token = CreateToken(TokenType.DM_RawString, tokenText, preprocToken.Value); break;
default: token = CreateToken(TokenType.Error, tokenText, "Invalid string"); break;
Expand All @@ -246,45 +246,18 @@ protected override Token ParseNextToken() {
Advance();
break;
}
case TokenType.DM_Preproc_String: {
string tokenText = preprocToken.Text;

string? stringStart = null, stringEnd = null;
switch (preprocToken.Text[0]) {
case '"': stringStart = "\""; stringEnd = "\""; break;
case '{': stringStart = "{\""; stringEnd = "\"}"; break;
}

if (stringStart != null && stringEnd != null) {
TokenTextBuilder.Clear();
TokenTextBuilder.Append(tokenText);

int stringNesting = 1;
while (!AtEndOfSource) {
Token stringToken = Advance();

TokenTextBuilder.Append(stringToken.Text);
if (stringToken.Type == TokenType.DM_Preproc_String) {
if (stringToken.Text.StartsWith(stringStart)) {
stringNesting++;
} else if (stringToken.Text.EndsWith(stringEnd)) {
stringNesting--;

if (stringNesting == 0) break;
}
}
}

string stringText = TokenTextBuilder.ToString();
string stringValue = stringText.Substring(stringStart.Length, stringText.Length - stringStart.Length - stringEnd.Length);
token = CreateToken(TokenType.DM_String, stringText, stringValue);
} else {
token = CreateToken(TokenType.Error, tokenText, "Invalid string");
}

case TokenType.DM_Preproc_StringBegin:
token = CreateToken(TokenType.DM_StringBegin, preprocToken.Text, preprocToken.Value);
Advance();
break;
case TokenType.DM_Preproc_StringMiddle:
token = CreateToken(TokenType.DM_StringMiddle, preprocToken.Text, preprocToken.Value);
Advance();
break;
case TokenType.DM_Preproc_StringEnd:
token = CreateToken(TokenType.DM_StringEnd, preprocToken.Text, preprocToken.Value);
Advance();
break;
}
case TokenType.DM_Preproc_Identifier: {
TokenTextBuilder.Clear();

Expand Down
6 changes: 5 additions & 1 deletion DMCompiler/Compiler/DM/DMParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2141,6 +2141,7 @@ public void ExpressionTo(out DMASTExpression? endRange, out DMASTExpression? ste
primary = ParseProcCall(primary);
}
}

if (primary == null && Check(TokenType.DM_Call)) {
Whitespace();
DMASTCallParameter[]? callParameters = ProcCall();
Expand All @@ -2164,7 +2165,10 @@ public void ExpressionTo(out DMASTExpression? endRange, out DMASTExpression? ste
case TokenType.DM_Resource: Advance(); return new DMASTConstantResource(constantToken.Location, (string)constantToken.Value);
case TokenType.DM_Null: Advance(); return new DMASTConstantNull(constantToken.Location);
case TokenType.DM_RawString: Advance(); return new DMASTConstantString(constantToken.Location, (string)constantToken.Value);
case TokenType.DM_String: return ExpressionFromString(constantToken);
case TokenType.DM_ConstantString:
case TokenType.DM_StringBegin:
// Don't advance, ExpressionFromString() will handle it
return ExpressionFromString();
default: return null;
}
}
Expand Down
Loading

0 comments on commit 577e789

Please sign in to comment.