Skip to content

Commit cb1c179

Browse files
committed
add-escaping
Signed-off-by: yaacov <kobi.zamir@gmail.com>
1 parent 815036f commit cb1c179

File tree

64 files changed

+322
-581
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+322
-581
lines changed

v6/cmd/tsl/printer.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"fmt"
5+
"strconv"
56
"time"
67

78
"github.com/yaacov/tree-search-language/v6/pkg/tsl"
@@ -36,12 +37,30 @@ func (p *ASTPrinter) Print(node *tsl.TSLNode, level int) {
3637
p.printArray(node, level)
3738
case tsl.KindTimestampLiteral:
3839
p.printTimestamp(node, level)
40+
case tsl.KindStringLiteral:
41+
p.printString(node, level)
3942
default:
4043
// Leaf nodes
4144
p.printIndented(level, "[%s]: %v\n", t.String(), node.Value())
4245
}
4346
}
4447

48+
// printString formats and prints string values with escaped special characters
49+
func (p *ASTPrinter) printString(node *tsl.TSLNode, level int) {
50+
str, ok := node.Value().(string)
51+
if !ok {
52+
p.printIndented(level, "[%s]: %v\n", node.Type().String(), node.Value())
53+
return
54+
}
55+
56+
// Use Go's built-in escaping functionality
57+
quoted := strconv.Quote(str)
58+
// Remove the surrounding quotes to get just the escaped string
59+
escaped := quoted[1 : len(quoted)-1]
60+
61+
p.printIndented(level, "[%s]: %s\n", node.Type().String(), escaped)
62+
}
63+
4564
func (p *ASTPrinter) printBinaryOp(node *tsl.TSLNode, level int) {
4665
v := node.Value().(tsl.TSLExpressionOp)
4766

v6/pkg/parser/tsl_lexer.l

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,44 @@ int check_date_formats(char *s) {
2828
return 0;
2929
}
3030

31+
/* Process escaped characters in a string */
32+
char* process_escapes(char* text, int len) {
33+
char* result = malloc(len + 1);
34+
int i, j = 0;
35+
36+
for (i = 0; i < len; i++) {
37+
if (text[i] == '\\' && i + 1 < len) {
38+
i++; // Skip backslash
39+
switch (text[i]) {
40+
case 'n': result[j++] = '\n'; break;
41+
case 't': result[j++] = '\t'; break;
42+
case 'r': result[j++] = '\r'; break;
43+
case 'b': result[j++] = '\b'; break;
44+
case 'f': result[j++] = '\f'; break;
45+
case '\\': result[j++] = '\\'; break;
46+
case '\'': result[j++] = '\''; break;
47+
case '\"': result[j++] = '\"'; break;
48+
case '`': result[j++] = '`'; break;
49+
default: result[j++] = text[i]; break;
50+
}
51+
} else {
52+
result[j++] = text[i];
53+
}
54+
}
55+
result[j] = '\0';
56+
return result;
57+
}
58+
3159
/* Strip quotes and process string */
3260
char* strip_quotes(char* text, int offset) {
33-
int len = strlen(text);
34-
char *s = malloc(len - 1);
35-
strncpy(s, text + offset, len - (offset * 2));
36-
s[len - (offset * 2)] = '\0';
37-
return s;
61+
int len = strlen(text) - (offset * 2);
62+
char *raw = malloc(len + 1);
63+
strncpy(raw, text + offset, len);
64+
raw[len] = '\0';
65+
66+
char *processed = process_escapes(raw, len);
67+
free(raw);
68+
return processed;
3869
}
3970
%}
4071

@@ -110,23 +141,23 @@ NUMBER_WITH_SUFFIX ({INTEGER}|{DECIMAL}){SIZE_SUFFIX}
110141
{NUMBER_WITH_SUFFIX} { yylval.str = strdup(yytext); return NUMERIC_LITERAL; }
111142

112143
/* String literals and identifiers */
113-
'[^']*' {
144+
'([^'\\]|\\.)*' {
114145
char *s = strip_quotes(yytext, 1);
115146
int token = check_date_formats(s);
116147
if (token) return token;
117148
yylval.str = s;
118149
return STRING_LITERAL;
119150
}
120151

121-
\"[^"]*\" {
152+
\"([^"\\]|\\.)*\" {
122153
char *s = strip_quotes(yytext, 1);
123154
int token = check_date_formats(s);
124155
if (token) return token;
125156
yylval.str = s;
126157
return STRING_LITERAL;
127158
}
128159

129-
`[^`]*` {
160+
`([^`\\]|\\.)*` {
130161
char *s = strip_quotes(yytext, 1);
131162
int token = check_date_formats(s);
132163
if (token) return token;

0 commit comments

Comments
 (0)