regexp_parser 2.12.0 → 2.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,43 +11,10 @@ require_relative 'scanner/errors/premature_end_error'
11
11
  require_relative 'scanner/errors/validation_error'
12
12
 
13
13
  class Regexp::Scanner
14
- # Scans the given regular expression text, or Regexp object and collects the
15
- # emitted token into an array that gets returned at the end. If a block is
16
- # given, it gets called for each emitted token.
17
- #
18
- # This method may raise errors if a syntax error is encountered.
19
- # --------------------------------------------------------------------------
20
- def self.scan(input_object, options: nil, collect_tokens: true, &block)
21
- new.scan(input_object, options: options, collect_tokens: collect_tokens, &block)
22
- end
23
-
24
- def scan(input_object, options: nil, collect_tokens: true, &block)
25
- self.collect_tokens = collect_tokens
26
- self.literal_run = nil
27
- stack = []
14
+ # Emit fixed machine data once. The ragel task converts its generated
15
+ # accessors and tables to constants with frozen values.
28
16
 
29
- input = input_object.is_a?(Regexp) ? input_object.source : input_object
30
- self.free_spacing = free_spacing?(input_object, options)
31
- self.regexp_encoding = extract_encoding(input_object, options)
32
- self.spacing_stack = [{:free_spacing => free_spacing, :depth => 0}]
33
-
34
- data = input.unpack("c*")
35
- eof = data.length
36
-
37
- self.tokens = []
38
- self.block = block
39
-
40
- self.set_depth = 0
41
- self.group_depth = 0
42
- self.capturing_group_count = 0
43
- self.conditional_stack = []
44
- self.char_pos = 0
45
-
46
- class << self
47
- attr_accessor :_re_scanner_trans_keys
48
- private :_re_scanner_trans_keys, :_re_scanner_trans_keys=
49
- end
50
- self._re_scanner_trans_keys = [
17
+ RE_SCANNER_TRANS_KEYS = [
51
18
  0,0,-128,-65,-128,-65,
52
19
  -128,-65,41,41,39,
53
20
  57,39,39,33,62,
@@ -98,13 +65,9 @@ self._re_scanner_trans_keys = [
98
65
  92,39,60,39,57,
99
66
  48,57,41,57,33,62,
100
67
  0
101
- ]
68
+ ].freeze
102
69
 
103
- class << self
104
- attr_accessor :_re_scanner_key_spans
105
- private :_re_scanner_key_spans, :_re_scanner_key_spans=
106
- end
107
- self._re_scanner_key_spans = [
70
+ RE_SCANNER_KEY_SPANS = [
108
71
  0,64,64,64,1,19,1,30,
109
72
  1,22,19,1,10,19,10,19,
110
73
  30,1,10,20,10,15,22,19,
@@ -122,13 +85,9 @@ self._re_scanner_key_spans = [
122
85
  10,10,10,10,1,1,0,33,
123
86
  1,0,1,55,55,1,22,19,
124
87
  10,17,30
125
- ]
88
+ ].freeze
126
89
 
127
- class << self
128
- attr_accessor :_re_scanner_index_offsets
129
- private :_re_scanner_index_offsets, :_re_scanner_index_offsets=
130
- end
131
- self._re_scanner_index_offsets = [
90
+ RE_SCANNER_INDEX_OFFSETS = [
132
91
  0,0,65,130,195,197,217,219,
133
92
  250,252,275,295,297,308,328,339,
134
93
  359,390,392,403,424,435,451,474,
@@ -146,13 +105,9 @@ self._re_scanner_index_offsets = [
146
105
  5196,5207,5218,5229,5240,5242,5244,5245,
147
106
  5279,5281,5282,5284,5340,5396,5398,5421,
148
107
  5441,5452,5470
149
- ]
108
+ ].freeze
150
109
 
151
- class << self
152
- attr_accessor :_re_scanner_indicies
153
- private :_re_scanner_indicies, :_re_scanner_indicies=
154
- end
155
- self._re_scanner_indicies = [
110
+ RE_SCANNER_INDICIES = [
156
111
  1,1,1,1,1,1,1,1,
157
112
  1,1,1,1,1,1,1,1,
158
113
  1,1,1,1,1,1,1,1,
@@ -841,13 +796,9 @@ self._re_scanner_indicies = [
841
796
  96,96,211,96,96,211,211,211,
842
797
  211,211,211,211,211,211,211,96,
843
798
  96,96,211,93,96,0
844
- ]
799
+ ].freeze
845
800
 
846
- class << self
847
- attr_accessor :_re_scanner_trans_targs
848
- private :_re_scanner_trans_targs, :_re_scanner_trans_targs=
849
- end
850
- self._re_scanner_trans_targs = [
801
+ RE_SCANNER_TRANS_TARGS = [
851
802
  76,77,1,2,76,4,76,6,
852
803
  76,8,76,76,10,16,11,76,
853
804
  12,13,14,15,17,18,19,20,
@@ -875,13 +826,9 @@ self._re_scanner_trans_targs = [
875
826
  114,106,117,106,53,106,120,122,
876
827
  106,56,106,106,106,69,126,127,
877
828
  128,129,130,126
878
- ]
829
+ ].freeze
879
830
 
880
- class << self
881
- attr_accessor :_re_scanner_trans_actions
882
- private :_re_scanner_trans_actions, :_re_scanner_trans_actions=
883
- end
884
- self._re_scanner_trans_actions = [
831
+ RE_SCANNER_TRANS_ACTIONS = [
885
832
  1,2,0,0,3,0,4,0,
886
833
  5,0,6,7,0,0,0,8,
887
834
  0,0,0,0,0,0,0,0,
@@ -909,13 +856,9 @@ self._re_scanner_trans_actions = [
909
856
  0,89,33,90,0,91,33,0,
910
857
  92,0,93,94,95,0,96,33,
911
858
  33,33,33,97
912
- ]
859
+ ].freeze
913
860
 
914
- class << self
915
- attr_accessor :_re_scanner_to_state_actions
916
- private :_re_scanner_to_state_actions, :_re_scanner_to_state_actions=
917
- end
918
- self._re_scanner_to_state_actions = [
861
+ RE_SCANNER_TO_STATE_ACTIONS = [
919
862
  0,0,0,0,0,0,0,0,
920
863
  0,0,0,0,0,0,0,0,
921
864
  0,0,0,0,0,0,0,0,
@@ -933,13 +876,9 @@ self._re_scanner_to_state_actions = [
933
876
  0,0,0,0,0,0,0,0,
934
877
  0,0,0,0,0,0,64,0,
935
878
  0,0,0
936
- ]
879
+ ].freeze
937
880
 
938
- class << self
939
- attr_accessor :_re_scanner_from_state_actions
940
- private :_re_scanner_from_state_actions, :_re_scanner_from_state_actions=
941
- end
942
- self._re_scanner_from_state_actions = [
881
+ RE_SCANNER_FROM_STATE_ACTIONS = [
943
882
  0,0,0,0,0,0,0,0,
944
883
  0,0,0,0,0,0,0,0,
945
884
  0,0,0,0,0,0,0,0,
@@ -957,13 +896,9 @@ self._re_scanner_from_state_actions = [
957
896
  0,0,0,0,0,0,0,0,
958
897
  0,0,0,0,0,0,37,0,
959
898
  0,0,0
960
- ]
899
+ ].freeze
961
900
 
962
- class << self
963
- attr_accessor :_re_scanner_eof_actions
964
- private :_re_scanner_eof_actions, :_re_scanner_eof_actions=
965
- end
966
- self._re_scanner_eof_actions = [
901
+ RE_SCANNER_EOF_ACTIONS = [
967
902
  0,0,0,0,0,0,0,0,
968
903
  0,0,0,0,0,0,0,0,
969
904
  0,0,0,0,0,0,0,0,
@@ -981,13 +916,9 @@ self._re_scanner_eof_actions = [
981
916
  0,0,0,0,0,0,0,0,
982
917
  0,0,0,0,0,0,0,0,
983
918
  0,0,0
984
- ]
919
+ ].freeze
985
920
 
986
- class << self
987
- attr_accessor :_re_scanner_eof_trans
988
- private :_re_scanner_eof_trans, :_re_scanner_eof_trans=
989
- end
990
- self._re_scanner_eof_trans = [
921
+ RE_SCANNER_EOF_TRANS = [
991
922
  0,1,1,1,5,5,5,5,
992
923
  5,12,12,12,12,12,12,12,
993
924
  12,12,12,12,12,12,12,12,
@@ -1005,54 +936,58 @@ self._re_scanner_eof_trans = [
1005
936
  191,191,191,191,194,194,194,198,
1006
937
  198,198,198,203,203,205,0,212,
1007
938
  212,212,212
1008
- ]
939
+ ].freeze
1009
940
 
1010
- class << self
1011
- attr_accessor :re_scanner_start
1012
- end
1013
- self.re_scanner_start = 76;
1014
- class << self
1015
- attr_accessor :re_scanner_first_final
1016
- end
1017
- self.re_scanner_first_final = 76;
1018
- class << self
1019
- attr_accessor :re_scanner_error
1020
- end
1021
- self.re_scanner_error = 0;
941
+ RE_SCANNER_START = 76.freeze
942
+ RE_SCANNER_FIRST_FINAL = 76.freeze
943
+ RE_SCANNER_ERROR = 0.freeze
1022
944
 
1023
- class << self
1024
- attr_accessor :re_scanner_en_char_type
1025
- end
1026
- self.re_scanner_en_char_type = 91;
1027
- class << self
1028
- attr_accessor :re_scanner_en_unicode_property
1029
- end
1030
- self.re_scanner_en_unicode_property = 92;
1031
- class << self
1032
- attr_accessor :re_scanner_en_character_set
1033
- end
1034
- self.re_scanner_en_character_set = 93;
1035
- class << self
1036
- attr_accessor :re_scanner_en_set_escape_sequence
1037
- end
1038
- self.re_scanner_en_set_escape_sequence = 100;
1039
- class << self
1040
- attr_accessor :re_scanner_en_escape_sequence
1041
- end
1042
- self.re_scanner_en_escape_sequence = 106;
1043
- class << self
1044
- attr_accessor :re_scanner_en_conditional_expression
1045
- end
1046
- self.re_scanner_en_conditional_expression = 126;
1047
- class << self
1048
- attr_accessor :re_scanner_en_main
1049
- end
1050
- self.re_scanner_en_main = 76;
945
+ RE_SCANNER_EN_CHAR_TYPE = 91.freeze
946
+ RE_SCANNER_EN_UNICODE_PROPERTY = 92.freeze
947
+ RE_SCANNER_EN_CHARACTER_SET = 93.freeze
948
+ RE_SCANNER_EN_SET_ESCAPE_SEQUENCE = 100.freeze
949
+ RE_SCANNER_EN_ESCAPE_SEQUENCE = 106.freeze
950
+ RE_SCANNER_EN_CONDITIONAL_EXPRESSION = 126.freeze
951
+ RE_SCANNER_EN_MAIN = 76.freeze
952
+
953
+ # Scans the given regular expression text, or Regexp object and collects the
954
+ # emitted token into an array that gets returned at the end. If a block is
955
+ # given, it gets called for each emitted token.
956
+ #
957
+ # This method may raise errors if a syntax error is encountered.
958
+ # --------------------------------------------------------------------------
959
+ def self.scan(input_object, options: nil, collect_tokens: true, &block)
960
+ new.scan(input_object, options: options, collect_tokens: collect_tokens, &block)
961
+ end
962
+
963
+ def scan(input_object, options: nil, collect_tokens: true, &block)
964
+ self.collect_tokens = collect_tokens
965
+ self.literal_run = nil
966
+ stack = []
967
+
968
+ input = input_object.is_a?(Regexp) ? input_object.source : input_object
969
+ self.free_spacing = free_spacing?(input_object, options)
970
+ self.regexp_encoding = extract_encoding(input_object, options)
971
+ self.spacing_stack = [{:free_spacing => free_spacing, :depth => 0}]
972
+
973
+ # Keep token text stable if a callback mutates the caller's String.
974
+ source = input.dup.freeze
975
+ data = source.unpack("c*")
976
+ eof = data.length
977
+
978
+ self.tokens = []
979
+ self.block = block
980
+
981
+ self.set_depth = 0
982
+ self.group_depth = 0
983
+ self.capturing_group_count = 0
984
+ self.conditional_stack = []
985
+ self.char_pos = 0
1051
986
 
1052
987
  begin
1053
988
  p ||= 0
1054
989
  pe ||= data.length
1055
- cs = re_scanner_start
990
+ cs = RE_SCANNER_START
1056
991
  top = 0
1057
992
  ts = nil
1058
993
  te = nil
@@ -1080,29 +1015,29 @@ begin
1080
1015
  end
1081
1016
  end
1082
1017
  if _goto_level <= _resume
1083
- case _re_scanner_from_state_actions[cs]
1018
+ case RE_SCANNER_FROM_STATE_ACTIONS[cs]
1084
1019
  when 37
1085
1020
  begin
1086
1021
  ts = p
1087
1022
  end
1088
1023
  end
1089
1024
  _keys = cs << 1
1090
- _inds = _re_scanner_index_offsets[cs]
1091
- _slen = _re_scanner_key_spans[cs]
1025
+ _inds = RE_SCANNER_INDEX_OFFSETS[cs]
1026
+ _slen = RE_SCANNER_KEY_SPANS[cs]
1092
1027
  _wide = data[p].ord
1093
1028
  _trans = if ( _slen > 0 &&
1094
- _re_scanner_trans_keys[_keys] <= _wide &&
1095
- _wide <= _re_scanner_trans_keys[_keys + 1]
1029
+ RE_SCANNER_TRANS_KEYS[_keys] <= _wide &&
1030
+ _wide <= RE_SCANNER_TRANS_KEYS[_keys + 1]
1096
1031
  )
1097
- _re_scanner_indicies[ _inds + _wide - _re_scanner_trans_keys[_keys] ]
1032
+ RE_SCANNER_INDICIES[ _inds + _wide - RE_SCANNER_TRANS_KEYS[_keys] ]
1098
1033
  else
1099
- _re_scanner_indicies[ _inds + _slen ]
1034
+ RE_SCANNER_INDICIES[ _inds + _slen ]
1100
1035
  end
1101
1036
  end
1102
1037
  if _goto_level <= _eof_trans
1103
- cs = _re_scanner_trans_targs[_trans]
1104
- if _re_scanner_trans_actions[_trans] != 0
1105
- case _re_scanner_trans_actions[_trans]
1038
+ cs = RE_SCANNER_TRANS_TARGS[_trans]
1039
+ if RE_SCANNER_TRANS_ACTIONS[_trans] != 0
1040
+ case RE_SCANNER_TRANS_ACTIONS[_trans]
1106
1041
  when 39
1107
1042
  begin
1108
1043
  self.group_depth = group_depth + 1 end
@@ -1114,7 +1049,7 @@ te = p+1
1114
1049
  begin
1115
1050
  te = p+1
1116
1051
  begin
1117
- case text = copy(data, ts-1,te)
1052
+ case text = copy(source, ts-1,te)
1118
1053
  when '\d'; emit(:type, :digit, text)
1119
1054
  when '\D'; emit(:type, :nondigit, text)
1120
1055
  when '\h'; emit(:type, :hex, text)
@@ -1139,7 +1074,7 @@ te = p+1
1139
1074
  begin
1140
1075
  te = p+1
1141
1076
  begin
1142
- text = copy(data, ts-1,te)
1077
+ text = copy(source, ts-1,te)
1143
1078
  type = (text[1] == 'P') ^ (text[3] == '^') ? :nonproperty : :property
1144
1079
 
1145
1080
  name = text[3..-2].gsub(/[\^\s_\-]/, '').downcase
@@ -1202,14 +1137,14 @@ te = p+1
1202
1137
  begin
1203
1138
  te = p+1
1204
1139
  begin
1205
- emit(:literal, :literal, copy(data, ts, te))
1140
+ emit(:literal, :literal, copy(source, ts, te))
1206
1141
  end
1207
1142
  end
1208
1143
  when 15
1209
1144
  begin
1210
1145
  te = p+1
1211
1146
  begin
1212
- text = copy(data, ts, te)
1147
+ text = copy(source, ts, te)
1213
1148
  emit(:literal, :literal, text)
1214
1149
  end
1215
1150
  end
@@ -1245,7 +1180,7 @@ p = p - 1; begin
1245
1180
  begin
1246
1181
  te = p
1247
1182
  p = p - 1; begin
1248
- text = copy(data, ts, te)
1183
+ text = copy(source, ts, te)
1249
1184
  emit(:literal, :literal, text)
1250
1185
  end
1251
1186
  end
@@ -1281,7 +1216,7 @@ p = p - 1; begin
1281
1216
  begin
1282
1217
  begin p = ((te))-1; end
1283
1218
  begin
1284
- text = copy(data, ts, te)
1219
+ text = copy(source, ts, te)
1285
1220
  emit(:literal, :literal, text)
1286
1221
  end
1287
1222
  end
@@ -1289,7 +1224,7 @@ p = p - 1; begin
1289
1224
  begin
1290
1225
  te = p+1
1291
1226
  begin
1292
- emit(:escape, :octal, copy(data, ts-1,te))
1227
+ emit(:escape, :octal, copy(source, ts-1,te))
1293
1228
  begin
1294
1229
  top -= 1
1295
1230
  cs = stack[top]
@@ -1319,7 +1254,7 @@ te = p+1
1319
1254
  begin
1320
1255
  te = p+1
1321
1256
  begin
1322
- emit(:escape, :literal, copy(data, ts-1,te))
1257
+ emit(:escape, :literal, copy(source, ts-1,te))
1323
1258
  begin
1324
1259
  top -= 1
1325
1260
  cs = stack[top]
@@ -1333,7 +1268,7 @@ te = p+1
1333
1268
  begin
1334
1269
  te = p
1335
1270
  p = p - 1; begin
1336
- emit(:escape, :octal, copy(data, ts-1,te))
1271
+ emit(:escape, :octal, copy(source, ts-1,te))
1337
1272
  begin
1338
1273
  top -= 1
1339
1274
  cs = stack[top]
@@ -1347,7 +1282,7 @@ p = p - 1; begin
1347
1282
  begin
1348
1283
  te = p
1349
1284
  p = p - 1; begin
1350
- emit(:escape, :literal, copy(data, ts-1,te))
1285
+ emit(:escape, :literal, copy(source, ts-1,te))
1351
1286
  begin
1352
1287
  top -= 1
1353
1288
  cs = stack[top]
@@ -1361,7 +1296,7 @@ p = p - 1; begin
1361
1296
  begin
1362
1297
  begin p = ((te))-1; end
1363
1298
  begin
1364
- emit(:escape, :literal, copy(data, ts-1,te))
1299
+ emit(:escape, :literal, copy(source, ts-1,te))
1365
1300
  begin
1366
1301
  top -= 1
1367
1302
  cs = stack[top]
@@ -1375,7 +1310,7 @@ p = p - 1; begin
1375
1310
  begin
1376
1311
  te = p+1
1377
1312
  begin
1378
- emit(:escape, :octal, copy(data, ts-1,te))
1313
+ emit(:escape, :octal, copy(source, ts-1,te))
1379
1314
  begin
1380
1315
  top -= 1
1381
1316
  cs = stack[top]
@@ -1389,7 +1324,7 @@ te = p+1
1389
1324
  begin
1390
1325
  te = p+1
1391
1326
  begin
1392
- case text = copy(data, ts-1,te)
1327
+ case text = copy(source, ts-1,te)
1393
1328
  when '\.'; emit(:escape, :dot, text)
1394
1329
  when '\|'; emit(:escape, :alternation, text)
1395
1330
  when '\^'; emit(:escape, :bol, text)
@@ -1421,7 +1356,7 @@ te = p+1
1421
1356
  begin
1422
1357
  # \b is emitted as backspace only when inside a character set, otherwise
1423
1358
  # it is a word boundary anchor. A syntax might "normalize" it if needed.
1424
- case text = copy(data, ts-1,te)
1359
+ case text = copy(source, ts-1,te)
1425
1360
  when '\a'; emit(:escape, :bell, text)
1426
1361
  when '\b'; emit(:escape, :backspace, text)
1427
1362
  when '\e'; emit(:escape, :escape, text)
@@ -1444,7 +1379,7 @@ te = p+1
1444
1379
  begin
1445
1380
  te = p+1
1446
1381
  begin
1447
- text = copy(data, ts-1,te)
1382
+ text = copy(source, ts-1,te)
1448
1383
  if text[2] == '{'
1449
1384
  emit(:escape, :codepoint_list, text)
1450
1385
  else
@@ -1463,7 +1398,7 @@ te = p+1
1463
1398
  begin
1464
1399
  te = p+1
1465
1400
  begin
1466
- emit(:escape, :hex, copy(data, ts-1,te))
1401
+ emit(:escape, :hex, copy(source, ts-1,te))
1467
1402
  begin
1468
1403
  top -= 1
1469
1404
  cs = stack[top]
@@ -1477,7 +1412,7 @@ te = p+1
1477
1412
  begin
1478
1413
  te = p+1
1479
1414
  begin
1480
- emit_meta_control_sequence(data, ts, te, :control)
1415
+ emit_meta_control_sequence(data, source, ts, te, :control)
1481
1416
  begin
1482
1417
  top -= 1
1483
1418
  cs = stack[top]
@@ -1491,7 +1426,7 @@ te = p+1
1491
1426
  begin
1492
1427
  te = p+1
1493
1428
  begin
1494
- emit_meta_control_sequence(data, ts, te, :meta_sequence)
1429
+ emit_meta_control_sequence(data, source, ts, te, :meta_sequence)
1495
1430
  begin
1496
1431
  top -= 1
1497
1432
  cs = stack[top]
@@ -1537,7 +1472,7 @@ te = p+1
1537
1472
  begin
1538
1473
  te = p+1
1539
1474
  begin
1540
- emit(:escape, :literal, copy(data, ts-1,te))
1475
+ emit(:escape, :literal, copy(source, ts-1,te))
1541
1476
  begin
1542
1477
  top -= 1
1543
1478
  cs = stack[top]
@@ -1551,7 +1486,7 @@ te = p+1
1551
1486
  begin
1552
1487
  te = p
1553
1488
  p = p - 1; begin
1554
- text = copy(data, ts-1,te)
1489
+ text = copy(source, ts-1,te)
1555
1490
 
1556
1491
  # If not enough groups have been opened, there is a fallback to either an
1557
1492
  # octal or literal interpretation for 2+ digit numerical escapes.
@@ -1578,7 +1513,7 @@ p = p - 1; begin
1578
1513
  begin
1579
1514
  te = p
1580
1515
  p = p - 1; begin
1581
- emit(:escape, :octal, copy(data, ts-1,te))
1516
+ emit(:escape, :octal, copy(source, ts-1,te))
1582
1517
  begin
1583
1518
  top -= 1
1584
1519
  cs = stack[top]
@@ -1592,7 +1527,7 @@ p = p - 1; begin
1592
1527
  begin
1593
1528
  te = p
1594
1529
  p = p - 1; begin
1595
- text = copy(data, ts-1,te)
1530
+ text = copy(source, ts-1,te)
1596
1531
  if regexp_encoding == Encoding::BINARY
1597
1532
  text.split(/(?=\\)/).each { |part| emit(:escape, :hex, part) }
1598
1533
  else
@@ -1611,7 +1546,7 @@ p = p - 1; begin
1611
1546
  begin
1612
1547
  te = p
1613
1548
  p = p - 1; begin
1614
- emit(:escape, :hex, copy(data, ts-1,te))
1549
+ emit(:escape, :hex, copy(source, ts-1,te))
1615
1550
  begin
1616
1551
  top -= 1
1617
1552
  cs = stack[top]
@@ -1625,7 +1560,7 @@ p = p - 1; begin
1625
1560
  begin
1626
1561
  te = p
1627
1562
  p = p - 1; begin
1628
- emit_meta_control_sequence(data, ts, te, :control)
1563
+ emit_meta_control_sequence(data, source, ts, te, :control)
1629
1564
  begin
1630
1565
  top -= 1
1631
1566
  cs = stack[top]
@@ -1639,7 +1574,7 @@ p = p - 1; begin
1639
1574
  begin
1640
1575
  te = p
1641
1576
  p = p - 1; begin
1642
- emit_meta_control_sequence(data, ts, te, :meta_sequence)
1577
+ emit_meta_control_sequence(data, source, ts, te, :meta_sequence)
1643
1578
  begin
1644
1579
  top -= 1
1645
1580
  cs = stack[top]
@@ -1653,7 +1588,7 @@ p = p - 1; begin
1653
1588
  begin
1654
1589
  te = p
1655
1590
  p = p - 1; begin
1656
- emit(:escape, :literal, copy(data, ts-1,te))
1591
+ emit(:escape, :literal, copy(source, ts-1,te))
1657
1592
  begin
1658
1593
  top -= 1
1659
1594
  cs = stack[top]
@@ -1667,7 +1602,7 @@ p = p - 1; begin
1667
1602
  begin
1668
1603
  begin p = ((te))-1; end
1669
1604
  begin
1670
- text = copy(data, ts-1,te)
1605
+ text = copy(source, ts-1,te)
1671
1606
  if regexp_encoding == Encoding::BINARY
1672
1607
  text.split(/(?=\\)/).each { |part| emit(:escape, :hex, part) }
1673
1608
  else
@@ -1686,7 +1621,7 @@ p = p - 1; begin
1686
1621
  begin
1687
1622
  begin p = ((te))-1; end
1688
1623
  begin
1689
- emit(:escape, :literal, copy(data, ts-1,te))
1624
+ emit(:escape, :literal, copy(source, ts-1,te))
1690
1625
  begin
1691
1626
  top -= 1
1692
1627
  cs = stack[top]
@@ -1700,7 +1635,7 @@ p = p - 1; begin
1700
1635
  begin
1701
1636
  te = p+1
1702
1637
  begin
1703
- text = copy(data, ts, te-1)
1638
+ text = copy(source, ts, te-1)
1704
1639
  text =~ /[^0]/ or raise ValidationError.for(:backref, 'condition', 'invalid ref ID')
1705
1640
  emit(:conditional, :condition, text)
1706
1641
  emit(:conditional, :condition_close, ')')
@@ -1755,7 +1690,7 @@ p = p - 1; begin
1755
1690
  begin
1756
1691
  te = p+1
1757
1692
  begin
1758
- emit(:meta, :dot, copy(data, ts, te))
1693
+ emit(:meta, :dot, copy(source, ts, te))
1759
1694
  end
1760
1695
  end
1761
1696
  when 45
@@ -1763,9 +1698,9 @@ te = p+1
1763
1698
  te = p+1
1764
1699
  begin
1765
1700
  if conditional_stack.last == group_depth
1766
- emit(:conditional, :separator, copy(data, ts, te))
1701
+ emit(:conditional, :separator, copy(source, ts, te))
1767
1702
  else
1768
- emit(:meta, :alternation, copy(data, ts, te))
1703
+ emit(:meta, :alternation, copy(source, ts, te))
1769
1704
  end
1770
1705
  end
1771
1706
  end
@@ -1773,28 +1708,28 @@ te = p+1
1773
1708
  begin
1774
1709
  te = p+1
1775
1710
  begin
1776
- emit(:anchor, :bol, copy(data, ts, te))
1711
+ emit(:anchor, :bol, copy(source, ts, te))
1777
1712
  end
1778
1713
  end
1779
1714
  when 38
1780
1715
  begin
1781
1716
  te = p+1
1782
1717
  begin
1783
- emit(:anchor, :eol, copy(data, ts, te))
1718
+ emit(:anchor, :eol, copy(source, ts, te))
1784
1719
  end
1785
1720
  end
1786
1721
  when 62
1787
1722
  begin
1788
1723
  te = p+1
1789
1724
  begin
1790
- emit(:keep, :mark, copy(data, ts, te))
1725
+ emit(:keep, :mark, copy(source, ts, te))
1791
1726
  end
1792
1727
  end
1793
1728
  when 61
1794
1729
  begin
1795
1730
  te = p+1
1796
1731
  begin
1797
- case text = copy(data, ts, te)
1732
+ case text = copy(source, ts, te)
1798
1733
  when '\A'; emit(:anchor, :bos, text)
1799
1734
  when '\z'; emit(:anchor, :eos, text)
1800
1735
  when '\Z'; emit(:anchor, :eos_ob_eol, text)
@@ -1808,14 +1743,14 @@ te = p+1
1808
1743
  begin
1809
1744
  te = p+1
1810
1745
  begin
1811
- append_literal(data, ts, te)
1746
+ append_literal(source, ts, te)
1812
1747
  end
1813
1748
  end
1814
1749
  when 52
1815
1750
  begin
1816
1751
  te = p+1
1817
1752
  begin
1818
- text = copy(data, ts, te)
1753
+ text = copy(source, ts, te)
1819
1754
 
1820
1755
  conditional_stack << group_depth
1821
1756
 
@@ -1835,7 +1770,7 @@ te = p+1
1835
1770
  begin
1836
1771
  te = p+1
1837
1772
  begin
1838
- text = copy(data, ts, te)
1773
+ text = copy(source, ts, te)
1839
1774
  if text[2..-1] =~ /([^\-mixdau:]|^$)|-.*([dau])/
1840
1775
  raise ValidationError.for(:group_option, $1 || "-#{$2}", text)
1841
1776
  end
@@ -1846,7 +1781,7 @@ te = p+1
1846
1781
  begin
1847
1782
  te = p+1
1848
1783
  begin
1849
- case text = copy(data, ts, te)
1784
+ case text = copy(source, ts, te)
1850
1785
  when '(?='; emit(:assertion, :lookahead, text)
1851
1786
  when '(?!'; emit(:assertion, :nlookahead, text)
1852
1787
  when '(?<='; emit(:assertion, :lookbehind, text)
@@ -1858,7 +1793,7 @@ te = p+1
1858
1793
  begin
1859
1794
  te = p+1
1860
1795
  begin
1861
- case text = copy(data, ts, te)
1796
+ case text = copy(source, ts, te)
1862
1797
  when '(?:'; emit(:group, :passive, text)
1863
1798
  when '(?>'; emit(:group, :atomic, text)
1864
1799
  when '(?~'; emit(:group, :absence, text)
@@ -1879,7 +1814,7 @@ te = p+1
1879
1814
  begin
1880
1815
  te = p+1
1881
1816
  begin
1882
- case text = copy(data, ts, te)
1817
+ case text = copy(source, ts, te)
1883
1818
  when /^\\k(.)[^0-9\-][^+\-]*['>]$/
1884
1819
  emit(:backref, $1 == '<' ? :name_ref_ab : :name_ref_sq, text)
1885
1820
  when /^\\k(.)0*[1-9]\d*['>]$/
@@ -1899,7 +1834,7 @@ te = p+1
1899
1834
  begin
1900
1835
  te = p+1
1901
1836
  begin
1902
- case text = copy(data, ts, te)
1837
+ case text = copy(source, ts, te)
1903
1838
  when /^\\g(.)[^0-9+\-].*['>]$/
1904
1839
  emit(:backref, $1 == '<' ? :name_call_ab : :name_call_sq, text)
1905
1840
  when /^\\g(.)(?:0|0*[1-9]\d*)['>]$/
@@ -1915,7 +1850,7 @@ te = p+1
1915
1850
  begin
1916
1851
  te = p+1
1917
1852
  begin
1918
- case text = copy(data, ts, te)
1853
+ case text = copy(source, ts, te)
1919
1854
  when '?' ; emit(:quantifier, :zero_or_one, text)
1920
1855
  when '??'; emit(:quantifier, :zero_or_one_reluctant, text)
1921
1856
  when '?+'; emit(:quantifier, :zero_or_one_possessive, text)
@@ -1926,7 +1861,7 @@ te = p+1
1926
1861
  begin
1927
1862
  te = p+1
1928
1863
  begin
1929
- case text = copy(data, ts, te)
1864
+ case text = copy(source, ts, te)
1930
1865
  when '*' ; emit(:quantifier, :zero_or_more, text)
1931
1866
  when '*?'; emit(:quantifier, :zero_or_more_reluctant, text)
1932
1867
  when '*+'; emit(:quantifier, :zero_or_more_possessive, text)
@@ -1937,7 +1872,7 @@ te = p+1
1937
1872
  begin
1938
1873
  te = p+1
1939
1874
  begin
1940
- case text = copy(data, ts, te)
1875
+ case text = copy(source, ts, te)
1941
1876
  when '+' ; emit(:quantifier, :one_or_more, text)
1942
1877
  when '+?'; emit(:quantifier, :one_or_more_reluctant, text)
1943
1878
  when '++'; emit(:quantifier, :one_or_more_possessive, text)
@@ -1948,7 +1883,7 @@ te = p+1
1948
1883
  begin
1949
1884
  te = p+1
1950
1885
  begin
1951
- emit(:quantifier, :interval, copy(data, ts, te))
1886
+ emit(:quantifier, :interval, copy(source, ts, te))
1952
1887
  end
1953
1888
  end
1954
1889
  when 49
@@ -1956,10 +1891,10 @@ te = p+1
1956
1891
  te = p+1
1957
1892
  begin
1958
1893
  if free_spacing
1959
- emit(:free_space, :comment, copy(data, ts, te))
1894
+ emit(:free_space, :comment, copy(source, ts, te))
1960
1895
  else
1961
1896
  # consume only the pound sign (#) and backtrack to do regular scanning
1962
- append_literal(data, ts, ts + 1)
1897
+ append_literal(source, ts, ts + 1)
1963
1898
  begin p = (( ts + 1))-1; end
1964
1899
 
1965
1900
  end
@@ -1969,7 +1904,7 @@ te = p+1
1969
1904
  begin
1970
1905
  te = p
1971
1906
  p = p - 1; begin
1972
- text = copy(data, ts, te)
1907
+ text = copy(source, ts, te)
1973
1908
  if text[2..-1] =~ /([^\-mixdau:]|^$)|-.*([dau])/
1974
1909
  raise ValidationError.for(:group_option, $1 || "-#{$2}", text)
1975
1910
  end
@@ -1981,7 +1916,7 @@ p = p - 1; begin
1981
1916
  te = p
1982
1917
  p = p - 1; begin
1983
1918
  self.capturing_group_count = capturing_group_count + 1
1984
- text = copy(data, ts, te)
1919
+ text = copy(source, ts, te)
1985
1920
  emit(:group, :capture, text)
1986
1921
  end
1987
1922
  end
@@ -1989,7 +1924,7 @@ p = p - 1; begin
1989
1924
  begin
1990
1925
  te = p
1991
1926
  p = p - 1; begin
1992
- case text = copy(data, ts, te)
1927
+ case text = copy(source, ts, te)
1993
1928
  when '?' ; emit(:quantifier, :zero_or_one, text)
1994
1929
  when '??'; emit(:quantifier, :zero_or_one_reluctant, text)
1995
1930
  when '?+'; emit(:quantifier, :zero_or_one_possessive, text)
@@ -2000,7 +1935,7 @@ p = p - 1; begin
2000
1935
  begin
2001
1936
  te = p
2002
1937
  p = p - 1; begin
2003
- case text = copy(data, ts, te)
1938
+ case text = copy(source, ts, te)
2004
1939
  when '*' ; emit(:quantifier, :zero_or_more, text)
2005
1940
  when '*?'; emit(:quantifier, :zero_or_more_reluctant, text)
2006
1941
  when '*+'; emit(:quantifier, :zero_or_more_possessive, text)
@@ -2011,7 +1946,7 @@ p = p - 1; begin
2011
1946
  begin
2012
1947
  te = p
2013
1948
  p = p - 1; begin
2014
- case text = copy(data, ts, te)
1949
+ case text = copy(source, ts, te)
2015
1950
  when '+' ; emit(:quantifier, :one_or_more, text)
2016
1951
  when '+?'; emit(:quantifier, :one_or_more_reluctant, text)
2017
1952
  when '++'; emit(:quantifier, :one_or_more_possessive, text)
@@ -2022,7 +1957,7 @@ p = p - 1; begin
2022
1957
  begin
2023
1958
  te = p
2024
1959
  p = p - 1; begin
2025
- append_literal(data, ts, te)
1960
+ append_literal(source, ts, te)
2026
1961
  end
2027
1962
  end
2028
1963
  when 60
@@ -2044,10 +1979,10 @@ p = p - 1; begin
2044
1979
  te = p
2045
1980
  p = p - 1; begin
2046
1981
  if free_spacing
2047
- emit(:free_space, :comment, copy(data, ts, te))
1982
+ emit(:free_space, :comment, copy(source, ts, te))
2048
1983
  else
2049
1984
  # consume only the pound sign (#) and backtrack to do regular scanning
2050
- append_literal(data, ts, ts + 1)
1985
+ append_literal(source, ts, ts + 1)
2051
1986
  begin p = (( ts + 1))-1; end
2052
1987
 
2053
1988
  end
@@ -2058,9 +1993,9 @@ p = p - 1; begin
2058
1993
  te = p
2059
1994
  p = p - 1; begin
2060
1995
  if free_spacing
2061
- emit(:free_space, :whitespace, copy(data, ts, te))
1996
+ emit(:free_space, :whitespace, copy(source, ts, te))
2062
1997
  else
2063
- append_literal(data, ts, te)
1998
+ append_literal(source, ts, te)
2064
1999
  end
2065
2000
  end
2066
2001
  end
@@ -2068,14 +2003,14 @@ p = p - 1; begin
2068
2003
  begin
2069
2004
  te = p
2070
2005
  p = p - 1; begin
2071
- append_literal(data, ts, te)
2006
+ append_literal(source, ts, te)
2072
2007
  end
2073
2008
  end
2074
2009
  when 3
2075
2010
  begin
2076
2011
  begin p = ((te))-1; end
2077
2012
  begin
2078
- text = copy(data, ts, te)
2013
+ text = copy(source, ts, te)
2079
2014
  if text[2..-1] =~ /([^\-mixdau:]|^$)|-.*([dau])/
2080
2015
  raise ValidationError.for(:group_option, $1 || "-#{$2}", text)
2081
2016
  end
@@ -2086,7 +2021,7 @@ p = p - 1; begin
2086
2021
  begin
2087
2022
  begin p = ((te))-1; end
2088
2023
  begin
2089
- append_literal(data, ts, te)
2024
+ append_literal(source, ts, te)
2090
2025
  end
2091
2026
  end
2092
2027
  when 7
@@ -2116,14 +2051,14 @@ end
2116
2051
  when 58
2117
2052
  begin begin p = ((te))-1; end
2118
2053
 
2119
- append_literal(data, ts, te)
2054
+ append_literal(source, ts, te)
2120
2055
  end
2121
2056
  end
2122
2057
  end
2123
2058
  when 75
2124
2059
  begin
2125
2060
 
2126
- text = copy(data, ts ? ts-1 : 0,-1)
2061
+ text = error_text(source, ts, p)
2127
2062
  raise PrematureEndError.new(text)
2128
2063
  end
2129
2064
  begin
@@ -2143,7 +2078,7 @@ p = p - 1; begin
2143
2078
  when 18
2144
2079
  begin
2145
2080
 
2146
- text = copy(data, ts ? ts-1 : 0,-1)
2081
+ text = error_text(source, ts, p)
2147
2082
  raise PrematureEndError.new(text)
2148
2083
  end
2149
2084
  begin
@@ -2163,13 +2098,13 @@ p = p - 1; begin
2163
2098
  when 89
2164
2099
  begin
2165
2100
 
2166
- text = copy(data, ts ? ts-1 : 0,-1)
2101
+ text = error_text(source, ts, p)
2167
2102
  raise PrematureEndError.new(text)
2168
2103
  end
2169
2104
  begin
2170
2105
  te = p
2171
2106
  p = p - 1; begin
2172
- emit_meta_control_sequence(data, ts, te, :control)
2107
+ emit_meta_control_sequence(data, source, ts, te, :control)
2173
2108
  begin
2174
2109
  top -= 1
2175
2110
  cs = stack[top]
@@ -2182,13 +2117,13 @@ p = p - 1; begin
2182
2117
  when 91
2183
2118
  begin
2184
2119
 
2185
- text = copy(data, ts ? ts-1 : 0,-1)
2120
+ text = error_text(source, ts, p)
2186
2121
  raise PrematureEndError.new(text)
2187
2122
  end
2188
2123
  begin
2189
2124
  te = p
2190
2125
  p = p - 1; begin
2191
- emit_meta_control_sequence(data, ts, te, :meta_sequence)
2126
+ emit_meta_control_sequence(data, source, ts, te, :meta_sequence)
2192
2127
  begin
2193
2128
  top -= 1
2194
2129
  cs = stack[top]
@@ -2201,13 +2136,13 @@ p = p - 1; begin
2201
2136
  when 27
2202
2137
  begin
2203
2138
 
2204
- text = copy(data, ts ? ts-1 : 0,-1)
2139
+ text = error_text(source, ts, p)
2205
2140
  raise PrematureEndError.new(text)
2206
2141
  end
2207
2142
  begin
2208
2143
  begin p = ((te))-1; end
2209
2144
  begin
2210
- emit_meta_control_sequence(data, ts, te, :control)
2145
+ emit_meta_control_sequence(data, source, ts, te, :control)
2211
2146
  begin
2212
2147
  top -= 1
2213
2148
  cs = stack[top]
@@ -2220,13 +2155,13 @@ p = p - 1; begin
2220
2155
  when 29
2221
2156
  begin
2222
2157
 
2223
- text = copy(data, ts ? ts-1 : 0,-1)
2158
+ text = error_text(source, ts, p)
2224
2159
  raise PrematureEndError.new(text)
2225
2160
  end
2226
2161
  begin
2227
2162
  begin p = ((te))-1; end
2228
2163
  begin
2229
- emit_meta_control_sequence(data, ts, te, :meta_sequence)
2164
+ emit_meta_control_sequence(data, source, ts, te, :meta_sequence)
2230
2165
  begin
2231
2166
  top -= 1
2232
2167
  cs = stack[top]
@@ -2239,7 +2174,7 @@ p = p - 1; begin
2239
2174
  when 31
2240
2175
  begin
2241
2176
 
2242
- text = copy(data, ts ? ts-1 : 0,-1)
2177
+ text = error_text(source, ts, p)
2243
2178
  raise ValidationError.for(:sequence, 'sequence', text)
2244
2179
  end
2245
2180
  begin
@@ -2260,7 +2195,7 @@ te = p+1
2260
2195
  begin
2261
2196
  te = p+1
2262
2197
  begin
2263
- emit(:group, :comment, copy(data, ts, te))
2198
+ emit(:group, :comment, copy(source, ts, te))
2264
2199
  end
2265
2200
  end
2266
2201
  when 40
@@ -2291,7 +2226,7 @@ te = p+1
2291
2226
  begin
2292
2227
  te = p+1
2293
2228
  begin
2294
- emit(:set, :open, copy(data, ts, te))
2229
+ emit(:set, :open, copy(source, ts, te))
2295
2230
  begin
2296
2231
  stack[top] = cs
2297
2232
  top+= 1
@@ -2308,7 +2243,7 @@ te = p+1
2308
2243
  begin
2309
2244
  te = p+1
2310
2245
  begin
2311
- emit(:set, :close, copy(data, ts, te))
2246
+ emit(:set, :close, copy(source, ts, te))
2312
2247
  if in_set?
2313
2248
  begin
2314
2249
  top -= 1
@@ -2359,7 +2294,7 @@ te = p+1
2359
2294
  begin
2360
2295
  te = p+1
2361
2296
  begin
2362
- text = copy(data, ts, te)
2297
+ text = copy(source, ts, te)
2363
2298
 
2364
2299
  type = :posixclass
2365
2300
  class_name = text[2..-3]
@@ -2391,7 +2326,7 @@ act = 58; end
2391
2326
  end
2392
2327
  end
2393
2328
  if _goto_level <= _again
2394
- case _re_scanner_to_state_actions[cs]
2329
+ case RE_SCANNER_TO_STATE_ACTIONS[cs]
2395
2330
  when 64
2396
2331
  begin
2397
2332
  ts = nil; end
@@ -2415,12 +2350,12 @@ act = 0
2415
2350
  end
2416
2351
  if _goto_level <= _test_eof
2417
2352
  if p == eof
2418
- if _re_scanner_eof_trans[cs] > 0
2419
- _trans = _re_scanner_eof_trans[cs] - 1;
2353
+ if RE_SCANNER_EOF_TRANS[cs] > 0
2354
+ _trans = RE_SCANNER_EOF_TRANS[cs] - 1;
2420
2355
  _goto_level = _eof_trans
2421
2356
  next;
2422
2357
  end
2423
- case _re_scanner_eof_actions[cs]
2358
+ case RE_SCANNER_EOF_ACTIONS[cs]
2424
2359
  when 12
2425
2360
  begin
2426
2361
 
@@ -2429,7 +2364,7 @@ act = 0
2429
2364
  when 25
2430
2365
  begin
2431
2366
 
2432
- text = copy(data, ts ? ts-1 : 0,-1)
2367
+ text = error_text(source, ts, p)
2433
2368
  raise PrematureEndError.new(text)
2434
2369
  end
2435
2370
  end
@@ -2445,9 +2380,9 @@ end
2445
2380
  # to avoid "warning: assigned but unused variable - testEof"
2446
2381
  testEof = testEof
2447
2382
 
2448
- if cs == re_scanner_error
2449
- text = copy(data, ts ? ts-1 : 0,-1)
2450
- raise ScannerError.new("Scan error at '#{text}'")
2383
+ if cs == RE_SCANNER_ERROR
2384
+ text = error_text(source, ts, p)
2385
+ raise ScannerError.new("Scan error at #{text}")
2451
2386
  end
2452
2387
 
2453
2388
  raise PrematureEndError.new("(missing group closing paranthesis) "+
@@ -2545,15 +2480,28 @@ end
2545
2480
  set_depth > 0
2546
2481
  end
2547
2482
 
2548
- # Copy from ts to te from data as text
2549
- def copy(data, ts, te)
2550
- data[ts...te].pack('c*').force_encoding('utf-8')
2483
+ # Ragel offsets are bytes; emitted token positions are characters.
2484
+ def copy(source, ts, te)
2485
+ source.byteslice(ts, te - ts).force_encoding('utf-8')
2486
+ end
2487
+
2488
+ def error_text(source, ts, position)
2489
+ start = ts ? [ts - 1,0].max : 0
2490
+ finish = source.bytesize
2491
+ if position < finish
2492
+ # Include the complete offending UTF-8 character, but no following text.
2493
+ character = source.byteslice(position, 4).force_encoding('utf-8').each_char.first
2494
+ finish = position + character.bytesize
2495
+ end
2496
+ text = copy(source, start, finish)
2497
+ text = "…#{text[-9..-1]}" if text.length > 10
2498
+ text
2551
2499
  end
2552
2500
 
2553
2501
  # Appends one or more characters to the literal buffer, to be emitted later
2554
2502
  # by a call to emit_literal.
2555
- def append_literal(data, ts, te)
2556
- (self.literal_run ||= []) << copy(data, ts, te)
2503
+ def append_literal(source, ts, te)
2504
+ (self.literal_run ||= []) << copy(source, ts, te)
2557
2505
  end
2558
2506
 
2559
2507
  # Emits the literal run collected by calls to the append_literal method.
@@ -2592,10 +2540,10 @@ end
2592
2540
  emit(:group, token, text)
2593
2541
  end
2594
2542
 
2595
- def emit_meta_control_sequence(data, ts, te, token)
2543
+ def emit_meta_control_sequence(data, source, ts, te, token)
2596
2544
  if data.last < 0x00 || data.last > 0x7F
2597
2545
  raise ValidationError.for(:sequence, 'escape', token.to_s)
2598
2546
  end
2599
- emit(:escape, token, copy(data, ts-1,te))
2547
+ emit(:escape, token, copy(source, ts-1,te))
2600
2548
  end
2601
- end # module Regexp::Scanner
2549
+ end