Add backslash escape codes - close #19
This commit is contained in:
parent
1d1590dfda
commit
5b2cbe53e6
@ -325,9 +325,16 @@ Regular expressions can include many special characters:
|
|||||||
* The `(` character begins a matching group.
|
* The `(` character begins a matching group.
|
||||||
* The `{` character begins a count qualifier.
|
* The `{` character begins a count qualifier.
|
||||||
* The `\` character escapes the following character and changes its meaning:
|
* The `\` character escapes the following character and changes its meaning:
|
||||||
|
* The `\a` sequence matches an ASCII bell character (0x07).
|
||||||
|
* The `\b` sequence matches an ASCII backspace character (0x08).
|
||||||
* The `\d` sequence matches any character `0` through `9`.
|
* The `\d` sequence matches any character `0` through `9`.
|
||||||
|
* The `\f` sequence matches an ASCII form feed character (0x0C).
|
||||||
|
* The `\n` sequence matches an ASCII new line character (0x0A).
|
||||||
|
* The `\r` sequence matches an ASCII carriage return character (0x0D).
|
||||||
* The `\s` sequence matches a space, horizontal tab `\t`, carriage return
|
* The `\s` sequence matches a space, horizontal tab `\t`, carriage return
|
||||||
`\r`, a form feed `\f`, or a vertical tab `\v` character.
|
`\r`, a form feed `\f`, or a vertical tab `\v` character.
|
||||||
|
* The `\t` sequence matches an ASCII tab character (0x09).
|
||||||
|
* The `\v` sequence matches an ASCII vertical tab character (0x0B).
|
||||||
* Any other character matches itself.
|
* Any other character matches itself.
|
||||||
* The `|` character creates an alternate match.
|
* The `|` character creates an alternate match.
|
||||||
|
|
||||||
|
@ -134,8 +134,18 @@ class Propane
|
|||||||
else
|
else
|
||||||
c = @pattern.slice!(0)
|
c = @pattern.slice!(0)
|
||||||
case c
|
case c
|
||||||
|
when "a"
|
||||||
|
CharacterRangeUnit.new("\a", "\a")
|
||||||
|
when "b"
|
||||||
|
CharacterRangeUnit.new("\b", "\b")
|
||||||
when "d"
|
when "d"
|
||||||
CharacterRangeUnit.new("0", "9")
|
CharacterRangeUnit.new("0", "9")
|
||||||
|
when "f"
|
||||||
|
CharacterRangeUnit.new("\f", "\f")
|
||||||
|
when "n"
|
||||||
|
CharacterRangeUnit.new("\n", "\n")
|
||||||
|
when "r"
|
||||||
|
CharacterRangeUnit.new("\r", "\r")
|
||||||
when "s"
|
when "s"
|
||||||
ccu = CharacterClassUnit.new
|
ccu = CharacterClassUnit.new
|
||||||
ccu << CharacterRangeUnit.new(" ")
|
ccu << CharacterRangeUnit.new(" ")
|
||||||
@ -145,6 +155,10 @@ class Propane
|
|||||||
ccu << CharacterRangeUnit.new("\f")
|
ccu << CharacterRangeUnit.new("\f")
|
||||||
ccu << CharacterRangeUnit.new("\v")
|
ccu << CharacterRangeUnit.new("\v")
|
||||||
ccu
|
ccu
|
||||||
|
when "t"
|
||||||
|
CharacterRangeUnit.new("\t", "\t")
|
||||||
|
when "v"
|
||||||
|
CharacterRangeUnit.new("\v", "\v")
|
||||||
else
|
else
|
||||||
CharacterRangeUnit.new(c)
|
CharacterRangeUnit.new(c)
|
||||||
end
|
end
|
||||||
|
@ -768,6 +768,89 @@ EOF
|
|||||||
expect(results.stderr).to eq ""
|
expect(results.stderr).to eq ""
|
||||||
expect(results.status).to eq 0
|
expect(results.status).to eq 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "matches backslash escape sequences" do
|
||||||
|
case language
|
||||||
|
when "c"
|
||||||
|
write_grammar <<EOF
|
||||||
|
<<
|
||||||
|
#include <stdio.h>
|
||||||
|
>>
|
||||||
|
tokenid t;
|
||||||
|
/\\a/ <<
|
||||||
|
printf("A\\n");
|
||||||
|
>>
|
||||||
|
/\\b/ <<
|
||||||
|
printf("B\\n");
|
||||||
|
>>
|
||||||
|
/\\t/ <<
|
||||||
|
printf("T\\n");
|
||||||
|
>>
|
||||||
|
/\\n/ <<
|
||||||
|
printf("N\\n");
|
||||||
|
>>
|
||||||
|
/\\v/ <<
|
||||||
|
printf("V\\n");
|
||||||
|
>>
|
||||||
|
/\\f/ <<
|
||||||
|
printf("F\\n");
|
||||||
|
>>
|
||||||
|
/\\r/ <<
|
||||||
|
printf("R\\n");
|
||||||
|
>>
|
||||||
|
/t/ <<
|
||||||
|
return $token(t);
|
||||||
|
>>
|
||||||
|
Start -> t;
|
||||||
|
EOF
|
||||||
|
when "d"
|
||||||
|
write_grammar <<EOF
|
||||||
|
<<
|
||||||
|
import std.stdio;
|
||||||
|
>>
|
||||||
|
tokenid t;
|
||||||
|
/\\a/ <<
|
||||||
|
writeln("A");
|
||||||
|
>>
|
||||||
|
/\\b/ <<
|
||||||
|
writeln("B");
|
||||||
|
>>
|
||||||
|
/\\t/ <<
|
||||||
|
writeln("T");
|
||||||
|
>>
|
||||||
|
/\\n/ <<
|
||||||
|
writeln("N");
|
||||||
|
>>
|
||||||
|
/\\v/ <<
|
||||||
|
writeln("V");
|
||||||
|
>>
|
||||||
|
/\\f/ <<
|
||||||
|
writeln("F");
|
||||||
|
>>
|
||||||
|
/\\r/ <<
|
||||||
|
writeln("R");
|
||||||
|
>>
|
||||||
|
/t/ <<
|
||||||
|
return $token(t);
|
||||||
|
>>
|
||||||
|
Start -> t;
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
build_parser(language: language)
|
||||||
|
compile("spec/test_match_backslashes.#{language}", language: language)
|
||||||
|
results = run
|
||||||
|
expect(results.stderr).to eq ""
|
||||||
|
expect(results.status).to eq 0
|
||||||
|
verify_lines(results.stdout, [
|
||||||
|
"A",
|
||||||
|
"B",
|
||||||
|
"T",
|
||||||
|
"N",
|
||||||
|
"V",
|
||||||
|
"F",
|
||||||
|
"R",
|
||||||
|
])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
13
spec/test_match_backslashes.c
Normal file
13
spec/test_match_backslashes.c
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "testparser.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
char const * input = "\a\b\t\n\v\f\rt";
|
||||||
|
p_context_t context;
|
||||||
|
p_context_init(&context, (uint8_t const *)input, strlen(input));
|
||||||
|
assert(p_parse(&context) == P_SUCCESS);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
15
spec/test_match_backslashes.d
Normal file
15
spec/test_match_backslashes.d
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import testparser;
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
string input = "\a\b\t\n\v\f\rt";
|
||||||
|
p_context_t context;
|
||||||
|
p_context_init(&context, input);
|
||||||
|
assert(p_parse(&context) == P_SUCCESS);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user