Skip to content

Commit

Permalink
fix #485
Browse files Browse the repository at this point in the history
  • Loading branch information
b3b00 committed Oct 10, 2024
1 parent e3f5f5b commit fe72161
Show file tree
Hide file tree
Showing 11 changed files with 179 additions and 8 deletions.
7 changes: 5 additions & 2 deletions src/sly/lexer/CallBacksBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ public static void BuildCallbacks<IN>(GenericLexer<IN> lexer) where IN : struct
{
var attributes =
(CallBacksAttribute[]) typeof(IN).GetCustomAttributes(typeof(CallBacksAttribute), true);
Type callbackClass = attributes[0].CallBacksClass;
ExtractCallBacks<IN>(callbackClass,lexer);
if (attributes.Length > 0)
{
Type callbackClass = attributes[0].CallBacksClass;
ExtractCallBacks<IN>(callbackClass, lexer);
}

}

Expand Down
22 changes: 19 additions & 3 deletions src/sly/lexer/GenericLexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -794,15 +794,31 @@ public ReadOnlyMemory<char> diffCharEscaper(char escapeStringDelimiterChar, char
var value = stringValue;
string newValue = "";
int i = 0;
bool escaping = false;
while (i < value.Length)
{
char current = value.At(i);
if (current == escapeStringDelimiterChar)
if (current == escapeStringDelimiterChar && !escaping)
{
escaping = true;
}
else if (escaping)
{
if (escaping)
{
if (current != stringDelimiterChar)
{
newValue += escapeStringDelimiterChar;
}
}
escaping = false;
}

if (!escaping)
{
i++;
newValue += value.At(i);
}

newValue += value.At(i);
i++;

}
Expand Down
5 changes: 4 additions & 1 deletion src/sly/parser/generator/ParserBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,10 @@ protected virtual BuildResult<ILexer<IN>> BuildLexer(
{
var lexer = LexerBuilder.BuildLexer<IN>(new BuildResult<ILexer<IN>>(), extensionBuilder, I18N,
lexerPostProcess, explicitTokens);

if (lexer.IsOk && lexer.Result != null && lexer.Result is GenericLexer<IN> genericLexer)
{
CallBacksBuilder.BuildCallbacks(genericLexer);
}
return lexer;
}

Expand Down
10 changes: 10 additions & 0 deletions tests/ParserTests/Issue485/Issue485Lexer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using sly.lexer;

namespace ParserTests.Issue485;

public enum Issue485Lexer
{
[Sugar(":")] COLON,
[Keyword("Property")] PROPERTY,
[String] STRING
}
14 changes: 14 additions & 0 deletions tests/ParserTests/Issue485/Issue485Parser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using sly.lexer;
using sly.parser.generator;

namespace ParserTests.Issue485;

[ParserRoot("root")]
public class Issue485Parser
{
[Production("root : PROPERTY[d] COLON[d] STRING")]
public string Parse(Token<Issue485Lexer> str)
{
return str.StringWithoutQuotes;
}
}
10 changes: 10 additions & 0 deletions tests/ParserTests/Issue485/Issue485SelfEscapeLexer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using sly.lexer;

namespace ParserTests.Issue485;

public enum Issue485SelfEscapeLexer
{
[Sugar(":")] COLON,
[Keyword("Property")] PROPERTY,
[String("\"","\"")] STRING
}
14 changes: 14 additions & 0 deletions tests/ParserTests/Issue485/Issue485SelfEscapeParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using sly.lexer;
using sly.parser.generator;

namespace ParserTests.Issue485;

[ParserRoot("root")]
public class Issue485SelfEscapeParser
{
[Production("root : PROPERTY[d] COLON[d] STRING")]
public string Parse(Token<Issue485SelfEscapeLexer> str)
{
return str.StringWithoutQuotes;
}
}
55 changes: 55 additions & 0 deletions tests/ParserTests/Issue485/Issue485Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using NFluent;
using sly.parser.generator;
using Xunit;

namespace ParserTests.Issue485;

public class Issue485Tests
{
[Fact]
public void TestIssue485()
{
var builder = new ParserBuilder<Issue485Lexer, string>();
var build = builder.BuildParser(new Issue485Parser(), ParserType.EBNF_LL_RECURSIVE_DESCENT,"root");
Check.That(build).IsOk();
var parser = build.Result;
Check.That(parser).IsNotNull();
var parsed = parser.Parse("Property: \"Hello \\\"There\\\"\\nSecond line\"");
Check.That(parsed).IsOkParsing();
var result = parsed.Result;
Check.That(result).IsNotNull();
Check.That(result).IsNotEmpty();
Check.That(result).Equals("Hello \"There\"\\nSecond line");
}
[Fact]
public void TestIssue485SelfEscape()
{
var builder = new ParserBuilder<Issue485SelfEscapeLexer, string>();
var build = builder.BuildParser(new Issue485SelfEscapeParser(), ParserType.EBNF_LL_RECURSIVE_DESCENT,"root");
Check.That(build).IsOk();
var parser = build.Result;
Check.That(parser).IsNotNull();
var parsed = parser.Parse("Property: \"Hello \"\"There\"\"\\nSecond line\"");
Check.That(parsed).IsOkParsing();
var result = parsed.Result;
Check.That(result).IsNotNull();
Check.That(result).IsNotEmpty();
Check.That(result).Equals("Hello \"There\"\\nSecond line");
}

[Fact]
public void TestIssue485WithCallback()
{
var builder = new ParserBuilder<Issue485WithCallbackLexer, string>();
var build = builder.BuildParser(new Issue485WithCallbackParser(), ParserType.EBNF_LL_RECURSIVE_DESCENT,"root");
Check.That(build).IsOk();
var parser = build.Result;
Check.That(parser).IsNotNull();
var parsed = parser.Parse("Property: \"Hello \\\"There\\\"\\nSecond line\"");
Check.That(parsed).IsOkParsing();
var result = parsed.Result;
Check.That(result).IsNotNull();
Check.That(result).IsNotEmpty();
Check.That(result).Equals("Hello \"There\"\nSecond line");
}
}
29 changes: 29 additions & 0 deletions tests/ParserTests/Issue485/Issue485WithCallbackLexer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using sly.lexer;

namespace ParserTests.Issue485;

[CallBacks(typeof(Issue485Callbacks))]
public enum Issue485WithCallbackLexer
{
[Sugar(":")] COLON,
[Keyword("Property")] PROPERTY,
[String] STRING
}

public class Issue485Callbacks
{

[TokenCallback((int)Issue485WithCallbackLexer.STRING)]
public static Token<Issue485WithCallbackLexer> EscapeEscapedSequences(Token<Issue485WithCallbackLexer> token)
{
string value = token.Value;

value = value.Replace("\\n", "\n");
value = value.Replace("\\r", "\r");
value = value.Replace("\\t", "\t");
value = value.Replace("\\\\", "\\");
token.SpanValue = new ReadOnlyMemory<char>(value.ToCharArray());
return token;
}
}
14 changes: 14 additions & 0 deletions tests/ParserTests/Issue485/Issue485WithCallbackParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using sly.lexer;
using sly.parser.generator;

namespace ParserTests.Issue485;

[ParserRoot("root")]
public class Issue485WithCallbackParser
{
[Production("root : PROPERTY[d] COLON[d] STRING")]
public string Parse(Token<Issue485WithCallbackLexer> str)
{
return str.StringWithoutQuotes;
}
}
7 changes: 5 additions & 2 deletions tests/ParserTests/lexer/GenericLexerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -591,8 +591,9 @@ public void TestIssue348()
Check.That(r.Tokens).CountIs(2);
var tok = r.Tokens[0];
Check.That(tok.TokenID).IsEqualTo(Issue348.STriNG);
Check.That(tok.Value).IsEqualTo("\"\"te\\\\st\"\"");
Check.That(tok.StringWithoutQuotes).IsEqualTo("\"te\\\\st\"");
Check.That(tok.StringWithoutQuotes).IsEqualTo("\"te\\\\\\\\st\"");
Check.That(tok.Value).IsEqualTo("\"\"te\\\\\\\\st\"\"");

}

[Fact]
Expand Down Expand Up @@ -809,6 +810,7 @@ public void TestTokenCallbacks()
Check.That(tokens[0]).IsEqualTo(CallbackTokens.IDENTIFIER, "AAA");
Check.That(tokens[1]).IsEqualTo(CallbackTokens.SKIP, "BBB");
}


[Fact]
public void TestCharTokens()
Expand Down Expand Up @@ -1336,5 +1338,6 @@ public void TestI18nDuplicateLabel()
Check.That(error.Message).Contains("left paranthesis").And.Contains("paranthèse ouvrante");
}


}
}

0 comments on commit fe72161

Please sign in to comment.