tree-sitter-sed 0.2.0 → 0.4.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.
- package/CMakeLists.txt +121 -0
- package/Makefile +145 -0
- package/README.md +6 -1
- package/bindings/c/tree-sitter-sed.pc.in +10 -0
- package/bindings/c/tree_sitter/tree-sitter-sed.h +17 -0
- package/common/dsl.js +23 -1
- package/common/grammar.js +264 -334
- package/common/regex.js +12 -23
- package/common/scanner.h +569 -592
- package/package.json +9 -5
- package/sed_ere/src/grammar.json +1264 -2013
- package/sed_ere/src/node-types.json +109 -32
- package/sed_ere/src/parser.c +37125 -36566
- package/src/grammar.json +1261 -2076
- package/src/node-types.json +131 -38
- package/src/parser.c +31231 -30740
- package/test/binding.test.c +9 -0
- package/tree-sitter.json +2 -2
package/common/scanner.h
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#ifndef
|
|
2
|
-
#define
|
|
1
|
+
#ifndef TREE_SITTER_SED_COMMON_SCANNER_H_
|
|
2
|
+
#define TREE_SITTER_SED_COMMON_SCANNER_H_
|
|
3
3
|
|
|
4
4
|
#ifndef SED_REGEX_EXTENDED
|
|
5
5
|
#error "SED_REGEX_EXTENDED must be defined before including scanner.h"
|
|
@@ -42,7 +42,6 @@ enum TokenType {
|
|
|
42
42
|
BRE_QUESTION_MARK_ESCAPE_MARKER,
|
|
43
43
|
BRE_PLUS_ESCAPE_MARKER,
|
|
44
44
|
REGEX_UNMATCHED_INTERVAL_CLOSE,
|
|
45
|
-
UNMATCHED_INTERVAL_CLOSE_MARKER,
|
|
46
45
|
#endif
|
|
47
46
|
#if SED_REGEX_EXTENDED
|
|
48
47
|
REGEX_ALTERNATION_OPERATOR,
|
|
@@ -109,6 +108,7 @@ enum TokenType {
|
|
|
109
108
|
TRANSLATE_UNTERMINATED_SOURCE,
|
|
110
109
|
TRANSLATE_UNTERMINATED_DESTINATION,
|
|
111
110
|
INVALID_SUBSTITUTION_FLAG,
|
|
111
|
+
FLAG_AFTER_WRITE_MARKER,
|
|
112
112
|
TEXT_COMMAND_START,
|
|
113
113
|
TEXT_LITERAL,
|
|
114
114
|
TEXT_BACKSLASH_ESCAPE,
|
|
@@ -122,7 +122,7 @@ enum TokenType {
|
|
|
122
122
|
SUBSTITUTION_WFILE_ARGUMENT,
|
|
123
123
|
LINE_WORD,
|
|
124
124
|
RIGHT_BRACE,
|
|
125
|
-
|
|
125
|
+
RESERVED_UNKNOWN_FUNCTION_TOKEN,
|
|
126
126
|
REGEX_INCOMPLETE_GROUP,
|
|
127
127
|
REGEX_INCOMPLETE_BRACKET_TERM,
|
|
128
128
|
REGEX_INCOMPLETE_INTERVAL,
|
|
@@ -132,15 +132,15 @@ enum TokenType {
|
|
|
132
132
|
REPLACEMENT_LINE_UNTERMINATED,
|
|
133
133
|
TRANSLATE_LINE_UNTERMINATED_SOURCE,
|
|
134
134
|
TRANSLATE_LINE_UNTERMINATED_DESTINATION,
|
|
135
|
+
BLANKS_AROUND_ADDRESS_SEPARATOR,
|
|
135
136
|
OMITTED_ADDRESS_MARKER,
|
|
137
|
+
INCOMPLETE_OMITTED_ADDRESS_MARKER,
|
|
136
138
|
OMITTED_FIRST_ADDRESS_MARKER,
|
|
137
139
|
EMPTY_SUBEXPRESSION_MARKER,
|
|
138
140
|
MISSING_SUBEXPRESSION_MARKER,
|
|
139
141
|
#if SED_REGEX_EXTENDED
|
|
140
142
|
EMPTY_ALTERNATIVE_MARKER,
|
|
141
143
|
#endif
|
|
142
|
-
EXCESS_ADDRESSES_MARKER,
|
|
143
|
-
ADDITIONAL_ADDRESS_MARKER,
|
|
144
144
|
MISSING_FUNCTION_MARKER,
|
|
145
145
|
MISSING_LABEL_MARKER,
|
|
146
146
|
MISSING_RFILE_MARKER,
|
|
@@ -149,9 +149,7 @@ enum TokenType {
|
|
|
149
149
|
MISSING_TEXT_INTRODUCER_MARKER,
|
|
150
150
|
MISSING_TEXT_MARKER,
|
|
151
151
|
MISSING_COMMAND_SEPARATOR_MARKER,
|
|
152
|
-
BLANKS_AROUND_ADDRESS_SEPARATOR_MARKER,
|
|
153
152
|
MISSING_ADDRESS_SEPARATOR_MARKER,
|
|
154
|
-
DUPLICATE_NEGATION_MARKER,
|
|
155
153
|
MISSING_CLOSING_BRACE_MARKER,
|
|
156
154
|
MISSING_OPENING_DELIMITER_MARKER,
|
|
157
155
|
MISSING_SEPARATOR_BEFORE_UNMATCHED_BRACE_MARKER,
|
|
@@ -248,6 +246,17 @@ enum {
|
|
|
248
246
|
SCANNER_SERIALIZED_STATE_SIZE = 17,
|
|
249
247
|
};
|
|
250
248
|
|
|
249
|
+
enum {
|
|
250
|
+
SERIALIZED_AT_BRANCH_START_FLAG = 1 << 0,
|
|
251
|
+
SERIALIZED_AFTER_ALTERNATION_FLAG = 1 << 1,
|
|
252
|
+
SERIALIZED_AFTER_ANCHOR_FLAG = 1 << 2,
|
|
253
|
+
SERIALIZED_TEXT_STATE_SHIFT = 3,
|
|
254
|
+
SERIALIZED_MODE_FLAGS_MAXIMUM = 31,
|
|
255
|
+
SERIALIZED_RANGE_PENDING_FLAG = 1 << 0,
|
|
256
|
+
SERIALIZED_DUPLICATION_STATE_SHIFT = 1,
|
|
257
|
+
SERIALIZED_BRACKET_FLAGS_MAXIMUM = 7,
|
|
258
|
+
};
|
|
259
|
+
|
|
251
260
|
static void reset_bracket_tracking(ScannerState *state) {
|
|
252
261
|
state->regex_bracket_term_state = REGEX_BRACKET_TERM_NONE;
|
|
253
262
|
state->regex_bracket_pending_element = REGEX_BRACKET_PENDING_NONE;
|
|
@@ -306,6 +315,10 @@ static uint16_t deserialize_uint16(const char *buffer, unsigned offset) {
|
|
|
306
315
|
((uint16_t)(unsigned char)buffer[offset + 1] << 8));
|
|
307
316
|
}
|
|
308
317
|
|
|
318
|
+
static bool is_regex_mode(enum ScannerMode mode) {
|
|
319
|
+
return mode == MODE_REGEX_ADDRESS || mode == MODE_SUBSTITUTE_PATTERN;
|
|
320
|
+
}
|
|
321
|
+
|
|
309
322
|
static unsigned sed_scanner_serialize(void *payload, char *buffer) {
|
|
310
323
|
const ScannerState *state = payload;
|
|
311
324
|
const uint32_t delimiter = (uint32_t)state->delimiter;
|
|
@@ -313,10 +326,11 @@ static unsigned sed_scanner_serialize(void *payload, char *buffer) {
|
|
|
313
326
|
buffer[0] = SCANNER_SERIALIZATION_VERSION;
|
|
314
327
|
buffer[1] = (char)state->mode;
|
|
315
328
|
buffer[2] = (char)state->regex_state;
|
|
316
|
-
buffer[3] =
|
|
317
|
-
(state->
|
|
318
|
-
(state->
|
|
319
|
-
(
|
|
329
|
+
buffer[3] =
|
|
330
|
+
(state->regex_at_branch_start ? SERIALIZED_AT_BRANCH_START_FLAG : 0) |
|
|
331
|
+
(state->regex_after_alternation ? SERIALIZED_AFTER_ALTERNATION_FLAG : 0) |
|
|
332
|
+
(state->regex_after_anchor ? SERIALIZED_AFTER_ANCHOR_FLAG : 0) |
|
|
333
|
+
((unsigned char)state->text_state << SERIALIZED_TEXT_STATE_SHIFT);
|
|
320
334
|
buffer[4] = (char)(delimiter & UINT32_C(0xff));
|
|
321
335
|
buffer[5] = (char)((delimiter >> 8) & UINT32_C(0xff));
|
|
322
336
|
buffer[6] = (char)((delimiter >> 16) & UINT32_C(0xff));
|
|
@@ -328,11 +342,103 @@ static unsigned sed_scanner_serialize(void *payload, char *buffer) {
|
|
|
328
342
|
buffer[13] = (char)state->regex_bracket_first_element;
|
|
329
343
|
buffer[14] = (char)state->regex_bracket_last_element;
|
|
330
344
|
buffer[15] = (char)state->regex_bracket_element_count;
|
|
331
|
-
buffer[16] =
|
|
332
|
-
(
|
|
345
|
+
buffer[16] =
|
|
346
|
+
(state->regex_bracket_range_pending ? SERIALIZED_RANGE_PENDING_FLAG : 0) |
|
|
347
|
+
((unsigned char)state->regex_duplication_state
|
|
348
|
+
<< SERIALIZED_DUPLICATION_STATE_SHIFT);
|
|
333
349
|
return SCANNER_SERIALIZED_STATE_SIZE;
|
|
334
350
|
}
|
|
335
351
|
|
|
352
|
+
static bool bracket_tracking_is_reset(const ScannerState *state) {
|
|
353
|
+
return state->regex_bracket_term_state ==
|
|
354
|
+
REGEX_BRACKET_TERM_NONE &&
|
|
355
|
+
state->regex_bracket_pending_element ==
|
|
356
|
+
REGEX_BRACKET_PENDING_NONE &&
|
|
357
|
+
state->regex_bracket_first_element ==
|
|
358
|
+
REGEX_BRACKET_PENDING_NONE &&
|
|
359
|
+
state->regex_bracket_last_element ==
|
|
360
|
+
REGEX_BRACKET_PENDING_NONE &&
|
|
361
|
+
state->regex_bracket_element_count ==
|
|
362
|
+
0 &&
|
|
363
|
+
!state->regex_bracket_range_pending;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
static bool regex_position_is_reset(const ScannerState *state) {
|
|
367
|
+
return !state->regex_at_branch_start &&
|
|
368
|
+
state->regex_duplication_state ==
|
|
369
|
+
REGEX_DUPLICATION_NONE &&
|
|
370
|
+
!state->regex_after_alternation &&
|
|
371
|
+
!state->regex_after_anchor;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
static bool deserialized_delimiter_is_valid(uint32_t delimiter) {
|
|
375
|
+
return delimiter !=
|
|
376
|
+
0 &&
|
|
377
|
+
delimiter <=
|
|
378
|
+
UINT32_C(0x10ffff) &&
|
|
379
|
+
!(delimiter >= UINT32_C(0xd800) && delimiter <= UINT32_C(0xdfff)) &&
|
|
380
|
+
delimiter !=
|
|
381
|
+
(uint32_t)'\\' &&
|
|
382
|
+
delimiter != (uint32_t)'\n';
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
static bool deserialized_state_is_valid(const ScannerState *candidate) {
|
|
386
|
+
if (candidate->mode == MODE_NONE) {
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (candidate->mode == MODE_TEXT) {
|
|
391
|
+
return candidate->delimiter ==
|
|
392
|
+
0 &&
|
|
393
|
+
candidate->regex_state ==
|
|
394
|
+
REGEX_OUTSIDE_BRACKET &&
|
|
395
|
+
regex_position_is_reset(candidate) &&
|
|
396
|
+
candidate->regex_group_depth ==
|
|
397
|
+
0 &&
|
|
398
|
+
candidate->regex_interval_state ==
|
|
399
|
+
REGEX_INTERVAL_NONE &&
|
|
400
|
+
bracket_tracking_is_reset(candidate);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (!deserialized_delimiter_is_valid((uint32_t)candidate->delimiter)) {
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (!is_regex_mode(candidate->mode)) {
|
|
408
|
+
return candidate->regex_state ==
|
|
409
|
+
REGEX_OUTSIDE_BRACKET &&
|
|
410
|
+
regex_position_is_reset(candidate) &&
|
|
411
|
+
candidate->text_state ==
|
|
412
|
+
TEXT_EMPTY &&
|
|
413
|
+
candidate->regex_interval_state ==
|
|
414
|
+
REGEX_INTERVAL_NONE &&
|
|
415
|
+
bracket_tracking_is_reset(candidate) &&
|
|
416
|
+
candidate->regex_group_depth == 0;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (candidate->text_state != TEXT_EMPTY) {
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (candidate->regex_state == REGEX_OUTSIDE_BRACKET) {
|
|
424
|
+
return bracket_tracking_is_reset(candidate);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (!regex_position_is_reset(candidate)) {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
if (
|
|
432
|
+
candidate->regex_state ==
|
|
433
|
+
REGEX_BRACKET_FIRST ||
|
|
434
|
+
candidate->regex_state == REGEX_BRACKET_AFTER_CARET
|
|
435
|
+
) {
|
|
436
|
+
return bracket_tracking_is_reset(candidate);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
return true;
|
|
440
|
+
}
|
|
441
|
+
|
|
336
442
|
static void
|
|
337
443
|
sed_scanner_deserialize(void *payload, const char *buffer, unsigned length) {
|
|
338
444
|
ScannerState *state = payload;
|
|
@@ -346,256 +452,106 @@ sed_scanner_deserialize(void *payload, const char *buffer, unsigned length) {
|
|
|
346
452
|
return;
|
|
347
453
|
}
|
|
348
454
|
|
|
349
|
-
const enum ScannerMode mode = (enum ScannerMode)(unsigned char)buffer[1];
|
|
350
|
-
const enum RegexState regex_state = (enum RegexState)(unsigned char)buffer[2];
|
|
351
455
|
const unsigned char mode_flags = (unsigned char)buffer[3];
|
|
352
|
-
const uint32_t delimiter = (uint32_t)(unsigned char)buffer[4] |
|
|
353
|
-
((uint32_t)(unsigned char)buffer[5] << 8) |
|
|
354
|
-
((uint32_t)(unsigned char)buffer[6] << 16) |
|
|
355
|
-
((uint32_t)(unsigned char)buffer[7] << 24);
|
|
356
|
-
const uint16_t regex_group_depth = deserialize_uint16(buffer, 8);
|
|
357
|
-
const enum RegexIntervalState regex_interval_state =
|
|
358
|
-
(enum RegexIntervalState)(unsigned char)buffer[10];
|
|
359
|
-
const enum RegexBracketTermState regex_bracket_term_state =
|
|
360
|
-
(enum RegexBracketTermState)(unsigned char)buffer[11];
|
|
361
|
-
const enum RegexBracketPendingElement regex_bracket_pending_element =
|
|
362
|
-
(enum RegexBracketPendingElement)(unsigned char)buffer[12];
|
|
363
|
-
const enum RegexBracketPendingElement regex_bracket_first_element =
|
|
364
|
-
(enum RegexBracketPendingElement)(unsigned char)buffer[13];
|
|
365
|
-
const enum RegexBracketPendingElement regex_bracket_last_element =
|
|
366
|
-
(enum RegexBracketPendingElement)(unsigned char)buffer[14];
|
|
367
|
-
const uint8_t regex_bracket_element_count =
|
|
368
|
-
(uint8_t)(unsigned char)buffer[15];
|
|
369
456
|
const unsigned char regex_bracket_flags = (unsigned char)buffer[16];
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
457
|
+
const ScannerState candidate = {
|
|
458
|
+
.delimiter = (int32_t)((uint32_t)(unsigned char)buffer[4] |
|
|
459
|
+
((uint32_t)(unsigned char)buffer[5] << 8) |
|
|
460
|
+
((uint32_t)(unsigned char)buffer[6] << 16) |
|
|
461
|
+
((uint32_t)(unsigned char)buffer[7] << 24)),
|
|
462
|
+
.mode = (enum ScannerMode)(unsigned char)buffer[1],
|
|
463
|
+
.regex_state = (enum RegexState)(unsigned char)buffer[2],
|
|
464
|
+
.regex_at_branch_start =
|
|
465
|
+
(mode_flags & SERIALIZED_AT_BRANCH_START_FLAG) != 0,
|
|
466
|
+
.regex_duplication_state = (enum RegexDuplicationState)(
|
|
467
|
+
(regex_bracket_flags >> SERIALIZED_DUPLICATION_STATE_SHIFT) & 3U
|
|
468
|
+
),
|
|
469
|
+
.regex_after_alternation =
|
|
470
|
+
(mode_flags & SERIALIZED_AFTER_ALTERNATION_FLAG) != 0,
|
|
471
|
+
.regex_after_anchor = (mode_flags & SERIALIZED_AFTER_ANCHOR_FLAG) != 0,
|
|
472
|
+
.text_state =
|
|
473
|
+
(enum TextState)((mode_flags >> SERIALIZED_TEXT_STATE_SHIFT) & 3U),
|
|
474
|
+
.regex_interval_state = (enum RegexIntervalState)(unsigned char)buffer[10],
|
|
475
|
+
.regex_bracket_term_state =
|
|
476
|
+
(enum RegexBracketTermState)(unsigned char)buffer[11],
|
|
477
|
+
.regex_bracket_pending_element =
|
|
478
|
+
(enum RegexBracketPendingElement)(unsigned char)buffer[12],
|
|
479
|
+
.regex_bracket_first_element =
|
|
480
|
+
(enum RegexBracketPendingElement)(unsigned char)buffer[13],
|
|
481
|
+
.regex_bracket_last_element =
|
|
482
|
+
(enum RegexBracketPendingElement)(unsigned char)buffer[14],
|
|
483
|
+
.regex_bracket_element_count = (uint8_t)(unsigned char)buffer[15],
|
|
484
|
+
.regex_bracket_range_pending =
|
|
485
|
+
(regex_bracket_flags & SERIALIZED_RANGE_PENDING_FLAG) != 0,
|
|
486
|
+
.regex_group_depth = deserialize_uint16(buffer, 8),
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
if (candidate.mode > MODE_TEXT) {
|
|
375
490
|
return;
|
|
376
491
|
}
|
|
377
492
|
|
|
378
|
-
if (regex_state > REGEX_BRACKET_BODY) {
|
|
493
|
+
if (candidate.regex_state > REGEX_BRACKET_BODY) {
|
|
379
494
|
return;
|
|
380
495
|
}
|
|
381
496
|
|
|
382
|
-
if ((mode_flags & (unsigned char)~
|
|
497
|
+
if ((mode_flags & (unsigned char)~SERIALIZED_MODE_FLAGS_MAXIMUM) != 0) {
|
|
383
498
|
return;
|
|
384
499
|
}
|
|
385
|
-
|
|
386
|
-
const bool regex_after_alternation = (mode_flags & 2U) != 0;
|
|
387
|
-
const bool regex_after_anchor = (mode_flags & 4U) != 0;
|
|
388
|
-
const enum TextState text_state = (enum TextState)((mode_flags >> 3) & 3U);
|
|
389
|
-
if (text_state > TEXT_AFTER_ESCAPED_NEWLINE) {
|
|
500
|
+
if (candidate.text_state > TEXT_AFTER_ESCAPED_NEWLINE) {
|
|
390
501
|
return;
|
|
391
502
|
}
|
|
392
503
|
#if !SED_REGEX_EXTENDED
|
|
393
|
-
if (regex_after_alternation) {
|
|
504
|
+
if (candidate.regex_after_alternation) {
|
|
394
505
|
return;
|
|
395
506
|
}
|
|
396
507
|
#endif
|
|
397
508
|
|
|
398
|
-
if (regex_interval_state > REGEX_INTERVAL_AFTER_MAXIMUM) {
|
|
509
|
+
if (candidate.regex_interval_state > REGEX_INTERVAL_AFTER_MAXIMUM) {
|
|
399
510
|
return;
|
|
400
511
|
}
|
|
401
|
-
if (regex_bracket_term_state > REGEX_BRACKET_TERM_EQUAL) {
|
|
512
|
+
if (candidate.regex_bracket_term_state > REGEX_BRACKET_TERM_EQUAL) {
|
|
402
513
|
return;
|
|
403
514
|
}
|
|
404
515
|
if (
|
|
405
|
-
regex_bracket_pending_element >
|
|
516
|
+
candidate.regex_bracket_pending_element >
|
|
406
517
|
REGEX_BRACKET_PENDING_COLON ||
|
|
407
|
-
regex_bracket_first_element >
|
|
518
|
+
candidate.regex_bracket_first_element >
|
|
408
519
|
REGEX_BRACKET_PENDING_COLON ||
|
|
409
|
-
regex_bracket_last_element >
|
|
520
|
+
candidate.regex_bracket_last_element >
|
|
410
521
|
REGEX_BRACKET_PENDING_COLON ||
|
|
411
|
-
regex_bracket_element_count >
|
|
522
|
+
candidate.regex_bracket_element_count >
|
|
412
523
|
3U ||
|
|
413
|
-
(regex_bracket_flags & (unsigned char)~
|
|
524
|
+
(regex_bracket_flags & (unsigned char)~SERIALIZED_BRACKET_FLAGS_MAXIMUM) !=
|
|
414
525
|
0 ||
|
|
415
526
|
#if SED_REGEX_EXTENDED
|
|
416
|
-
regex_duplication_state > REGEX_AFTER_REPETITION_MODIFIER
|
|
527
|
+
candidate.regex_duplication_state > REGEX_AFTER_REPETITION_MODIFIER
|
|
417
528
|
#else
|
|
418
|
-
regex_duplication_state > REGEX_AFTER_DUPLICATION_SYMBOL
|
|
529
|
+
candidate.regex_duplication_state > REGEX_AFTER_DUPLICATION_SYMBOL
|
|
419
530
|
#endif
|
|
420
531
|
) {
|
|
421
532
|
return;
|
|
422
533
|
}
|
|
423
534
|
if (
|
|
424
|
-
(regex_bracket_element_count ==
|
|
535
|
+
(candidate.regex_bracket_element_count ==
|
|
425
536
|
0 &&
|
|
426
|
-
(regex_bracket_first_element !=
|
|
537
|
+
(candidate.regex_bracket_first_element !=
|
|
427
538
|
REGEX_BRACKET_PENDING_NONE ||
|
|
428
|
-
regex_bracket_last_element != REGEX_BRACKET_PENDING_NONE)) ||
|
|
429
|
-
(regex_bracket_element_count >
|
|
539
|
+
candidate.regex_bracket_last_element != REGEX_BRACKET_PENDING_NONE)) ||
|
|
540
|
+
(candidate.regex_bracket_element_count >
|
|
430
541
|
0 &&
|
|
431
|
-
(regex_bracket_first_element ==
|
|
542
|
+
(candidate.regex_bracket_first_element ==
|
|
432
543
|
REGEX_BRACKET_PENDING_NONE ||
|
|
433
|
-
regex_bracket_last_element == REGEX_BRACKET_PENDING_NONE)) ||
|
|
434
|
-
(regex_bracket_pending_element !=
|
|
435
|
-
REGEX_BRACKET_PENDING_NONE &&
|
|
436
|
-
regex_bracket_range_pending)
|
|
437
|
-
) {
|
|
438
|
-
return;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
if (mode == MODE_NONE) {
|
|
442
|
-
return;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
if (mode == MODE_TEXT) {
|
|
446
|
-
if (
|
|
447
|
-
delimiter ==
|
|
448
|
-
0 &&
|
|
449
|
-
regex_state ==
|
|
450
|
-
REGEX_OUTSIDE_BRACKET &&
|
|
451
|
-
!regex_at_branch_start &&
|
|
452
|
-
regex_duplication_state ==
|
|
453
|
-
REGEX_DUPLICATION_NONE &&
|
|
454
|
-
regex_group_depth ==
|
|
455
|
-
0 &&
|
|
456
|
-
!regex_after_anchor &&
|
|
457
|
-
regex_interval_state ==
|
|
458
|
-
REGEX_INTERVAL_NONE &&
|
|
459
|
-
!regex_after_alternation &&
|
|
460
|
-
regex_bracket_term_state ==
|
|
461
|
-
REGEX_BRACKET_TERM_NONE &&
|
|
462
|
-
regex_bracket_pending_element ==
|
|
463
|
-
REGEX_BRACKET_PENDING_NONE &&
|
|
464
|
-
regex_bracket_first_element ==
|
|
544
|
+
candidate.regex_bracket_last_element == REGEX_BRACKET_PENDING_NONE)) ||
|
|
545
|
+
(candidate.regex_bracket_pending_element !=
|
|
465
546
|
REGEX_BRACKET_PENDING_NONE &&
|
|
466
|
-
|
|
467
|
-
REGEX_BRACKET_PENDING_NONE &&
|
|
468
|
-
regex_bracket_element_count ==
|
|
469
|
-
0 &&
|
|
470
|
-
!regex_bracket_range_pending
|
|
471
|
-
) {
|
|
472
|
-
state->mode = mode;
|
|
473
|
-
state->text_state = text_state;
|
|
474
|
-
}
|
|
475
|
-
return;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
if (
|
|
479
|
-
delimiter ==
|
|
480
|
-
0 ||
|
|
481
|
-
delimiter >
|
|
482
|
-
UINT32_C(0x10ffff) ||
|
|
483
|
-
(delimiter >= UINT32_C(0xd800) && delimiter <= UINT32_C(0xdfff)) ||
|
|
484
|
-
delimiter ==
|
|
485
|
-
(uint32_t)'\\' ||
|
|
486
|
-
delimiter == (uint32_t)'\n'
|
|
487
|
-
) {
|
|
488
|
-
return;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
if (
|
|
492
|
-
mode !=
|
|
493
|
-
MODE_REGEX_ADDRESS &&
|
|
494
|
-
mode !=
|
|
495
|
-
MODE_SUBSTITUTE_PATTERN &&
|
|
496
|
-
(regex_state !=
|
|
497
|
-
REGEX_OUTSIDE_BRACKET ||
|
|
498
|
-
regex_at_branch_start ||
|
|
499
|
-
regex_duplication_state !=
|
|
500
|
-
REGEX_DUPLICATION_NONE ||
|
|
501
|
-
regex_after_alternation ||
|
|
502
|
-
regex_after_anchor ||
|
|
503
|
-
text_state !=
|
|
504
|
-
TEXT_EMPTY ||
|
|
505
|
-
regex_interval_state !=
|
|
506
|
-
REGEX_INTERVAL_NONE ||
|
|
507
|
-
regex_bracket_term_state !=
|
|
508
|
-
REGEX_BRACKET_TERM_NONE ||
|
|
509
|
-
regex_bracket_pending_element !=
|
|
510
|
-
REGEX_BRACKET_PENDING_NONE ||
|
|
511
|
-
regex_bracket_first_element !=
|
|
512
|
-
REGEX_BRACKET_PENDING_NONE ||
|
|
513
|
-
regex_bracket_last_element !=
|
|
514
|
-
REGEX_BRACKET_PENDING_NONE ||
|
|
515
|
-
regex_bracket_element_count !=
|
|
516
|
-
0 ||
|
|
517
|
-
regex_bracket_range_pending)
|
|
518
|
-
) {
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
if (
|
|
523
|
-
regex_state !=
|
|
524
|
-
REGEX_OUTSIDE_BRACKET &&
|
|
525
|
-
(regex_at_branch_start ||
|
|
526
|
-
regex_duplication_state !=
|
|
527
|
-
REGEX_DUPLICATION_NONE ||
|
|
528
|
-
regex_after_alternation ||
|
|
529
|
-
regex_after_anchor)
|
|
530
|
-
) {
|
|
531
|
-
return;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
if (
|
|
535
|
-
regex_state ==
|
|
536
|
-
REGEX_OUTSIDE_BRACKET &&
|
|
537
|
-
(regex_bracket_term_state !=
|
|
538
|
-
REGEX_BRACKET_TERM_NONE ||
|
|
539
|
-
regex_bracket_pending_element !=
|
|
540
|
-
REGEX_BRACKET_PENDING_NONE ||
|
|
541
|
-
regex_bracket_first_element !=
|
|
542
|
-
REGEX_BRACKET_PENDING_NONE ||
|
|
543
|
-
regex_bracket_last_element !=
|
|
544
|
-
REGEX_BRACKET_PENDING_NONE ||
|
|
545
|
-
regex_bracket_element_count !=
|
|
546
|
-
0 ||
|
|
547
|
-
regex_bracket_range_pending)
|
|
548
|
-
) {
|
|
549
|
-
return;
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
if (
|
|
553
|
-
(regex_state ==
|
|
554
|
-
REGEX_BRACKET_FIRST ||
|
|
555
|
-
regex_state == REGEX_BRACKET_AFTER_CARET) &&
|
|
556
|
-
(regex_bracket_term_state !=
|
|
557
|
-
REGEX_BRACKET_TERM_NONE ||
|
|
558
|
-
regex_bracket_pending_element !=
|
|
559
|
-
REGEX_BRACKET_PENDING_NONE ||
|
|
560
|
-
regex_bracket_element_count !=
|
|
561
|
-
0 ||
|
|
562
|
-
regex_bracket_range_pending)
|
|
563
|
-
) {
|
|
564
|
-
return;
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
if (
|
|
568
|
-
(mode == MODE_REGEX_ADDRESS || mode == MODE_SUBSTITUTE_PATTERN) &&
|
|
569
|
-
text_state != TEXT_EMPTY
|
|
547
|
+
candidate.regex_bracket_range_pending)
|
|
570
548
|
) {
|
|
571
549
|
return;
|
|
572
550
|
}
|
|
573
551
|
|
|
574
|
-
if (
|
|
575
|
-
|
|
576
|
-
MODE_REGEX_ADDRESS &&
|
|
577
|
-
mode !=
|
|
578
|
-
MODE_SUBSTITUTE_PATTERN &&
|
|
579
|
-
regex_group_depth != 0
|
|
580
|
-
) {
|
|
581
|
-
return;
|
|
552
|
+
if (deserialized_state_is_valid(&candidate)) {
|
|
553
|
+
*state = candidate;
|
|
582
554
|
}
|
|
583
|
-
|
|
584
|
-
state->mode = mode;
|
|
585
|
-
state->delimiter = (int32_t)delimiter;
|
|
586
|
-
state->regex_state = regex_state;
|
|
587
|
-
state->regex_at_branch_start = regex_at_branch_start;
|
|
588
|
-
state->regex_duplication_state = regex_duplication_state;
|
|
589
|
-
state->regex_after_alternation = regex_after_alternation;
|
|
590
|
-
state->regex_after_anchor = regex_after_anchor;
|
|
591
|
-
state->regex_interval_state = regex_interval_state;
|
|
592
|
-
state->regex_bracket_term_state = regex_bracket_term_state;
|
|
593
|
-
state->regex_bracket_pending_element = regex_bracket_pending_element;
|
|
594
|
-
state->regex_bracket_first_element = regex_bracket_first_element;
|
|
595
|
-
state->regex_bracket_last_element = regex_bracket_last_element;
|
|
596
|
-
state->regex_bracket_element_count = regex_bracket_element_count;
|
|
597
|
-
state->regex_bracket_range_pending = regex_bracket_range_pending;
|
|
598
|
-
state->regex_group_depth = regex_group_depth;
|
|
599
555
|
}
|
|
600
556
|
|
|
601
557
|
static void advance(TSLexer *lexer) {
|
|
@@ -789,6 +745,42 @@ static bool scan_substitution_wfile_argument(TSLexer *lexer) {
|
|
|
789
745
|
return true;
|
|
790
746
|
}
|
|
791
747
|
|
|
748
|
+
enum FlagAfterWriteScan {
|
|
749
|
+
FLAG_AFTER_WRITE_NONE,
|
|
750
|
+
FLAG_AFTER_WRITE_MATCH,
|
|
751
|
+
FLAG_AFTER_WRITE_FALLBACK,
|
|
752
|
+
};
|
|
753
|
+
|
|
754
|
+
static bool is_substitution_flag_character(int32_t character) {
|
|
755
|
+
if (is_digit(character)) {
|
|
756
|
+
return true;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
switch (character) {
|
|
760
|
+
case 'g':
|
|
761
|
+
case 'i':
|
|
762
|
+
case 'p':
|
|
763
|
+
case 'w':
|
|
764
|
+
return true;
|
|
765
|
+
default:
|
|
766
|
+
return false;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
static enum FlagAfterWriteScan scan_flag_after_write_marker(TSLexer *lexer) {
|
|
771
|
+
if (!is_substitution_flag_character(lexer->lookahead)) {
|
|
772
|
+
return FLAG_AFTER_WRITE_NONE;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
lexer->mark_end(lexer);
|
|
776
|
+
do {
|
|
777
|
+
advance(lexer);
|
|
778
|
+
} while (is_substitution_flag_character(lexer->lookahead));
|
|
779
|
+
|
|
780
|
+
return is_blank(lexer->lookahead) ? FLAG_AFTER_WRITE_MATCH
|
|
781
|
+
: FLAG_AFTER_WRITE_FALLBACK;
|
|
782
|
+
}
|
|
783
|
+
|
|
792
784
|
static bool scan_right_brace(TSLexer *lexer, ScannerState *state) {
|
|
793
785
|
if (state->mode != MODE_NONE) {
|
|
794
786
|
return false;
|
|
@@ -883,8 +875,8 @@ static enum PostBlankRecoveryScan scan_post_blank_recovery(
|
|
|
883
875
|
) {
|
|
884
876
|
if (
|
|
885
877
|
!valid_symbols[OMITTED_ADDRESS_MARKER] &&
|
|
886
|
-
!valid_symbols[
|
|
887
|
-
!valid_symbols[
|
|
878
|
+
!valid_symbols[INCOMPLETE_OMITTED_ADDRESS_MARKER] &&
|
|
879
|
+
!valid_symbols[BLANKS_AROUND_ADDRESS_SEPARATOR] &&
|
|
888
880
|
!valid_symbols[MISSING_ADDRESS_SEPARATOR_MARKER] &&
|
|
889
881
|
!valid_symbols[MISSING_SEPARATOR_BEFORE_UNMATCHED_BRACE_MARKER] &&
|
|
890
882
|
!valid_symbols[MISSING_COMMAND_SEPARATOR_MARKER] &&
|
|
@@ -896,22 +888,23 @@ static enum PostBlankRecoveryScan scan_post_blank_recovery(
|
|
|
896
888
|
lexer->mark_end(lexer);
|
|
897
889
|
advance_past_blanks(lexer);
|
|
898
890
|
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
}
|
|
891
|
+
const bool after_separator = valid_symbols[OMITTED_ADDRESS_MARKER] ||
|
|
892
|
+
valid_symbols[INCOMPLETE_OMITTED_ADDRESS_MARKER];
|
|
893
|
+
|
|
903
894
|
if (
|
|
904
|
-
valid_symbols[
|
|
905
|
-
(lexer->lookahead == ','
|
|
895
|
+
valid_symbols[BLANKS_AROUND_ADDRESS_SEPARATOR] &&
|
|
896
|
+
(after_separator ? can_start_address(lexer) : lexer->lookahead == ',')
|
|
906
897
|
) {
|
|
907
|
-
|
|
898
|
+
lexer->mark_end(lexer);
|
|
899
|
+
*symbol = BLANKS_AROUND_ADDRESS_SEPARATOR;
|
|
908
900
|
return POST_BLANK_RECOVERY_TOKEN;
|
|
909
901
|
}
|
|
910
|
-
if (
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
902
|
+
if (after_separator && !can_start_address(lexer)) {
|
|
903
|
+
*symbol = lexer->eof(lexer) ? INCOMPLETE_OMITTED_ADDRESS_MARKER
|
|
904
|
+
: OMITTED_ADDRESS_MARKER;
|
|
905
|
+
if (!valid_symbols[*symbol]) {
|
|
906
|
+
return POST_BLANK_RECOVERY_FAILED;
|
|
907
|
+
}
|
|
915
908
|
return POST_BLANK_RECOVERY_TOKEN;
|
|
916
909
|
}
|
|
917
910
|
if (
|
|
@@ -1021,10 +1014,6 @@ static bool scan_text_token(
|
|
|
1021
1014
|
return true;
|
|
1022
1015
|
}
|
|
1023
1016
|
|
|
1024
|
-
static bool is_regex_mode(enum ScannerMode mode) {
|
|
1025
|
-
return mode == MODE_REGEX_ADDRESS || mode == MODE_SUBSTITUTE_PATTERN;
|
|
1026
|
-
}
|
|
1027
|
-
|
|
1028
1017
|
static bool regex_is_inside_bracket(const ScannerState *state) {
|
|
1029
1018
|
return state->regex_state != REGEX_OUTSIDE_BRACKET;
|
|
1030
1019
|
}
|
|
@@ -1125,44 +1114,36 @@ update_bracket_state_after_literal(ScannerState *state, int32_t character) {
|
|
|
1125
1114
|
static bool
|
|
1126
1115
|
regex_literal_boundary(const ScannerState *state, int32_t character) {
|
|
1127
1116
|
if (state->regex_state == REGEX_OUTSIDE_BRACKET) {
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
'|' ||
|
|
1146
|
-
character ==
|
|
1147
|
-
'{' ||
|
|
1148
|
-
character ==
|
|
1149
|
-
'.' ||
|
|
1150
|
-
character ==
|
|
1151
|
-
'^' ||
|
|
1152
|
-
character == '$';
|
|
1117
|
+
switch (character) {
|
|
1118
|
+
case '\\':
|
|
1119
|
+
case '(':
|
|
1120
|
+
case ')':
|
|
1121
|
+
case '[':
|
|
1122
|
+
case '*':
|
|
1123
|
+
case '+':
|
|
1124
|
+
case '?':
|
|
1125
|
+
case '|':
|
|
1126
|
+
case '{':
|
|
1127
|
+
case '.':
|
|
1128
|
+
case '^':
|
|
1129
|
+
case '$':
|
|
1130
|
+
return true;
|
|
1131
|
+
default:
|
|
1132
|
+
return character == state->delimiter;
|
|
1133
|
+
}
|
|
1153
1134
|
}
|
|
1154
1135
|
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
'[' ||
|
|
1158
|
-
(state->regex_state == REGEX_BRACKET_FIRST && character == '^') ||
|
|
1159
|
-
(state->regex_state == REGEX_BRACKET_BODY && character == '-') ||
|
|
1160
|
-
(state->regex_state == REGEX_BRACKET_BODY && character == ']')
|
|
1161
|
-
) {
|
|
1136
|
+
switch (character) {
|
|
1137
|
+
case '[':
|
|
1162
1138
|
return true;
|
|
1139
|
+
case '^':
|
|
1140
|
+
return state->regex_state == REGEX_BRACKET_FIRST;
|
|
1141
|
+
case '-':
|
|
1142
|
+
case ']':
|
|
1143
|
+
return state->regex_state == REGEX_BRACKET_BODY;
|
|
1144
|
+
default:
|
|
1145
|
+
return false;
|
|
1163
1146
|
}
|
|
1164
|
-
|
|
1165
|
-
return false;
|
|
1166
1147
|
}
|
|
1167
1148
|
|
|
1168
1149
|
static enum LiteralScanResult
|
|
@@ -1230,15 +1211,19 @@ static bool scan_regex_bracket_opener(
|
|
|
1230
1211
|
lexer->mark_end(lexer);
|
|
1231
1212
|
|
|
1232
1213
|
TSSymbol candidate;
|
|
1214
|
+
enum RegexBracketTermState term_state;
|
|
1233
1215
|
switch (lexer->lookahead) {
|
|
1234
1216
|
case ':':
|
|
1235
1217
|
candidate = REGEX_OPEN_COLON;
|
|
1218
|
+
term_state = REGEX_BRACKET_TERM_COLON;
|
|
1236
1219
|
break;
|
|
1237
1220
|
case '.':
|
|
1238
1221
|
candidate = REGEX_OPEN_DOT;
|
|
1222
|
+
term_state = REGEX_BRACKET_TERM_DOT;
|
|
1239
1223
|
break;
|
|
1240
1224
|
case '=':
|
|
1241
1225
|
candidate = REGEX_OPEN_EQUAL;
|
|
1226
|
+
term_state = REGEX_BRACKET_TERM_EQUAL;
|
|
1242
1227
|
break;
|
|
1243
1228
|
default:
|
|
1244
1229
|
begin_single_bracket_element(state, '[');
|
|
@@ -1252,10 +1237,7 @@ static bool scan_regex_bracket_opener(
|
|
|
1252
1237
|
consume(lexer);
|
|
1253
1238
|
begin_compound_bracket_element(state);
|
|
1254
1239
|
finish_first_bracket_element(state);
|
|
1255
|
-
state->regex_bracket_term_state =
|
|
1256
|
-
? REGEX_BRACKET_TERM_COLON
|
|
1257
|
-
: candidate == REGEX_OPEN_DOT ? REGEX_BRACKET_TERM_DOT
|
|
1258
|
-
: REGEX_BRACKET_TERM_EQUAL;
|
|
1240
|
+
state->regex_bracket_term_state = term_state;
|
|
1259
1241
|
*symbol = candidate;
|
|
1260
1242
|
return true;
|
|
1261
1243
|
}
|
|
@@ -1277,6 +1259,18 @@ static bool bracket_meta_character(int32_t character) {
|
|
|
1277
1259
|
return character == '^' || character == '-' || character == ']';
|
|
1278
1260
|
}
|
|
1279
1261
|
|
|
1262
|
+
static int32_t
|
|
1263
|
+
bracket_term_close_marker(enum RegexBracketTermState term_state) {
|
|
1264
|
+
switch (term_state) {
|
|
1265
|
+
case REGEX_BRACKET_TERM_COLON:
|
|
1266
|
+
return ':';
|
|
1267
|
+
case REGEX_BRACKET_TERM_DOT:
|
|
1268
|
+
return '.';
|
|
1269
|
+
default:
|
|
1270
|
+
return '=';
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1280
1274
|
static TSSymbol regex_bracket_term_content_symbol(
|
|
1281
1275
|
const ScannerState *state,
|
|
1282
1276
|
uint8_t character_count,
|
|
@@ -1509,6 +1503,18 @@ static bool scan_regex_interval(
|
|
|
1509
1503
|
return emit_symbol(valid_symbols, REGEX_INTERVAL_OPEN, symbol);
|
|
1510
1504
|
}
|
|
1511
1505
|
|
|
1506
|
+
static bool emit_interval_issue(
|
|
1507
|
+
TSLexer *lexer,
|
|
1508
|
+
ScannerState *state,
|
|
1509
|
+
TSSymbol candidate,
|
|
1510
|
+
TSSymbol *symbol
|
|
1511
|
+
) {
|
|
1512
|
+
lexer->mark_end(lexer);
|
|
1513
|
+
state->regex_interval_state = REGEX_INTERVAL_NONE;
|
|
1514
|
+
*symbol = candidate;
|
|
1515
|
+
return true;
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1512
1518
|
static bool
|
|
1513
1519
|
scan_invalid_interval_remainder(TSLexer *lexer, ScannerState *state);
|
|
1514
1520
|
|
|
@@ -1604,9 +1610,7 @@ static enum DuplicationContextScan scan_regex_duplication_context_marker(
|
|
|
1604
1610
|
#endif
|
|
1605
1611
|
|
|
1606
1612
|
if (lexer->eof(lexer) && valid_symbols[REGEX_INCOMPLETE_INTERVAL]) {
|
|
1607
|
-
|
|
1608
|
-
state->regex_interval_state = REGEX_INTERVAL_NONE;
|
|
1609
|
-
*symbol = REGEX_INCOMPLETE_INTERVAL;
|
|
1613
|
+
emit_interval_issue(lexer, state, REGEX_INCOMPLETE_INTERVAL, symbol);
|
|
1610
1614
|
return DUPLICATION_CONTEXT_TOKEN;
|
|
1611
1615
|
}
|
|
1612
1616
|
|
|
@@ -1615,12 +1619,25 @@ static enum DuplicationContextScan scan_regex_duplication_context_marker(
|
|
|
1615
1619
|
return DUPLICATION_CONTEXT_TOKEN;
|
|
1616
1620
|
}
|
|
1617
1621
|
scan_invalid_interval_remainder(lexer, state);
|
|
1618
|
-
|
|
1619
|
-
state->regex_interval_state = REGEX_INTERVAL_NONE;
|
|
1620
|
-
*symbol = REGEX_INVALID_INTERVAL;
|
|
1622
|
+
emit_interval_issue(lexer, state, REGEX_INVALID_INTERVAL, symbol);
|
|
1621
1623
|
return DUPLICATION_CONTEXT_TOKEN;
|
|
1622
1624
|
}
|
|
1623
1625
|
|
|
1626
|
+
static bool raw_regex_operator_character(int32_t character) {
|
|
1627
|
+
switch (character) {
|
|
1628
|
+
case '(':
|
|
1629
|
+
case ')':
|
|
1630
|
+
case '*':
|
|
1631
|
+
case '+':
|
|
1632
|
+
case '?':
|
|
1633
|
+
case '|':
|
|
1634
|
+
case '{':
|
|
1635
|
+
return true;
|
|
1636
|
+
default:
|
|
1637
|
+
return false;
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1624
1641
|
static bool scan_raw_regex_operator(
|
|
1625
1642
|
TSLexer *lexer,
|
|
1626
1643
|
ScannerState *state,
|
|
@@ -1689,39 +1706,42 @@ static bool scan_raw_regex_operator(
|
|
|
1689
1706
|
}
|
|
1690
1707
|
|
|
1691
1708
|
static bool regex_delimiter_is_special(int32_t character) {
|
|
1709
|
+
switch (character) {
|
|
1692
1710
|
#if SED_REGEX_EXTENDED
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
return character ==
|
|
1716
|
-
'.' ||
|
|
1717
|
-
character ==
|
|
1718
|
-
'[' ||
|
|
1719
|
-
character ==
|
|
1720
|
-
'*' ||
|
|
1721
|
-
character ==
|
|
1722
|
-
'^' ||
|
|
1723
|
-
character == '$';
|
|
1711
|
+
case '(':
|
|
1712
|
+
case ')':
|
|
1713
|
+
case '+':
|
|
1714
|
+
case '?':
|
|
1715
|
+
case '{':
|
|
1716
|
+
case '|':
|
|
1717
|
+
#endif
|
|
1718
|
+
case '.':
|
|
1719
|
+
case '[':
|
|
1720
|
+
case '*':
|
|
1721
|
+
case '^':
|
|
1722
|
+
case '$':
|
|
1723
|
+
return true;
|
|
1724
|
+
default:
|
|
1725
|
+
return false;
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
|
|
1729
|
+
static bool escape_quotes_regex_syntax(int32_t character) {
|
|
1730
|
+
switch (character) {
|
|
1731
|
+
#if SED_REGEX_EXTENDED
|
|
1732
|
+
case '}':
|
|
1724
1733
|
#endif
|
|
1734
|
+
case '.':
|
|
1735
|
+
case '*':
|
|
1736
|
+
case '^':
|
|
1737
|
+
case '$':
|
|
1738
|
+
case '[':
|
|
1739
|
+
case '\\':
|
|
1740
|
+
case ']':
|
|
1741
|
+
return true;
|
|
1742
|
+
default:
|
|
1743
|
+
return false;
|
|
1744
|
+
}
|
|
1725
1745
|
}
|
|
1726
1746
|
|
|
1727
1747
|
static bool scan_regex_escaped_delimiter(
|
|
@@ -1837,29 +1857,11 @@ static bool scan_regex_escape_after_backslash(
|
|
|
1837
1857
|
return emit_symbol(valid_symbols, REGEX_NEWLINE_ESCAPE, symbol);
|
|
1838
1858
|
}
|
|
1839
1859
|
|
|
1840
|
-
const
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
character ==
|
|
1844
|
-
'*' ||
|
|
1845
|
-
character ==
|
|
1846
|
-
'^' ||
|
|
1847
|
-
character ==
|
|
1848
|
-
'$' ||
|
|
1849
|
-
character ==
|
|
1850
|
-
'[' ||
|
|
1851
|
-
character ==
|
|
1852
|
-
'\\' ||
|
|
1853
|
-
character ==
|
|
1854
|
-
']' ||
|
|
1855
|
-
(SED_REGEX_EXTENDED && character == '}');
|
|
1856
|
-
if (!quotes_regex_syntax) {
|
|
1857
|
-
consume(lexer);
|
|
1858
|
-
return emit_symbol(valid_symbols, REGEX_NONPORTABLE_ESCAPE, symbol);
|
|
1859
|
-
}
|
|
1860
|
-
|
|
1860
|
+
const TSSymbol candidate = escape_quotes_regex_syntax(lexer->lookahead)
|
|
1861
|
+
? REGEX_QUOTED_ESCAPE
|
|
1862
|
+
: REGEX_NONPORTABLE_ESCAPE;
|
|
1861
1863
|
consume(lexer);
|
|
1862
|
-
return emit_symbol(valid_symbols,
|
|
1864
|
+
return emit_symbol(valid_symbols, candidate, symbol);
|
|
1863
1865
|
}
|
|
1864
1866
|
|
|
1865
1867
|
#if !SED_REGEX_EXTENDED
|
|
@@ -2053,10 +2055,12 @@ static bool scan_regex_token(
|
|
|
2053
2055
|
return true;
|
|
2054
2056
|
}
|
|
2055
2057
|
if (lexer->eof(lexer) && valid_symbols[REGEX_INCOMPLETE_INTERVAL]) {
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2058
|
+
return emit_interval_issue(
|
|
2059
|
+
lexer,
|
|
2060
|
+
state,
|
|
2061
|
+
REGEX_INCOMPLETE_INTERVAL,
|
|
2062
|
+
symbol
|
|
2063
|
+
);
|
|
2060
2064
|
}
|
|
2061
2065
|
if (!valid_symbols[REGEX_INVALID_INTERVAL]) {
|
|
2062
2066
|
return false;
|
|
@@ -2067,10 +2071,7 @@ static bool scan_regex_token(
|
|
|
2067
2071
|
advance_past_escaped_character(lexer);
|
|
2068
2072
|
scan_invalid_interval_remainder(lexer, state);
|
|
2069
2073
|
}
|
|
2070
|
-
|
|
2071
|
-
state->regex_interval_state = REGEX_INTERVAL_NONE;
|
|
2072
|
-
*symbol = REGEX_INVALID_INTERVAL;
|
|
2073
|
-
return true;
|
|
2074
|
+
return emit_interval_issue(lexer, state, REGEX_INVALID_INTERVAL, symbol);
|
|
2074
2075
|
}
|
|
2075
2076
|
#endif
|
|
2076
2077
|
|
|
@@ -2092,14 +2093,10 @@ static bool scan_regex_token(
|
|
|
2092
2093
|
valid_symbols[REGEX_COLL_ELEM_MULTI] ||
|
|
2093
2094
|
valid_symbols[REGEX_META_CHAR]
|
|
2094
2095
|
) {
|
|
2095
|
-
const int32_t close_marker =
|
|
2096
|
-
state->regex_bracket_term_state == REGEX_BRACKET_TERM_COLON ? ':'
|
|
2097
|
-
: state->regex_bracket_term_state == REGEX_BRACKET_TERM_DOT ? '.'
|
|
2098
|
-
: '=';
|
|
2099
2096
|
return scan_regex_bracket_term_content(
|
|
2100
2097
|
lexer,
|
|
2101
2098
|
state,
|
|
2102
|
-
|
|
2099
|
+
bracket_term_close_marker(state->regex_bracket_term_state),
|
|
2103
2100
|
valid_symbols,
|
|
2104
2101
|
symbol
|
|
2105
2102
|
);
|
|
@@ -2234,21 +2231,7 @@ static bool scan_regex_token(
|
|
|
2234
2231
|
);
|
|
2235
2232
|
}
|
|
2236
2233
|
|
|
2237
|
-
if (
|
|
2238
|
-
lexer->lookahead ==
|
|
2239
|
-
'(' ||
|
|
2240
|
-
lexer->lookahead ==
|
|
2241
|
-
')' ||
|
|
2242
|
-
lexer->lookahead ==
|
|
2243
|
-
'*' ||
|
|
2244
|
-
lexer->lookahead ==
|
|
2245
|
-
'+' ||
|
|
2246
|
-
lexer->lookahead ==
|
|
2247
|
-
'?' ||
|
|
2248
|
-
lexer->lookahead ==
|
|
2249
|
-
'|' ||
|
|
2250
|
-
lexer->lookahead == '{'
|
|
2251
|
-
) {
|
|
2234
|
+
if (raw_regex_operator_character(lexer->lookahead)) {
|
|
2252
2235
|
return scan_raw_regex_operator(lexer, state, valid_symbols, symbol);
|
|
2253
2236
|
}
|
|
2254
2237
|
|
|
@@ -2514,226 +2497,196 @@ static bool scan_translate_token(
|
|
|
2514
2497
|
return false;
|
|
2515
2498
|
}
|
|
2516
2499
|
|
|
2517
|
-
static bool
|
|
2518
|
-
ScannerState *state,
|
|
2500
|
+
static bool scan_regex_recovery_marker(
|
|
2519
2501
|
TSLexer *lexer,
|
|
2502
|
+
ScannerState *state,
|
|
2520
2503
|
const bool *valid_symbols,
|
|
2521
2504
|
TSSymbol *symbol
|
|
2522
2505
|
) {
|
|
2523
|
-
|
|
2524
|
-
|
|
2506
|
+
#if !SED_REGEX_EXTENDED
|
|
2507
|
+
if (
|
|
2508
|
+
emit_missing_marker(
|
|
2509
|
+
lexer,
|
|
2510
|
+
valid_symbols,
|
|
2511
|
+
BRE_VERTICAL_LINE_ESCAPE_MARKER,
|
|
2512
|
+
symbol
|
|
2513
|
+
) ||
|
|
2514
|
+
emit_missing_marker(
|
|
2515
|
+
lexer,
|
|
2516
|
+
valid_symbols,
|
|
2517
|
+
BRE_QUESTION_MARK_ESCAPE_MARKER,
|
|
2518
|
+
symbol
|
|
2519
|
+
) ||
|
|
2520
|
+
emit_missing_marker(lexer, valid_symbols, BRE_PLUS_ESCAPE_MARKER, symbol)
|
|
2521
|
+
) {
|
|
2522
|
+
return true;
|
|
2525
2523
|
}
|
|
2524
|
+
#endif
|
|
2526
2525
|
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2526
|
+
const bool at_line_boundary = lexer->eof(lexer) || lexer->lookahead == '\n';
|
|
2527
|
+
const bool at_regex_end =
|
|
2528
|
+
at_line_boundary || lexer->lookahead == state->delimiter;
|
|
2530
2529
|
|
|
2531
|
-
#if !SED_REGEX_EXTENDED
|
|
2532
2530
|
if (
|
|
2533
|
-
is_regex_mode(state->mode) &&
|
|
2534
|
-
(emit_missing_marker(
|
|
2535
|
-
lexer,
|
|
2536
|
-
valid_symbols,
|
|
2537
|
-
BRE_VERTICAL_LINE_ESCAPE_MARKER,
|
|
2538
|
-
symbol
|
|
2539
|
-
) ||
|
|
2540
|
-
emit_missing_marker(
|
|
2541
|
-
lexer,
|
|
2542
|
-
valid_symbols,
|
|
2543
|
-
BRE_QUESTION_MARK_ESCAPE_MARKER,
|
|
2544
|
-
symbol
|
|
2545
|
-
) ||
|
|
2546
|
-
emit_missing_marker(
|
|
2547
|
-
lexer,
|
|
2548
|
-
valid_symbols,
|
|
2549
|
-
BRE_PLUS_ESCAPE_MARKER,
|
|
2550
|
-
symbol
|
|
2551
|
-
) ||
|
|
2552
|
-
emit_missing_marker(
|
|
2553
|
-
lexer,
|
|
2554
|
-
valid_symbols,
|
|
2555
|
-
UNMATCHED_INTERVAL_CLOSE_MARKER,
|
|
2556
|
-
symbol
|
|
2557
|
-
))
|
|
2558
|
-
) {
|
|
2559
|
-
return true;
|
|
2560
|
-
}
|
|
2561
|
-
#endif
|
|
2562
|
-
|
|
2563
|
-
if (
|
|
2564
|
-
is_regex_mode(state->mode) &&
|
|
2565
2531
|
state->regex_state ==
|
|
2566
2532
|
REGEX_OUTSIDE_BRACKET &&
|
|
2567
2533
|
state->regex_group_depth >
|
|
2568
2534
|
0 &&
|
|
2569
2535
|
!state->regex_after_alternation &&
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2536
|
+
at_regex_end &&
|
|
2537
|
+
emit_missing_marker(
|
|
2538
|
+
lexer,
|
|
2539
|
+
valid_symbols,
|
|
2540
|
+
lexer->eof(lexer) ? MISSING_SUBEXPRESSION_MARKER
|
|
2541
|
+
: MISSING_SUBEXPRESSION_PLACEHOLDER_MARKER,
|
|
2542
|
+
symbol
|
|
2543
|
+
)
|
|
2574
2544
|
) {
|
|
2575
|
-
|
|
2576
|
-
? MISSING_SUBEXPRESSION_MARKER
|
|
2577
|
-
: MISSING_SUBEXPRESSION_PLACEHOLDER_MARKER;
|
|
2578
|
-
if (valid_symbols[candidate]) {
|
|
2579
|
-
lexer->mark_end(lexer);
|
|
2580
|
-
*symbol = candidate;
|
|
2581
|
-
return true;
|
|
2582
|
-
}
|
|
2545
|
+
return true;
|
|
2583
2546
|
}
|
|
2584
2547
|
|
|
2585
2548
|
if (
|
|
2586
|
-
is_regex_mode(state->mode) &&
|
|
2587
2549
|
(state->regex_state ==
|
|
2588
2550
|
REGEX_BRACKET_FIRST ||
|
|
2589
2551
|
state->regex_state == REGEX_BRACKET_AFTER_CARET) &&
|
|
2590
|
-
|
|
2552
|
+
at_line_boundary &&
|
|
2553
|
+
emit_missing_marker(
|
|
2554
|
+
lexer,
|
|
2555
|
+
valid_symbols,
|
|
2556
|
+
lexer->eof(lexer) ? INCOMPLETE_BRACKET_LIST_MARKER
|
|
2557
|
+
: MISSING_BRACKET_LIST_MARKER,
|
|
2558
|
+
symbol
|
|
2559
|
+
)
|
|
2591
2560
|
) {
|
|
2592
|
-
|
|
2593
|
-
? INCOMPLETE_BRACKET_LIST_MARKER
|
|
2594
|
-
: MISSING_BRACKET_LIST_MARKER;
|
|
2595
|
-
if (valid_symbols[candidate]) {
|
|
2596
|
-
lexer->mark_end(lexer);
|
|
2597
|
-
*symbol = candidate;
|
|
2598
|
-
return true;
|
|
2599
|
-
}
|
|
2561
|
+
return true;
|
|
2600
2562
|
}
|
|
2601
2563
|
|
|
2602
2564
|
if (
|
|
2603
|
-
is_regex_mode(state->mode) &&
|
|
2604
2565
|
state->regex_bracket_term_state !=
|
|
2605
2566
|
REGEX_BRACKET_TERM_NONE &&
|
|
2606
|
-
|
|
2567
|
+
at_line_boundary &&
|
|
2568
|
+
emit_missing_marker(
|
|
2569
|
+
lexer,
|
|
2570
|
+
valid_symbols,
|
|
2571
|
+
lexer->eof(lexer) ? REGEX_INCOMPLETE_BRACKET_TERM
|
|
2572
|
+
: REGEX_MALFORMED_BRACKET_TERM,
|
|
2573
|
+
symbol
|
|
2574
|
+
)
|
|
2607
2575
|
) {
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
lexer->mark_end(lexer);
|
|
2612
|
-
state->regex_bracket_term_state = REGEX_BRACKET_TERM_NONE;
|
|
2613
|
-
finish_compound_bracket_element(state);
|
|
2614
|
-
*symbol = candidate;
|
|
2615
|
-
return true;
|
|
2616
|
-
}
|
|
2576
|
+
state->regex_bracket_term_state = REGEX_BRACKET_TERM_NONE;
|
|
2577
|
+
finish_compound_bracket_element(state);
|
|
2578
|
+
return true;
|
|
2617
2579
|
}
|
|
2618
2580
|
|
|
2619
2581
|
if (
|
|
2620
|
-
is_regex_mode(state->mode) &&
|
|
2621
2582
|
regex_is_inside_bracket(state) &&
|
|
2622
|
-
|
|
2583
|
+
at_line_boundary &&
|
|
2584
|
+
emit_missing_marker(
|
|
2585
|
+
lexer,
|
|
2586
|
+
valid_symbols,
|
|
2587
|
+
lexer->eof(lexer) ? INCOMPLETE_BRACKET_EXPRESSION_MARKER
|
|
2588
|
+
: UNCLOSED_BRACKET_EXPRESSION_MARKER,
|
|
2589
|
+
symbol
|
|
2590
|
+
)
|
|
2623
2591
|
) {
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
if (valid_symbols[candidate]) {
|
|
2628
|
-
lexer->mark_end(lexer);
|
|
2629
|
-
state->regex_state = REGEX_OUTSIDE_BRACKET;
|
|
2630
|
-
reset_bracket_tracking(state);
|
|
2631
|
-
*symbol = candidate;
|
|
2632
|
-
return true;
|
|
2633
|
-
}
|
|
2592
|
+
state->regex_state = REGEX_OUTSIDE_BRACKET;
|
|
2593
|
+
reset_bracket_tracking(state);
|
|
2594
|
+
return true;
|
|
2634
2595
|
}
|
|
2635
2596
|
|
|
2636
2597
|
#if SED_REGEX_EXTENDED
|
|
2637
2598
|
if (
|
|
2638
|
-
is_regex_mode(state->mode) &&
|
|
2639
2599
|
state->regex_state ==
|
|
2640
2600
|
REGEX_OUTSIDE_BRACKET &&
|
|
2641
2601
|
state->regex_after_alternation &&
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
lexer
|
|
2645
|
-
|
|
2646
|
-
lexer->eof(lexer)
|
|
2602
|
+
at_regex_end &&
|
|
2603
|
+
emit_missing_marker(
|
|
2604
|
+
lexer,
|
|
2605
|
+
valid_symbols,
|
|
2606
|
+
lexer->eof(lexer) ? INCOMPLETE_ALTERNATIVE_MARKER
|
|
2607
|
+
: EMPTY_ALTERNATIVE_MARKER,
|
|
2608
|
+
symbol
|
|
2609
|
+
)
|
|
2647
2610
|
) {
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
if (valid_symbols[candidate]) {
|
|
2651
|
-
lexer->mark_end(lexer);
|
|
2652
|
-
state->regex_after_alternation = false;
|
|
2653
|
-
*symbol = candidate;
|
|
2654
|
-
return true;
|
|
2655
|
-
}
|
|
2611
|
+
state->regex_after_alternation = false;
|
|
2612
|
+
return true;
|
|
2656
2613
|
}
|
|
2657
2614
|
#endif
|
|
2658
2615
|
|
|
2659
2616
|
if (
|
|
2660
|
-
is_regex_mode(state->mode) &&
|
|
2661
2617
|
state->regex_interval_state !=
|
|
2662
2618
|
REGEX_INTERVAL_NONE &&
|
|
2663
|
-
(
|
|
2664
|
-
state->delimiter ||
|
|
2665
|
-
lexer->lookahead ==
|
|
2666
|
-
'\n' ||
|
|
2619
|
+
(at_regex_end
|
|
2667
2620
|
#if !SED_REGEX_EXTENDED
|
|
2668
|
-
|
|
2621
|
+
|| (state->delimiter == '}' && lexer->lookahead == '\\')
|
|
2669
2622
|
#endif
|
|
2670
|
-
|
|
2623
|
+
) &&
|
|
2624
|
+
emit_missing_marker(
|
|
2625
|
+
lexer,
|
|
2626
|
+
valid_symbols,
|
|
2627
|
+
lexer->eof(lexer) ? REGEX_INCOMPLETE_INTERVAL : REGEX_INVALID_INTERVAL,
|
|
2628
|
+
symbol
|
|
2629
|
+
)
|
|
2671
2630
|
) {
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
if (valid_symbols[candidate]) {
|
|
2675
|
-
lexer->mark_end(lexer);
|
|
2676
|
-
state->regex_interval_state = REGEX_INTERVAL_NONE;
|
|
2677
|
-
*symbol = candidate;
|
|
2678
|
-
return true;
|
|
2679
|
-
}
|
|
2631
|
+
state->regex_interval_state = REGEX_INTERVAL_NONE;
|
|
2632
|
+
return true;
|
|
2680
2633
|
}
|
|
2681
2634
|
|
|
2682
2635
|
if (
|
|
2683
|
-
is_regex_mode(state->mode) &&
|
|
2684
2636
|
state->regex_state ==
|
|
2685
2637
|
REGEX_OUTSIDE_BRACKET &&
|
|
2686
|
-
|
|
2638
|
+
state->regex_group_depth >
|
|
2639
|
+
0 &&
|
|
2640
|
+
at_line_boundary &&
|
|
2641
|
+
emit_missing_marker(
|
|
2642
|
+
lexer,
|
|
2643
|
+
valid_symbols,
|
|
2644
|
+
lexer->eof(lexer) ? REGEX_INCOMPLETE_GROUP : REGEX_UNCLOSED_GROUP,
|
|
2645
|
+
symbol
|
|
2646
|
+
)
|
|
2687
2647
|
) {
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
lexer->eof(lexer) ? REGEX_INCOMPLETE_GROUP : REGEX_UNCLOSED_GROUP;
|
|
2691
|
-
if (valid_symbols[candidate]) {
|
|
2692
|
-
lexer->mark_end(lexer);
|
|
2693
|
-
state->regex_group_depth--;
|
|
2694
|
-
*symbol = candidate;
|
|
2695
|
-
return true;
|
|
2696
|
-
}
|
|
2697
|
-
}
|
|
2648
|
+
state->regex_group_depth--;
|
|
2649
|
+
return true;
|
|
2698
2650
|
}
|
|
2699
2651
|
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
state->mode !=
|
|
2703
|
-
MODE_TEXT &&
|
|
2704
|
-
lexer->lookahead ==
|
|
2705
|
-
state->delimiter &&
|
|
2706
|
-
(!is_regex_mode(state->mode) ||
|
|
2707
|
-
state->regex_state == REGEX_OUTSIDE_BRACKET);
|
|
2708
|
-
if (delimiter_is_active) {
|
|
2709
|
-
if (state->regex_group_depth > 0 && valid_symbols[REGEX_UNCLOSED_GROUP]) {
|
|
2710
|
-
state->regex_group_depth--;
|
|
2711
|
-
*symbol = REGEX_UNCLOSED_GROUP;
|
|
2712
|
-
return true;
|
|
2713
|
-
}
|
|
2714
|
-
return scan_active_mode_delimiter(lexer, state, valid_symbols, symbol);
|
|
2715
|
-
}
|
|
2652
|
+
return false;
|
|
2653
|
+
}
|
|
2716
2654
|
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
case MODE_SUBSTITUTE_REPLACEMENT:
|
|
2722
|
-
return scan_replacement_token(lexer, state, valid_symbols, symbol);
|
|
2723
|
-
case MODE_TRANSLATE_SOURCE:
|
|
2724
|
-
case MODE_TRANSLATE_DESTINATION:
|
|
2725
|
-
return scan_translate_token(lexer, state, valid_symbols, symbol);
|
|
2726
|
-
case MODE_TEXT:
|
|
2727
|
-
return false;
|
|
2728
|
-
case MODE_NONE:
|
|
2729
|
-
break;
|
|
2730
|
-
}
|
|
2655
|
+
static TSSymbol missing_text_introducer_symbol(const TSLexer *lexer) {
|
|
2656
|
+
return lexer->eof(lexer) ? MISSING_TEXT_INTRODUCER_MARKER
|
|
2657
|
+
: NONCONFORMING_MISSING_TEXT_INTRODUCER_MARKER;
|
|
2658
|
+
}
|
|
2731
2659
|
|
|
2660
|
+
static bool scan_command_token(
|
|
2661
|
+
TSLexer *lexer,
|
|
2662
|
+
ScannerState *state,
|
|
2663
|
+
const bool *valid_symbols,
|
|
2664
|
+
TSSymbol *symbol
|
|
2665
|
+
) {
|
|
2732
2666
|
if (valid_symbols[LINE_WORD] && scan_to_physical_line_end(lexer, false)) {
|
|
2733
2667
|
*symbol = LINE_WORD;
|
|
2734
2668
|
return true;
|
|
2735
2669
|
}
|
|
2736
2670
|
|
|
2671
|
+
if (valid_symbols[FLAG_AFTER_WRITE_MARKER]) {
|
|
2672
|
+
const enum FlagAfterWriteScan scan = scan_flag_after_write_marker(lexer);
|
|
2673
|
+
if (scan == FLAG_AFTER_WRITE_MATCH) {
|
|
2674
|
+
*symbol = FLAG_AFTER_WRITE_MARKER;
|
|
2675
|
+
return true;
|
|
2676
|
+
}
|
|
2677
|
+
if (
|
|
2678
|
+
scan ==
|
|
2679
|
+
FLAG_AFTER_WRITE_FALLBACK &&
|
|
2680
|
+
valid_symbols[OMITTED_FILE_SEPARATOR_MARKER]
|
|
2681
|
+
) {
|
|
2682
|
+
*symbol = OMITTED_FILE_SEPARATOR_MARKER;
|
|
2683
|
+
return true;
|
|
2684
|
+
}
|
|
2685
|
+
if (scan == FLAG_AFTER_WRITE_FALLBACK) {
|
|
2686
|
+
return false;
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
|
|
2737
2690
|
if (
|
|
2738
2691
|
valid_symbols[SUBSTITUTION_WFILE_ARGUMENT] &&
|
|
2739
2692
|
scan_substitution_wfile_argument(lexer)
|
|
@@ -2750,15 +2703,7 @@ static bool sed_scanner_scan_impl(
|
|
|
2750
2703
|
if (
|
|
2751
2704
|
valid_symbols[INVALID_SUBSTITUTION_FLAG] &&
|
|
2752
2705
|
!is_blank(lexer->lookahead) &&
|
|
2753
|
-
!
|
|
2754
|
-
lexer->lookahead !=
|
|
2755
|
-
'g' &&
|
|
2756
|
-
lexer->lookahead !=
|
|
2757
|
-
'i' &&
|
|
2758
|
-
lexer->lookahead !=
|
|
2759
|
-
'p' &&
|
|
2760
|
-
lexer->lookahead !=
|
|
2761
|
-
'w' &&
|
|
2706
|
+
!is_substitution_flag_character(lexer->lookahead) &&
|
|
2762
2707
|
lexer->lookahead !=
|
|
2763
2708
|
';' &&
|
|
2764
2709
|
lexer->lookahead !=
|
|
@@ -2777,10 +2722,11 @@ static bool sed_scanner_scan_impl(
|
|
|
2777
2722
|
*symbol = TEXT_COMMAND_START;
|
|
2778
2723
|
return true;
|
|
2779
2724
|
}
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2725
|
+
return emit_symbol(
|
|
2726
|
+
valid_symbols,
|
|
2727
|
+
missing_text_introducer_symbol(lexer),
|
|
2728
|
+
symbol
|
|
2729
|
+
);
|
|
2784
2730
|
}
|
|
2785
2731
|
|
|
2786
2732
|
if (valid_symbols[DEFAULT_OUTPUT_SUPPRESSION] && lexer->lookahead == 'n') {
|
|
@@ -2794,11 +2740,23 @@ static bool sed_scanner_scan_impl(
|
|
|
2794
2740
|
return true;
|
|
2795
2741
|
}
|
|
2796
2742
|
|
|
2743
|
+
// Preserve an address interpretation before reserved-function recovery.
|
|
2797
2744
|
if (
|
|
2798
|
-
valid_symbols[
|
|
2745
|
+
valid_symbols[MISSING_ADDRESS_SEPARATOR_MARKER] && can_start_address(lexer)
|
|
2746
|
+
) {
|
|
2747
|
+
return emit_missing_marker(
|
|
2748
|
+
lexer,
|
|
2749
|
+
valid_symbols,
|
|
2750
|
+
MISSING_ADDRESS_SEPARATOR_MARKER,
|
|
2751
|
+
symbol
|
|
2752
|
+
);
|
|
2753
|
+
}
|
|
2754
|
+
|
|
2755
|
+
if (
|
|
2756
|
+
valid_symbols[RESERVED_UNKNOWN_FUNCTION_TOKEN] &&
|
|
2799
2757
|
scan_reserved_unknown_function(lexer)
|
|
2800
2758
|
) {
|
|
2801
|
-
*symbol =
|
|
2759
|
+
*symbol = RESERVED_UNKNOWN_FUNCTION_TOKEN;
|
|
2802
2760
|
return true;
|
|
2803
2761
|
}
|
|
2804
2762
|
|
|
@@ -2839,6 +2797,9 @@ static bool sed_scanner_scan_impl(
|
|
|
2839
2797
|
}
|
|
2840
2798
|
|
|
2841
2799
|
if (
|
|
2800
|
+
valid_symbols[OMITTED_FIRST_ADDRESS_MARKER] &&
|
|
2801
|
+
lexer->lookahead ==
|
|
2802
|
+
',' &&
|
|
2842
2803
|
emit_missing_marker(
|
|
2843
2804
|
lexer,
|
|
2844
2805
|
valid_symbols,
|
|
@@ -2850,54 +2811,20 @@ static bool sed_scanner_scan_impl(
|
|
|
2850
2811
|
}
|
|
2851
2812
|
|
|
2852
2813
|
if (
|
|
2853
|
-
valid_symbols[OMITTED_ADDRESS_MARKER]
|
|
2814
|
+
(valid_symbols[OMITTED_ADDRESS_MARKER] ||
|
|
2815
|
+
valid_symbols[INCOMPLETE_OMITTED_ADDRESS_MARKER]) &&
|
|
2854
2816
|
!can_start_address(lexer) &&
|
|
2855
2817
|
!is_blank(lexer->lookahead)
|
|
2856
2818
|
) {
|
|
2857
2819
|
return emit_missing_marker(
|
|
2858
2820
|
lexer,
|
|
2859
2821
|
valid_symbols,
|
|
2860
|
-
|
|
2822
|
+
lexer->eof(lexer) ? INCOMPLETE_OMITTED_ADDRESS_MARKER
|
|
2823
|
+
: OMITTED_ADDRESS_MARKER,
|
|
2861
2824
|
symbol
|
|
2862
2825
|
);
|
|
2863
2826
|
}
|
|
2864
2827
|
|
|
2865
|
-
if (
|
|
2866
|
-
valid_symbols[ADDITIONAL_ADDRESS_MARKER] &&
|
|
2867
|
-
(lexer->lookahead == ',' || can_start_address(lexer))
|
|
2868
|
-
) {
|
|
2869
|
-
return emit_missing_marker(
|
|
2870
|
-
lexer,
|
|
2871
|
-
valid_symbols,
|
|
2872
|
-
ADDITIONAL_ADDRESS_MARKER,
|
|
2873
|
-
symbol
|
|
2874
|
-
);
|
|
2875
|
-
}
|
|
2876
|
-
|
|
2877
|
-
if (
|
|
2878
|
-
valid_symbols[MISSING_ADDRESS_SEPARATOR_MARKER] && can_start_address(lexer)
|
|
2879
|
-
) {
|
|
2880
|
-
return emit_missing_marker(
|
|
2881
|
-
lexer,
|
|
2882
|
-
valid_symbols,
|
|
2883
|
-
MISSING_ADDRESS_SEPARATOR_MARKER,
|
|
2884
|
-
symbol
|
|
2885
|
-
);
|
|
2886
|
-
}
|
|
2887
|
-
|
|
2888
|
-
if (
|
|
2889
|
-
valid_symbols[BLANKS_AROUND_ADDRESS_SEPARATOR_MARKER] &&
|
|
2890
|
-
lexer->lookahead == ','
|
|
2891
|
-
) {
|
|
2892
|
-
lexer->mark_end(lexer);
|
|
2893
|
-
advance(lexer);
|
|
2894
|
-
if (is_blank(lexer->lookahead)) {
|
|
2895
|
-
*symbol = BLANKS_AROUND_ADDRESS_SEPARATOR_MARKER;
|
|
2896
|
-
return true;
|
|
2897
|
-
}
|
|
2898
|
-
return false;
|
|
2899
|
-
}
|
|
2900
|
-
|
|
2901
2828
|
if (is_blank(lexer->lookahead)) {
|
|
2902
2829
|
switch (scan_post_blank_recovery(lexer, valid_symbols, symbol)) {
|
|
2903
2830
|
case POST_BLANK_RECOVERY_TOKEN:
|
|
@@ -2909,18 +2836,6 @@ static bool sed_scanner_scan_impl(
|
|
|
2909
2836
|
}
|
|
2910
2837
|
}
|
|
2911
2838
|
|
|
2912
|
-
if (
|
|
2913
|
-
emit_missing_marker(lexer, valid_symbols, DUPLICATE_NEGATION_MARKER, symbol)
|
|
2914
|
-
) {
|
|
2915
|
-
return true;
|
|
2916
|
-
}
|
|
2917
|
-
|
|
2918
|
-
if (
|
|
2919
|
-
emit_missing_marker(lexer, valid_symbols, EXCESS_ADDRESSES_MARKER, symbol)
|
|
2920
|
-
) {
|
|
2921
|
-
return true;
|
|
2922
|
-
}
|
|
2923
|
-
|
|
2924
2839
|
if (
|
|
2925
2840
|
!at_command_boundary(lexer) &&
|
|
2926
2841
|
!is_blank(lexer->lookahead) &&
|
|
@@ -2951,11 +2866,13 @@ static bool sed_scanner_scan_impl(
|
|
|
2951
2866
|
}
|
|
2952
2867
|
}
|
|
2953
2868
|
|
|
2954
|
-
const TSSymbol missing_text_introducer = lexer->eof(lexer)
|
|
2955
|
-
? MISSING_TEXT_INTRODUCER_MARKER
|
|
2956
|
-
: NONCONFORMING_MISSING_TEXT_INTRODUCER_MARKER;
|
|
2957
2869
|
if (
|
|
2958
|
-
emit_missing_marker(
|
|
2870
|
+
emit_missing_marker(
|
|
2871
|
+
lexer,
|
|
2872
|
+
valid_symbols,
|
|
2873
|
+
missing_text_introducer_symbol(lexer),
|
|
2874
|
+
symbol
|
|
2875
|
+
)
|
|
2959
2876
|
) {
|
|
2960
2877
|
return true;
|
|
2961
2878
|
}
|
|
@@ -3029,6 +2946,60 @@ static bool sed_scanner_scan_impl(
|
|
|
3029
2946
|
return false;
|
|
3030
2947
|
}
|
|
3031
2948
|
|
|
2949
|
+
static bool sed_scanner_scan_impl(
|
|
2950
|
+
ScannerState *state,
|
|
2951
|
+
TSLexer *lexer,
|
|
2952
|
+
const bool *valid_symbols,
|
|
2953
|
+
TSSymbol *symbol
|
|
2954
|
+
) {
|
|
2955
|
+
if (valid_symbols[ERROR_SENTINEL]) {
|
|
2956
|
+
return false;
|
|
2957
|
+
}
|
|
2958
|
+
|
|
2959
|
+
if (state->mode == MODE_TEXT) {
|
|
2960
|
+
return scan_text_token(lexer, state, valid_symbols, symbol);
|
|
2961
|
+
}
|
|
2962
|
+
|
|
2963
|
+
if (
|
|
2964
|
+
is_regex_mode(state->mode) &&
|
|
2965
|
+
scan_regex_recovery_marker(lexer, state, valid_symbols, symbol)
|
|
2966
|
+
) {
|
|
2967
|
+
return true;
|
|
2968
|
+
}
|
|
2969
|
+
|
|
2970
|
+
const bool delimiter_is_active = state->mode !=
|
|
2971
|
+
MODE_NONE &&
|
|
2972
|
+
lexer->lookahead ==
|
|
2973
|
+
state->delimiter &&
|
|
2974
|
+
(!is_regex_mode(state->mode) ||
|
|
2975
|
+
state->regex_state == REGEX_OUTSIDE_BRACKET);
|
|
2976
|
+
if (delimiter_is_active) {
|
|
2977
|
+
if (state->regex_group_depth > 0 && valid_symbols[REGEX_UNCLOSED_GROUP]) {
|
|
2978
|
+
state->regex_group_depth--;
|
|
2979
|
+
*symbol = REGEX_UNCLOSED_GROUP;
|
|
2980
|
+
return true;
|
|
2981
|
+
}
|
|
2982
|
+
return scan_active_mode_delimiter(lexer, state, valid_symbols, symbol);
|
|
2983
|
+
}
|
|
2984
|
+
|
|
2985
|
+
switch (state->mode) {
|
|
2986
|
+
case MODE_REGEX_ADDRESS:
|
|
2987
|
+
case MODE_SUBSTITUTE_PATTERN:
|
|
2988
|
+
return scan_regex_token(lexer, state, valid_symbols, symbol);
|
|
2989
|
+
case MODE_SUBSTITUTE_REPLACEMENT:
|
|
2990
|
+
return scan_replacement_token(lexer, state, valid_symbols, symbol);
|
|
2991
|
+
case MODE_TRANSLATE_SOURCE:
|
|
2992
|
+
case MODE_TRANSLATE_DESTINATION:
|
|
2993
|
+
return scan_translate_token(lexer, state, valid_symbols, symbol);
|
|
2994
|
+
case MODE_TEXT:
|
|
2995
|
+
return false;
|
|
2996
|
+
case MODE_NONE:
|
|
2997
|
+
break;
|
|
2998
|
+
}
|
|
2999
|
+
|
|
3000
|
+
return scan_command_token(lexer, state, valid_symbols, symbol);
|
|
3001
|
+
}
|
|
3002
|
+
|
|
3032
3003
|
static void
|
|
3033
3004
|
update_regex_position_after_symbol(ScannerState *state, TSSymbol symbol) {
|
|
3034
3005
|
#if !SED_REGEX_EXTENDED
|
|
@@ -3037,9 +3008,7 @@ update_regex_position_after_symbol(ScannerState *state, TSSymbol symbol) {
|
|
|
3037
3008
|
BRE_VERTICAL_LINE_ESCAPE_MARKER ||
|
|
3038
3009
|
symbol ==
|
|
3039
3010
|
BRE_QUESTION_MARK_ESCAPE_MARKER ||
|
|
3040
|
-
symbol ==
|
|
3041
|
-
BRE_PLUS_ESCAPE_MARKER ||
|
|
3042
|
-
symbol == UNMATCHED_INTERVAL_CLOSE_MARKER
|
|
3011
|
+
symbol == BRE_PLUS_ESCAPE_MARKER
|
|
3043
3012
|
) {
|
|
3044
3013
|
return;
|
|
3045
3014
|
}
|
|
@@ -3081,7 +3050,15 @@ update_regex_position_after_symbol(ScannerState *state, TSSymbol symbol) {
|
|
|
3081
3050
|
}
|
|
3082
3051
|
#endif
|
|
3083
3052
|
|
|
3084
|
-
|
|
3053
|
+
bool is_anchor =
|
|
3054
|
+
symbol == REGEX_BEGINNING_ANCHOR || symbol == REGEX_END_ANCHOR;
|
|
3055
|
+
#if !SED_REGEX_EXTENDED
|
|
3056
|
+
is_anchor = is_anchor ||
|
|
3057
|
+
symbol ==
|
|
3058
|
+
REGEX_BRE_SUBEXPRESSION_CARET ||
|
|
3059
|
+
symbol == REGEX_BRE_SUBEXPRESSION_DOLLAR;
|
|
3060
|
+
#endif
|
|
3061
|
+
if (is_anchor) {
|
|
3085
3062
|
set_regex_position(state, true, REGEX_DUPLICATION_NONE, false, true);
|
|
3086
3063
|
return;
|
|
3087
3064
|
}
|