@@ -930,26 +930,51 @@ auto lex_line(
930
930
return 0 ;
931
931
};
932
932
933
+ // G simple-hexadecimal-digit-sequence:
934
+ // G hexadecimal-digit
935
+ // G simple-hexadecimal-digit-sequence hexadecimal-digit
936
+ // G
933
937
// G hexadecimal-escape-sequence:
934
938
// G '\x' hexadecimal-digit
935
939
// G hexadecimal-escape-sequence hexadecimal-digit
940
+ // G '\x{' simple-hexadecimal-digit-sequence '}'
936
941
// G
937
942
auto peek_is_hexadecimal_escape_sequence = [&](int offset)
938
943
{
939
944
if (
940
- peek ( offset) == ' \\ '
945
+ peek (offset) == ' \\ '
941
946
&& peek (1 +offset) == ' x'
942
- && is_hexadecimal_digit (peek (2 +offset))
947
+ && (
948
+ is_hexadecimal_digit (peek (2 +offset))
949
+ || (peek (2 +offset) == ' {' && is_hexadecimal_digit (peek (3 +offset)))
950
+ )
943
951
)
944
952
{
953
+ auto has_bracket = peek (2 +offset) == ' {' ;
945
954
auto j = 3 ;
955
+
956
+ if (has_bracket) { ++j; }
957
+
946
958
while (
947
959
peek (j+offset)
948
960
&& is_hexadecimal_digit (peek (j+offset))
949
961
)
950
962
{
951
963
++j;
952
964
}
965
+
966
+ if (has_bracket) {
967
+ if (peek (j+offset) == ' }' ) {
968
+ ++j;
969
+ } else {
970
+ errors.emplace_back (
971
+ source_position (lineno, i + offset),
972
+ " invalid hexadecimal escape sequence - \\ x{ must"
973
+ " be followed by hexadecimal digits and a closing }"
974
+ );
975
+ return 0 ;
976
+ }
977
+ }
953
978
return j;
954
979
}
955
980
return 0 ;
@@ -958,6 +983,7 @@ auto lex_line(
958
983
// G universal-character-name:
959
984
// G '\u' hex-quad
960
985
// G '\U' hex-quad hex-quad
986
+ // G '\u{' simple-hexadecimal-digit-sequence '}'
961
987
// G
962
988
// G hex-quad:
963
989
// G hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit
@@ -967,6 +993,7 @@ auto lex_line(
967
993
if (
968
994
peek (offset) == ' \\ '
969
995
&& peek (1 + offset) == ' u'
996
+ && peek (2 + offset) != ' {'
970
997
)
971
998
{
972
999
auto j = 2 ;
@@ -980,11 +1007,41 @@ auto lex_line(
980
1007
if (j == 6 ) { return j; }
981
1008
errors.emplace_back (
982
1009
source_position ( lineno, i + offset ),
983
- " invalid universal character name ( \\ u must"
984
- " be followed by 4 hexadecimal digits) "
1010
+ " invalid universal character name - \\ u without { must"
1011
+ " be followed by 4 hexadecimal digits"
985
1012
);
986
1013
}
987
- if (
1014
+
1015
+ else if (
1016
+ peek (offset) == ' \\ '
1017
+ && peek (1 + offset) == ' u'
1018
+ && peek (2 + offset) == ' {'
1019
+ )
1020
+ {
1021
+ auto j = 4 ;
1022
+
1023
+ while (
1024
+ peek (j + offset)
1025
+ && is_hexadecimal_digit (peek (j + offset))
1026
+ )
1027
+ {
1028
+ ++j;
1029
+ }
1030
+
1031
+ if (peek (j + offset) == ' }' ) {
1032
+ ++j;
1033
+ }
1034
+ else {
1035
+ errors.emplace_back (
1036
+ source_position (lineno, i + offset),
1037
+ " invalid universal character name - \\ u{ must"
1038
+ " be followed by hexadecimal digits and a closing }"
1039
+ );
1040
+ }
1041
+ return j;
1042
+ }
1043
+
1044
+ else if (
988
1045
peek (offset) == ' \\ '
989
1046
&& peek (1 +offset) == ' U'
990
1047
)
@@ -1000,8 +1057,8 @@ auto lex_line(
1000
1057
if (j == 10 ) { return j; }
1001
1058
errors.emplace_back (
1002
1059
source_position (lineno, i+offset),
1003
- " invalid universal character name ( \\ U must"
1004
- " be followed by 8 hexadecimal digits) "
1060
+ " invalid universal character name - \\ U must"
1061
+ " be followed by 8 hexadecimal digits"
1005
1062
);
1006
1063
}
1007
1064
return 0 ;
0 commit comments