Raku Books / Creating a Compiler in Raku / Dealing with Strings
Escaping quotes
It is quite obvious that the above-defined string cannot contain double quotes inside itself. Let us not allow using single quotes to delimit the string as Perl does, but only allow escaping the quote character inside a string:
say "Hello, \"World\"!";Currently, the parser stops at the second seen quote and terminates with an error:
Hello, \
Error: parse failedTo allow an escaped quote, the string rule must consume
all non-quote and non-backslash characters, and if it sees a backslash,
then only the sequence of \" is considered valid:
token string {
'"' ( [
| <-["\\]>+
| '\\"'
]* )
'"'
}We prefer a token over a rule from this moment to avoid skipping spaces after the opening quote.
In Raku, you can format the regexes freely enough to form some kind of ASCII graphics that helps better grasping of a regex. As we did it earlier, an additional vertical bar is added again to visualise the alternatives.
An escaped quote character is now allowed, but the backslash itself
became an illegal character in all other cases. Let’s add another escape
sequence, \\, to present a single backslash in a
string:
token string {
'"' ( [
| <-["\\]>+
| '\\"'
| '\\\\'
]* )
'"'
}All other sequences are not allowed, e.g., "\W" is an
error. Below are a few examples of valid strings with slashes and
quotes. A string may contain a newline or can be empty:
say "\\";
say "\"";
say "\\\\";
say "\"\"";
say "multi-
line";
say "";As we do not need an escaping backslash in the output, it should be removed from the string before passing it further:
method string($a) {
my $s = ~$a[0];
$s ~~ s:g/\\\"/"/;
$s ~~ s:g/\\\\/\\/;
$a.make($s);
}(Notice that we had to change the name of the method argument as
otherwise a runtime error occurs:
Cannot assign to a readonly variable ($/) or a value.)