tree-sitter-sed 0.3.0 → 0.5.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 ADDED
@@ -0,0 +1,121 @@
1
+ cmake_minimum_required(VERSION 3.13)
2
+
3
+ project(
4
+ tree-sitter-sed
5
+ VERSION 0.5.0
6
+ DESCRIPTION "Tree-sitter grammars for POSIX sed."
7
+ HOMEPAGE_URL "https://github.com/konomanoasa/tree-sitter-sed"
8
+ LANGUAGES C
9
+ )
10
+
11
+ option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
12
+ option(TREE_SITTER_REUSE_ALLOCATOR "Reuse the Tree-sitter allocator" OFF)
13
+
14
+ file(
15
+ STRINGS src/parser.c
16
+ TREE_SITTER_ABI_DEFINITION
17
+ REGEX "^#define LANGUAGE_VERSION [0-9]+$"
18
+ )
19
+ file(
20
+ STRINGS sed_ere/src/parser.c
21
+ TREE_SITTER_ERE_ABI_DEFINITION
22
+ REGEX "^#define LANGUAGE_VERSION [0-9]+$"
23
+ )
24
+ if(
25
+ NOT TREE_SITTER_ABI_DEFINITION MATCHES "^#define LANGUAGE_VERSION [0-9]+$"
26
+ OR NOT TREE_SITTER_ERE_ABI_DEFINITION MATCHES
27
+ "^#define LANGUAGE_VERSION [0-9]+$"
28
+ )
29
+ message(FATAL_ERROR "Both parsers must define one LANGUAGE_VERSION")
30
+ endif()
31
+ if(NOT TREE_SITTER_ABI_DEFINITION STREQUAL TREE_SITTER_ERE_ABI_DEFINITION)
32
+ message(FATAL_ERROR "The sed and sed_ere parsers must use the same ABI")
33
+ endif()
34
+ string(
35
+ REGEX REPLACE "^#define LANGUAGE_VERSION " ""
36
+ TREE_SITTER_ABI_VERSION
37
+ "${TREE_SITTER_ABI_DEFINITION}"
38
+ )
39
+
40
+ include(GNUInstallDirs)
41
+ if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
42
+ include(CTest)
43
+ endif()
44
+
45
+ add_library(
46
+ tree-sitter-sed
47
+ src/parser.c
48
+ src/scanner.c
49
+ sed_ere/src/parser.c
50
+ sed_ere/src/scanner.c
51
+ )
52
+ set_source_files_properties(
53
+ src/scanner.c
54
+ PROPERTIES INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/src"
55
+ )
56
+ set_source_files_properties(
57
+ sed_ere/src/scanner.c
58
+ PROPERTIES INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/sed_ere/src"
59
+ )
60
+ target_include_directories(
61
+ tree-sitter-sed
62
+ INTERFACE
63
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/bindings/c>
64
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
65
+ )
66
+ target_compile_definitions(
67
+ tree-sitter-sed
68
+ PRIVATE
69
+ $<$<BOOL:${TREE_SITTER_REUSE_ALLOCATOR}>:TREE_SITTER_REUSE_ALLOCATOR>
70
+ $<$<CONFIG:Debug>:TREE_SITTER_DEBUG>
71
+ )
72
+ set_target_properties(
73
+ tree-sitter-sed
74
+ PROPERTIES
75
+ C_STANDARD 11
76
+ C_STANDARD_REQUIRED ON
77
+ DEFINE_SYMBOL ""
78
+ POSITION_INDEPENDENT_CODE ON
79
+ SOVERSION "${TREE_SITTER_ABI_VERSION}.${PROJECT_VERSION_MAJOR}"
80
+ )
81
+
82
+ if(BUILD_TESTING AND CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
83
+ add_executable(tree-sitter-sed-binding-test test/binding.test.c)
84
+ target_link_libraries(tree-sitter-sed-binding-test PRIVATE tree-sitter-sed)
85
+ add_test(
86
+ NAME tree-sitter-sed-binding
87
+ COMMAND tree-sitter-sed-binding-test
88
+ )
89
+ endif()
90
+
91
+ configure_file(
92
+ bindings/c/tree-sitter-sed.pc.in
93
+ "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-sed.pc"
94
+ @ONLY
95
+ )
96
+
97
+ install(
98
+ TARGETS tree-sitter-sed
99
+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
100
+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
101
+ RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
102
+ )
103
+ install(
104
+ DIRECTORY bindings/c/tree_sitter
105
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
106
+ FILES_MATCHING PATTERN "*.h"
107
+ )
108
+ install(
109
+ FILES "${CMAKE_CURRENT_BINARY_DIR}/tree-sitter-sed.pc"
110
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
111
+ )
112
+ install(
113
+ DIRECTORY queries/
114
+ DESTINATION "${CMAKE_INSTALL_DATADIR}/tree-sitter/queries/sed"
115
+ FILES_MATCHING PATTERN "*.scm"
116
+ )
117
+ install(
118
+ DIRECTORY sed_ere/queries/
119
+ DESTINATION "${CMAKE_INSTALL_DATADIR}/tree-sitter/queries/sed_ere"
120
+ FILES_MATCHING PATTERN "*.scm"
121
+ )
package/Makefile ADDED
@@ -0,0 +1,145 @@
1
+ LANGUAGE_NAME := tree-sitter-sed
2
+ HOMEPAGE_URL := https://github.com/konomanoasa/tree-sitter-sed
3
+ VERSION := 0.5.0
4
+ DESCRIPTION := Tree-sitter grammars for POSIX sed.
5
+
6
+ PREFIX ?= /usr/local
7
+ DATADIR ?= $(PREFIX)/share
8
+ INCLUDEDIR ?= $(PREFIX)/include
9
+ LIBDIR ?= $(PREFIX)/lib
10
+ BINDIR ?= $(PREFIX)/bin
11
+ PCLIBDIR ?= $(LIBDIR)/pkgconfig
12
+
13
+ SOURCES := src/parser.c src/scanner.c \
14
+ sed_ere/src/parser.c sed_ere/src/scanner.c
15
+ OBJECTS := $(SOURCES:.c=.o)
16
+ MAKE_BUILD_DIR := build/make
17
+ STATIC_LIBRARY := lib$(LANGUAGE_NAME).a
18
+ PKG_CONFIG := $(LANGUAGE_NAME).pc
19
+ TEST := $(MAKE_BUILD_DIR)/binding.test
20
+
21
+ ARFLAGS := rcs
22
+ override CFLAGS += -std=c11 -fPIC
23
+
24
+ SONAME_MAJOR := $(shell sed -n 's/\#define LANGUAGE_VERSION //p' src/parser.c)
25
+ SED_ERE_SONAME_MAJOR := $(shell sed -n 's/\#define LANGUAGE_VERSION //p' sed_ere/src/parser.c)
26
+ SONAME_MINOR := $(word 1,$(subst ., ,$(VERSION)))
27
+
28
+ ifeq ($(SONAME_MAJOR),)
29
+ $(error Both parsers must define LANGUAGE_VERSION)
30
+ endif
31
+ ifneq ($(SONAME_MAJOR),$(SED_ERE_SONAME_MAJOR))
32
+ $(error The sed and sed_ere parsers must use the same ABI)
33
+ endif
34
+
35
+ MACHINE := $(shell $(CC) -dumpmachine)
36
+
37
+ ifneq ($(findstring darwin,$(MACHINE)),)
38
+ SOEXT := dylib
39
+ SOEXTVER_MAJOR := $(SONAME_MAJOR).$(SOEXT)
40
+ SOEXTVER := $(SONAME_MAJOR).$(SONAME_MINOR).$(SOEXT)
41
+ LINKSHARED := -dynamiclib -Wl,-install_name,$(LIBDIR)/lib$(LANGUAGE_NAME).$(SOEXTVER)
42
+ else ifneq ($(findstring mingw32,$(MACHINE)),)
43
+ SOEXT := dll
44
+ LINKSHARED := -s -shared -Wl,--out-implib,lib$(LANGUAGE_NAME).dll.a
45
+ TEST := $(MAKE_BUILD_DIR)/binding.test.exe
46
+ else
47
+ SOEXT := so
48
+ SOEXTVER_MAJOR := $(SOEXT).$(SONAME_MAJOR)
49
+ SOEXTVER := $(SOEXT).$(SONAME_MAJOR).$(SONAME_MINOR)
50
+ LINKSHARED := -shared -Wl,-soname,lib$(LANGUAGE_NAME).$(SOEXTVER)
51
+ ifneq ($(filter $(shell uname),FreeBSD NetBSD DragonFly),)
52
+ PCLIBDIR := $(PREFIX)/libdata/pkgconfig
53
+ endif
54
+ endif
55
+
56
+ SHARED_LIBRARY := lib$(LANGUAGE_NAME).$(SOEXT)
57
+
58
+ all: $(STATIC_LIBRARY) $(SHARED_LIBRARY) $(PKG_CONFIG)
59
+
60
+ $(STATIC_LIBRARY): $(OBJECTS)
61
+ $(AR) $(ARFLAGS) $@ $^
62
+
63
+ $(SHARED_LIBRARY): $(OBJECTS)
64
+ $(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@
65
+ ifneq ($(STRIP),)
66
+ $(STRIP) $@
67
+ endif
68
+
69
+ $(PKG_CONFIG): bindings/c/$(LANGUAGE_NAME).pc.in FORCE
70
+ sed -e 's|@PROJECT_VERSION@|$(VERSION)|' \
71
+ -e 's|@CMAKE_INSTALL_LIBDIR@|$(LIBDIR:$(PREFIX)/%=%)|' \
72
+ -e 's|@CMAKE_INSTALL_INCLUDEDIR@|$(INCLUDEDIR:$(PREFIX)/%=%)|' \
73
+ -e 's|@PROJECT_DESCRIPTION@|$(DESCRIPTION)|' \
74
+ -e 's|@PROJECT_HOMEPAGE_URL@|$(HOMEPAGE_URL)|' \
75
+ -e 's|@CMAKE_INSTALL_PREFIX@|$(PREFIX)|' $< > $@
76
+
77
+ src/parser.o: src/tree_sitter/parser.h
78
+ src/scanner.o: common/scanner.h src/tree_sitter/alloc.h src/tree_sitter/parser.h
79
+ src/scanner.o: CPPFLAGS += -Isrc
80
+ sed_ere/src/parser.o: sed_ere/src/tree_sitter/parser.h
81
+ sed_ere/src/scanner.o: common/scanner.h sed_ere/src/tree_sitter/alloc.h \
82
+ sed_ere/src/tree_sitter/parser.h
83
+ sed_ere/src/scanner.o: CPPFLAGS += -Ised_ere/src
84
+
85
+ $(MAKE_BUILD_DIR):
86
+ mkdir -p $@
87
+
88
+ $(TEST): test/binding.test.c $(STATIC_LIBRARY) | $(MAKE_BUILD_DIR)
89
+ $(CC) $(CPPFLAGS) $(CFLAGS) -Ibindings/c $< $(STATIC_LIBRARY) $(LDFLAGS) $(LDLIBS) -o $@
90
+
91
+ test: $(TEST)
92
+ ./$(TEST)
93
+
94
+ install: all
95
+ install -d '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/sed \
96
+ '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/sed_ere \
97
+ '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter \
98
+ '$(DESTDIR)$(PCLIBDIR)' \
99
+ '$(DESTDIR)$(LIBDIR)'
100
+ install -m644 bindings/c/tree_sitter/$(LANGUAGE_NAME).h \
101
+ '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h
102
+ install -m644 $(PKG_CONFIG) '$(DESTDIR)$(PCLIBDIR)'/$(PKG_CONFIG)
103
+ install -m644 $(STATIC_LIBRARY) '$(DESTDIR)$(LIBDIR)'/$(STATIC_LIBRARY)
104
+ ifneq ($(findstring mingw32,$(MACHINE)),)
105
+ install -d '$(DESTDIR)$(BINDIR)'
106
+ install -m755 $(SHARED_LIBRARY) '$(DESTDIR)$(BINDIR)'/$(SHARED_LIBRARY)
107
+ install -m644 lib$(LANGUAGE_NAME).dll.a \
108
+ '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).dll.a
109
+ else
110
+ install -m755 $(SHARED_LIBRARY) \
111
+ '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER)
112
+ cd '$(DESTDIR)$(LIBDIR)' && \
113
+ ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER) \
114
+ lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR)
115
+ cd '$(DESTDIR)$(LIBDIR)' && \
116
+ ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) $(SHARED_LIBRARY)
117
+ endif
118
+ install -m644 queries/*.scm \
119
+ '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/sed
120
+ install -m644 sed_ere/queries/*.scm \
121
+ '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/sed_ere
122
+
123
+ uninstall:
124
+ $(RM) '$(DESTDIR)$(LIBDIR)'/$(STATIC_LIBRARY) \
125
+ '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h \
126
+ '$(DESTDIR)$(PCLIBDIR)'/$(PKG_CONFIG)
127
+ ifneq ($(findstring mingw32,$(MACHINE)),)
128
+ $(RM) '$(DESTDIR)$(BINDIR)'/$(SHARED_LIBRARY) \
129
+ '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).dll.a
130
+ else
131
+ $(RM) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) \
132
+ '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) \
133
+ '$(DESTDIR)$(LIBDIR)'/$(SHARED_LIBRARY)
134
+ endif
135
+ $(RM) -r '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/sed \
136
+ '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/sed_ere
137
+
138
+ clean:
139
+ $(RM) $(OBJECTS) $(STATIC_LIBRARY) $(SHARED_LIBRARY) \
140
+ lib$(LANGUAGE_NAME).dll.a $(PKG_CONFIG)
141
+ $(RM) -r $(MAKE_BUILD_DIR)
142
+
143
+ FORCE:
144
+
145
+ .PHONY: all clean FORCE install test uninstall
package/README.md CHANGED
@@ -14,7 +14,12 @@ npm install tree-sitter-sed
14
14
 
15
15
  ## Grammars
16
16
 
17
- This repository contains two grammars. You can find [`sed_ere`](sed_ere) here.
17
+ This repository contains the following two grammars.
18
+
19
+ | Grammar | Regexp | C function |
20
+ | --------- | ------ | ----------------------- |
21
+ | `sed` | BRE | `tree_sitter_sed()` |
22
+ | `sed_ere` | ERE | `tree_sitter_sed_ere()` |
18
23
 
19
24
  ## Specifications
20
25
 
@@ -0,0 +1,10 @@
1
+ prefix=@CMAKE_INSTALL_PREFIX@
2
+ libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
3
+ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
4
+
5
+ Name: tree-sitter-sed
6
+ Description: @PROJECT_DESCRIPTION@
7
+ URL: @PROJECT_HOMEPAGE_URL@
8
+ Version: @PROJECT_VERSION@
9
+ Libs: -L${libdir} -ltree-sitter-sed
10
+ Cflags: -I${includedir}
@@ -0,0 +1,17 @@
1
+ #ifndef TREE_SITTER_SED_H_
2
+ #define TREE_SITTER_SED_H_
3
+
4
+ typedef struct TSLanguage TSLanguage;
5
+
6
+ #ifdef __cplusplus
7
+ extern "C" {
8
+ #endif
9
+
10
+ const TSLanguage *tree_sitter_sed(void);
11
+ const TSLanguage *tree_sitter_sed_ere(void);
12
+
13
+ #ifdef __cplusplus
14
+ }
15
+ #endif
16
+
17
+ #endif
package/common/dsl.js CHANGED
@@ -2,6 +2,28 @@ function issueRuleName(id) {
2
2
  return `_${id}_issue`;
3
3
  }
4
4
 
5
+ function outcomeRuleName(id) {
6
+ return `_${id}_outcome`;
7
+ }
8
+
9
+ function reasonRuleName(id) {
10
+ return `_${id}_reason`;
11
+ }
12
+
13
+ function defineIssueRules(definitions) {
14
+ const rules = {};
15
+
16
+ for (const definition of definitions) {
17
+ const { outcome, reason, rule } = definition;
18
+ const id = definition.id ?? reason;
19
+ rules[reasonRuleName(id)] = rule;
20
+ rules[outcomeRuleName(id)] = ($) => alias($[reasonRuleName(id)], $[reason]);
21
+ rules[issueRuleName(id)] = ($) => alias($[outcomeRuleName(id)], $[outcome]);
22
+ }
23
+
24
+ return rules;
25
+ }
26
+
5
27
  function namedExternal($, external, name) {
6
28
  return alias(external, $[name]);
7
29
  }
@@ -14,4 +36,4 @@ function issueNode($, id) {
14
36
  return alias($[issueRuleName(id)], $.syntax_issue);
15
37
  }
16
38
 
17
- module.exports = { issueField, issueNode, issueRuleName, namedExternal };
39
+ module.exports = { defineIssueRules, issueField, issueNode, namedExternal };
package/common/grammar.js CHANGED
@@ -1,33 +1,11 @@
1
1
  const {
2
+ defineIssueRules,
2
3
  issueField,
3
4
  issueNode,
4
- issueRuleName,
5
5
  namedExternal,
6
6
  } = require("./dsl");
7
7
  const regularExpressionRules = require("./regex");
8
8
 
9
- function outcomeRuleName(id) {
10
- return `_${id}_outcome`;
11
- }
12
-
13
- function reasonRuleName(id) {
14
- return `_${id}_reason`;
15
- }
16
-
17
- function defineIssueRules(definitions) {
18
- const rules = {};
19
-
20
- for (const definition of definitions) {
21
- const { outcome, reason, rule } = definition;
22
- const id = definition.id ?? reason;
23
- rules[reasonRuleName(id)] = rule;
24
- rules[outcomeRuleName(id)] = ($) => alias($[reasonRuleName(id)], $[reason]);
25
- rules[issueRuleName(id)] = ($) => alias($[outcomeRuleName(id)], $[outcome]);
26
- }
27
-
28
- return rules;
29
- }
30
-
31
9
  function missingAtEndOrBoundary($, reason) {
32
10
  return choice(
33
11
  issueField($, reason),
@@ -573,29 +551,17 @@ function operandRules(mode) {
573
551
  }
574
552
 
575
553
  return {
576
- _substitute_function_without_write: ($) =>
554
+ _substitute_function: ($) =>
577
555
  choice(
578
556
  seq(
579
557
  $._complete_substitute_function,
580
558
  optional(
581
- field(
582
- "flags",
583
- alias($._substitution_flags_without_write, $.substitution_flags),
584
- ),
559
+ field("flags", alias($._substitution_flags, $.substitution_flags)),
585
560
  ),
586
561
  ),
587
562
  $._incomplete_substitute_function,
588
563
  ),
589
564
 
590
- _substitute_function_with_write: ($) =>
591
- seq(
592
- $._complete_substitute_function,
593
- field(
594
- "flags",
595
- alias($._substitution_flags_with_write, $.substitution_flags),
596
- ),
597
- ),
598
-
599
565
  _complete_substitute_function: ($) =>
600
566
  seq(
601
567
  functionVerb($, "s"),
@@ -681,6 +647,12 @@ function operandRules(mode) {
681
647
  escaped_newline: ($) =>
682
648
  namedExternal($, $._replacement_escaped_newline, "escaped_newline_token"),
683
649
 
650
+ _substitution_flags: ($) =>
651
+ choice(
652
+ $._substitution_flags_without_write,
653
+ seq(optional($._substitution_flags_without_write), $.write_flag),
654
+ ),
655
+
684
656
  _substitution_flags_without_write: ($) =>
685
657
  choice(
686
658
  substitutionFlagChoice($),
@@ -689,9 +661,6 @@ function operandRules(mode) {
689
661
  ),
690
662
  ),
691
663
 
692
- _substitution_flags_with_write: ($) =>
693
- seq(optional($._substitution_flags_without_write), $.write_flag),
694
-
695
664
  occurrence_flag: () => /[[:digit:]]+/,
696
665
 
697
666
  global_flag: () => "g",
@@ -706,8 +675,7 @@ function operandRules(mode) {
706
675
  choice(
707
676
  seq(
708
677
  $._flag_after_write_marker,
709
- issueField($, "flag_after_write_flag"),
710
- repeat(postWriteSubstitutionFlagChoice($)),
678
+ repeat1(postWriteSubstitutionFlagChoice($)),
711
679
  $._blanks,
712
680
  choice(
713
681
  field("wfile", alias($._substitution_wfile, $.wfile)),
@@ -977,39 +945,19 @@ function editingCommandRules() {
977
945
 
978
946
  _line_terminated_editing_command: ($) =>
979
947
  seq(
980
- choice(
981
- $._line_terminated_regular_editing_command_body,
982
- $._line_terminated_substitute_editing_command_body,
983
- ),
948
+ addressedForms($, lineTerminated, "line_terminated"),
984
949
  optional(issueField($, "unexpected_command_text")),
985
950
  ),
986
951
 
987
952
  _recovered_line_terminated_editing_command: ($) =>
988
- choice(
989
- prec.right(
990
- seq(
991
- $._line_terminated_regular_editing_command_body,
992
- optional(issueField($, "unexpected_command_text")),
993
- issueField($, "forbidden_command_separator"),
994
- optional($._blanks),
995
- ),
996
- ),
997
- prec.right(
998
- seq(
999
- $._line_terminated_substitute_editing_command_body,
1000
- optional(issueField($, "unexpected_command_text")),
1001
- issueField($, "command_after_write_flag"),
1002
- optional($._blanks),
1003
- ),
953
+ prec.right(
954
+ seq(
955
+ $._line_terminated_editing_command,
956
+ issueField($, "forbidden_command_separator"),
957
+ optional($._blanks),
1004
958
  ),
1005
959
  ),
1006
960
 
1007
- _line_terminated_regular_editing_command_body: ($) =>
1008
- addressedForms($, lineTerminated, "line_terminated"),
1009
-
1010
- _line_terminated_substitute_editing_command_body: ($) =>
1011
- addressedFunction($, $._line_terminated_substitute_function),
1012
-
1013
961
  _recovered_editing_command: ($) =>
1014
962
  choice(
1015
963
  addressedFunction($, $._unknown_function),
@@ -1056,10 +1004,7 @@ function editingCommandRules() {
1056
1004
  _missing_function: ($) => missingAtEndOrBoundary($, "missing_function"),
1057
1005
 
1058
1006
  _chainable_substitute_function: ($) =>
1059
- alias($._substitute_function_without_write, $.substitute_function),
1060
-
1061
- _line_terminated_substitute_function: ($) =>
1062
- alias($._substitute_function_with_write, $.substitute_function),
1007
+ alias($._substitute_function, $.substitute_function),
1063
1008
 
1064
1009
  negation: ($) =>
1065
1010
  seq(
@@ -1272,16 +1217,6 @@ function issueDefinitions(mode) {
1272
1217
  outcome: "undefined_syntax",
1273
1218
  rule: ($) => $._translate_nonportable_escape,
1274
1219
  },
1275
- {
1276
- reason: "command_after_write_flag",
1277
- outcome: "undefined_syntax",
1278
- rule: () => token.immediate(";"),
1279
- },
1280
- {
1281
- reason: "flag_after_write_flag",
1282
- outcome: "undefined_syntax",
1283
- rule: ($) => postWriteSubstitutionFlagChoice($),
1284
- },
1285
1220
  {
1286
1221
  reason: "equivalence_class_range_start",
1287
1222
  outcome: "unspecified_syntax",
package/common/regex.js CHANGED
@@ -340,6 +340,14 @@ function breDuplicationSymbol($) {
340
340
  );
341
341
  }
342
342
 
343
+ function misplacedBreDuplSymbol($, reason) {
344
+ return choice(
345
+ seq(issueField($, reason), field("operator", $.bre_dupl_symbol)),
346
+ issueField($, "malformed_interval"),
347
+ issueField($, "incomplete_interval"),
348
+ );
349
+ }
350
+
343
351
  function breRules() {
344
352
  return {
345
353
  bre_extension_escape: ($) =>
@@ -483,24 +491,10 @@ function breRules() {
483
491
  intervalExpression($, "back_open_brace", "back_close_brace"),
484
492
 
485
493
  leading_bre_dupl_symbol: ($) =>
486
- choice(
487
- seq(
488
- issueField($, "leading_duplication_symbol"),
489
- field("operator", $.bre_dupl_symbol),
490
- ),
491
- issueField($, "malformed_interval"),
492
- issueField($, "incomplete_interval"),
493
- ),
494
+ misplacedBreDuplSymbol($, "leading_duplication_symbol"),
494
495
 
495
496
  adjacent_bre_dupl_symbol: ($) =>
496
- choice(
497
- seq(
498
- issueField($, "adjacent_duplication_symbol"),
499
- field("operator", $.bre_dupl_symbol),
500
- ),
501
- issueField($, "malformed_interval"),
502
- issueField($, "incomplete_interval"),
503
- ),
497
+ misplacedBreDuplSymbol($, "adjacent_duplication_symbol"),
504
498
  };
505
499
  }
506
500