grammar-composer 0.3.0 → 0.3.1
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/LICENSE.md +1 -1
- package/README.md +3 -2
- package/dist/tests/test-grammars/RegExpGrammar.d.ts +2 -1
- package/dist/tests/test-grammars/RegExpGrammar.d.ts.map +1 -1
- package/dist/tests/test-grammars/RegExpGrammar.js +25 -18
- package/dist/tests/test-grammars/RegExpGrammar.js.map +1 -1
- package/package.json +1 -1
- package/src/tests/test-grammars/RegExpGrammar.ts +33 -19
package/LICENSE.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright (c)
|
|
1
|
+
Copyright (c) 2026 Rotem Dan
|
|
2
2
|
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
4
|
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ A library to define, build and efficiently parse context-free grammars.
|
|
|
4
4
|
|
|
5
5
|
* Grammars are defined using TypeScript class declarations
|
|
6
6
|
* No tokenization stage. The generated parser accepts raw characters as input, meaning it's a form of lexer-free, or hybrid parser, supporting contextual tokenization - that is, low-level character patterns can be specialized to different high-level parser contexts, and sub-patterns captured in the low-level regular expressions are directly embedded as part of the resulting parse tree
|
|
7
|
-
* Raw character parsing is defined as part of the grammar via embedded `Pattern` objects that are internally processed through the [`regexp-composer`](https://github.com/rotemdan/regexp-composer) regular expression library
|
|
7
|
+
* Raw character parsing is defined as part of the grammar via embedded `Pattern` objects that are internally processed through the [`regexp-composer`](https://github.com/rotemdan/regexp-composer) regular expression library. This means that any subset of the grammar that can be stated as a regular expression can be moved to be parsed using the highly optimized native JavaScript RegExp engine, instead of being parsed via the slower context-free parser
|
|
8
8
|
* Top-down parsing (roughly equivalent to PEG parsing), with optional "packrat" caching that can be enabled or disabled for individual productions
|
|
9
9
|
* Supports right-recursion, but will currently error when left-recursion is detected
|
|
10
10
|
* Uses sophisticated static analysis to automatically identify and annotate optional productions
|
|
@@ -29,6 +29,7 @@ The grammar is defined within a container class `XmlGrammar`. It contains a mixt
|
|
|
29
29
|
* Regular expression productions are defined by `pattern(...)`
|
|
30
30
|
|
|
31
31
|
In this example, context-free operators are prefixed with `G`, and regular expression operators are prefixed with `R`, to avoid confusion between similarly named operators:
|
|
32
|
+
|
|
32
33
|
```ts
|
|
33
34
|
import * as G from 'grammar-composer'
|
|
34
35
|
import * as R from 'regexp-composer'
|
|
@@ -173,7 +174,7 @@ const quotedString = R.anyOf(
|
|
|
173
174
|
)
|
|
174
175
|
```
|
|
175
176
|
|
|
176
|
-
Building and parsing using the XML grammar
|
|
177
|
+
### Building and parsing using the XML grammar
|
|
177
178
|
|
|
178
179
|
```ts
|
|
179
180
|
import { buildGrammar } from 'grammar-composer'
|
|
@@ -24,7 +24,8 @@ export declare class RegExpGrammar {
|
|
|
24
24
|
escapedCharLiteral: () => G.PatternTerminal;
|
|
25
25
|
hexCharcode: () => G.PatternTerminal;
|
|
26
26
|
controlCharcode: () => G.PatternTerminal;
|
|
27
|
-
|
|
27
|
+
nullCharcode: () => G.PatternTerminal;
|
|
28
|
+
codepoint: () => G.Choice;
|
|
28
29
|
codepointRange: () => G.PatternTerminal;
|
|
29
30
|
unicodeProperty: () => G.PatternTerminal;
|
|
30
31
|
notUnicodeProperty: () => G.PatternTerminal;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RegExpGrammar.d.ts","sourceRoot":"","sources":["../../../src/tests/test-grammars/RegExpGrammar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,0BAA0B,CAAA;AAC7C,OAAO,KAAK,CAAC,MAAM,iBAAiB,CAAA;AAEpC,qBAAa,aAAa;IAIzB,WAAW,uBAOV;IAED,QAAQ,
|
|
1
|
+
{"version":3,"file":"RegExpGrammar.d.ts","sourceRoot":"","sources":["../../../src/tests/test-grammars/RegExpGrammar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,0BAA0B,CAAA;AAC7C,OAAO,KAAK,CAAC,MAAM,iBAAiB,CAAA;AAEpC,qBAAa,aAAa;IAIzB,WAAW,uBAOV;IAED,QAAQ,qBAAmC;IAE3C,OAAO,iBAIN;IAKD,4BAA4B,uBAe3B;IAED,oBAAoB,0BAIlB;IAEF,oBAAoB,0BAMlB;IAKF,KAAK,iBAIJ;IAED,eAAe,4CAId;IAED,iBAAiB,gEAMhB;IAED,mBAAmB,4CAIlB;IAKD,oBAAoB,0BAIjB;IAEH,kBAAkB,0BAKf;IAEH,aAAa,WAGZ;IAKD,iBAAiB,4CAIhB;IAED,iBAAiB,4CAIhB;IAED,kBAAkB,4CAIjB;IAED,kBAAkB,4CAIjB;IAED,UAAU,WAKT;IAKD,oBAAoB,iBAQnB;IAED,qBAAqB,0BAEpB;IAED,kBAAkB,0BAGhB;IAEF,WAAW,0BAKR;IAEH,eAAe,0BAGb;IAEF,YAAY,0BAAyB;IAErC,SAAS,iBAcR;IAED,cAAc,0BAOZ;IAEF,eAAe,0BAGb;IAEF,kBAAkB,0BAGhB;IAEF,0BAA0B,EAAE,CAAC,CAAC,OAAO,CAQpC;IAED,aAAa,0BAAwC;IAErD,SAAS,uBAaR;IAED,qBAAqB,WAKpB;IAED,gBAAgB,WAGf;IAED,SAAS,8BAIR;IAKD,cAAc,eAAY;IAC1B,cAAc,eAAY;IAC1B,mBAAmB,eAAY;IAE/B,gBAAgB,eAAY;IAE5B,gBAAgB,eAAY;IAC5B,cAAc,eAAY;IAE1B,eAAe,eAAY;IAE3B,oBAAoB,eAAY;IAEhC,MAAM,WAAsD;IAE5D,qBAAqB,0BAenB;CACF"}
|
|
@@ -2,7 +2,7 @@ import * as G from '../../exports/Exports.js';
|
|
|
2
2
|
import * as R from 'regexp-composer';
|
|
3
3
|
export class RegExpGrammar {
|
|
4
4
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
5
|
-
// High
|
|
5
|
+
// High-level productions
|
|
6
6
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
7
7
|
disjunction = () => [
|
|
8
8
|
this.sequence,
|
|
@@ -11,7 +11,7 @@ export class RegExpGrammar {
|
|
|
11
11
|
this.disjunction,
|
|
12
12
|
])
|
|
13
13
|
];
|
|
14
|
-
sequence = () => G.
|
|
14
|
+
sequence = () => G.zeroOrMore(this.element);
|
|
15
15
|
element = () => G.anyOf(this.anchor, this.lookaround, this.possiblyQuantifiedExpression);
|
|
16
16
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
17
17
|
// Quantifed expressions
|
|
@@ -38,13 +38,13 @@ export class RegExpGrammar {
|
|
|
38
38
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
39
39
|
group = () => G.anyOf(this.uncapturedGroup, this.namedCaptureGroup, this.unnamedCaptureGroup);
|
|
40
40
|
uncapturedGroup = () => [
|
|
41
|
-
'(
|
|
41
|
+
'(?:',
|
|
42
42
|
this.disjunction,
|
|
43
43
|
')',
|
|
44
44
|
];
|
|
45
45
|
namedCaptureGroup = () => [
|
|
46
46
|
'(?<',
|
|
47
|
-
G.pattern(R.captureAs('name', R.oneOrMore(
|
|
47
|
+
G.pattern(R.captureAs('name', R.oneOrMore(identifierChar))),
|
|
48
48
|
'>',
|
|
49
49
|
this.disjunction,
|
|
50
50
|
')',
|
|
@@ -63,7 +63,7 @@ export class RegExpGrammar {
|
|
|
63
63
|
]);
|
|
64
64
|
namedBackreference = () => G.pattern([
|
|
65
65
|
'\\k<',
|
|
66
|
-
R.captureAs('name',
|
|
66
|
+
R.captureAs('name', R.oneOrMore(identifierChar)),
|
|
67
67
|
'>',
|
|
68
68
|
]);
|
|
69
69
|
backReference = G.anyOf(this.unnamedBackreference, this.namedBackreference);
|
|
@@ -94,7 +94,7 @@ export class RegExpGrammar {
|
|
|
94
94
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
95
95
|
// Single character expressions
|
|
96
96
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
97
|
-
singleCharExpression = () => G.anyOf(this.anyCharWildcard, this.charClass, this.unicodeProperty, this.notUnicodeProperty, this.charcodeOrEscapedChar, this.unreservedCharLiteral);
|
|
97
|
+
singleCharExpression = () => G.anyOf(this.anyCharWildcard, this.charClass, this.unicodeProperty, this.notUnicodeProperty, this.escapedCharacterClass, this.charcodeOrEscapedChar, this.unreservedCharLiteral);
|
|
98
98
|
unreservedCharLiteral = () => G.pattern(R.notAnyOfChars('[', '.', '*', '+', '?', '^', '$', '{', '}', '(', ')', '|', ']', '\\'));
|
|
99
99
|
escapedCharLiteral = () => G.pattern([
|
|
100
100
|
'\\',
|
|
@@ -107,14 +107,21 @@ export class RegExpGrammar {
|
|
|
107
107
|
]);
|
|
108
108
|
controlCharcode = () => G.pattern([
|
|
109
109
|
'\\c',
|
|
110
|
-
R.charRange('A', 'Z'),
|
|
110
|
+
R.anyOf(R.charRange('A', 'Z'), R.charRange('a', 'z')),
|
|
111
111
|
]);
|
|
112
|
-
|
|
112
|
+
nullCharcode = () => G.pattern('\\0');
|
|
113
|
+
codepoint = () => G.anyOf(G.pattern([
|
|
113
114
|
'\\u',
|
|
114
115
|
'{',
|
|
115
|
-
R.captureAs('value', R.
|
|
116
|
+
R.captureAs('value', R.repeated([1, 6], hexDigit)),
|
|
116
117
|
'}',
|
|
117
|
-
])
|
|
118
|
+
]), G.pattern([
|
|
119
|
+
'\\u',
|
|
120
|
+
hexDigit,
|
|
121
|
+
hexDigit,
|
|
122
|
+
hexDigit,
|
|
123
|
+
hexDigit
|
|
124
|
+
]));
|
|
118
125
|
codepointRange = () => G.pattern([
|
|
119
126
|
'\\u',
|
|
120
127
|
'{',
|
|
@@ -133,10 +140,10 @@ export class RegExpGrammar {
|
|
|
133
140
|
]);
|
|
134
141
|
unicodePropertyBodyPattern = [
|
|
135
142
|
'{',
|
|
136
|
-
R.captureAs('property', R.oneOrMore(
|
|
143
|
+
R.captureAs('property', R.oneOrMore(R.anyOf(letter, digit, '_', '-'))),
|
|
137
144
|
R.possibly([
|
|
138
145
|
'=',
|
|
139
|
-
R.captureAs('value', R.oneOrMore(
|
|
146
|
+
R.captureAs('value', R.oneOrMore(R.anyOf(letter, digit, '_', '-'))),
|
|
140
147
|
]),
|
|
141
148
|
'}',
|
|
142
149
|
];
|
|
@@ -144,11 +151,11 @@ export class RegExpGrammar {
|
|
|
144
151
|
charClass = () => [
|
|
145
152
|
'[',
|
|
146
153
|
G.possibly(this.charClassNegator),
|
|
147
|
-
G.oneOrMore(G.anyOf(this.charRange, this.codepointRange, this.
|
|
154
|
+
G.oneOrMore(G.anyOf(this.charRange, this.codepointRange, this.unicodeProperty, this.notUnicodeProperty, this.escapedCharacterClass, this.charcodeOrEscapedChar, this.charClassChar)),
|
|
148
155
|
']',
|
|
149
156
|
];
|
|
150
157
|
charcodeOrEscapedChar = G.anyOf(this.codepoint, this.hexCharcode, this.controlCharcode, this.escapedCharLiteral);
|
|
151
|
-
charRangeElement = G.anyOf(this.charcodeOrEscapedChar, G.pattern(R.
|
|
158
|
+
charRangeElement = G.anyOf(this.charcodeOrEscapedChar, G.pattern(R.notAnyOfChars(']')));
|
|
152
159
|
charRange = () => [
|
|
153
160
|
this.charRangeElement,
|
|
154
161
|
'-',
|
|
@@ -166,19 +173,19 @@ export class RegExpGrammar {
|
|
|
166
173
|
anyCharWildcard = () => '.';
|
|
167
174
|
disjunctionSeparator = () => '|';
|
|
168
175
|
anchor = G.anyOf(this.inputStartAnchor, this.inputEndAnchor);
|
|
169
|
-
escapedCharacterClass = () => G.pattern(R.anyOf(R.captureAs('whitespace', escapedCharString.whitespace), R.captureAs('nonWhitespace', escapedCharString.nonWhitespace), R.captureAs('digit', escapedCharString.digit), R.captureAs('nonDigit', escapedCharString.nonDigit), R.captureAs('wordBoundary', escapedCharString.wordBoundary), R.captureAs('nonWordBoundary', escapedCharString.nonWordBoundary), R.captureAs('formFeed', escapedCharString.formFeed), R.captureAs('carriageReturn', escapedCharString.carriageReturn), R.captureAs('lineFeed', escapedCharString.lineFeed), R.captureAs('tab', escapedCharString.tab), R.captureAs('verticalTab', escapedCharString.verticalTab), R.captureAs('backwardSlash', escapedCharString.backwardSlash)));
|
|
176
|
+
escapedCharacterClass = () => G.pattern(R.anyOf(R.captureAs('whitespace', escapedCharString.whitespace), R.captureAs('nonWhitespace', escapedCharString.nonWhitespace), R.captureAs('digit', escapedCharString.digit), R.captureAs('nonDigit', escapedCharString.nonDigit), R.captureAs('word', escapedCharString.word), R.captureAs('nonWord', escapedCharString.nonWord), R.captureAs('wordBoundary', escapedCharString.wordBoundary), R.captureAs('nonWordBoundary', escapedCharString.nonWordBoundary), R.captureAs('formFeed', escapedCharString.formFeed), R.captureAs('carriageReturn', escapedCharString.carriageReturn), R.captureAs('lineFeed', escapedCharString.lineFeed), R.captureAs('tab', escapedCharString.tab), R.captureAs('verticalTab', escapedCharString.verticalTab), R.captureAs('backwardSlash', escapedCharString.backwardSlash)));
|
|
170
177
|
}
|
|
171
178
|
const digit = R.charRange('0', '9');
|
|
172
179
|
const letter = R.anyOf(R.charRange('a', 'z'), R.charRange('A', 'Z'));
|
|
173
|
-
const letterOrDigit = R.anyOf(letter, digit);
|
|
174
180
|
const hexDigit = R.anyOf(digit, R.charRange('a', 'f'), R.charRange('A', 'F'));
|
|
181
|
+
const identifierChar = R.anyOf(letter, digit, '_', '$');
|
|
175
182
|
const escapedCharString = {
|
|
176
183
|
whitespace: '\\s',
|
|
177
184
|
nonWhitespace: '\\S',
|
|
178
185
|
digit: '\\d',
|
|
179
186
|
nonDigit: '\\D',
|
|
180
|
-
word: '\\
|
|
181
|
-
nonWord: '\\
|
|
187
|
+
word: '\\w',
|
|
188
|
+
nonWord: '\\W',
|
|
182
189
|
wordBoundary: '\\b',
|
|
183
190
|
nonWordBoundary: '\\B',
|
|
184
191
|
formFeed: '\\f',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RegExpGrammar.js","sourceRoot":"","sources":["../../../src/tests/test-grammars/RegExpGrammar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,0BAA0B,CAAA;AAC7C,OAAO,KAAK,CAAC,MAAM,iBAAiB,CAAA;AAEpC,MAAM,OAAO,aAAa;IACzB,8FAA8F;IAC9F,yBAAyB;IACzB,8FAA8F;IAC9F,WAAW,GAAG,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,QAAQ;QAEb,CAAC,CAAC,QAAQ,CAAC;YACV,IAAI,CAAC,oBAAoB;YACzB,IAAI,CAAC,WAAW;SAChB,CAAC;KACF,CAAA;IAED,QAAQ,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"RegExpGrammar.js","sourceRoot":"","sources":["../../../src/tests/test-grammars/RegExpGrammar.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "grammar-composer",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Defines and generates parsers from composable grammar definitions. Includes advanced features like lexer-free parsing, selective packrat memoization and static analysis.",
|
|
5
5
|
"author": "Rotem Dan",
|
|
6
6
|
"license": "MIT",
|
|
@@ -3,7 +3,7 @@ import * as R from 'regexp-composer'
|
|
|
3
3
|
|
|
4
4
|
export class RegExpGrammar {
|
|
5
5
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
6
|
-
// High
|
|
6
|
+
// High-level productions
|
|
7
7
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
8
8
|
disjunction = () => [
|
|
9
9
|
this.sequence,
|
|
@@ -14,7 +14,7 @@ export class RegExpGrammar {
|
|
|
14
14
|
])
|
|
15
15
|
]
|
|
16
16
|
|
|
17
|
-
sequence = () => G.
|
|
17
|
+
sequence = () => G.zeroOrMore(this.element)
|
|
18
18
|
|
|
19
19
|
element = () => G.anyOf(
|
|
20
20
|
this.anchor,
|
|
@@ -66,14 +66,14 @@ export class RegExpGrammar {
|
|
|
66
66
|
)
|
|
67
67
|
|
|
68
68
|
uncapturedGroup = () => [
|
|
69
|
-
'(
|
|
69
|
+
'(?:',
|
|
70
70
|
this.disjunction,
|
|
71
71
|
')',
|
|
72
72
|
]
|
|
73
73
|
|
|
74
74
|
namedCaptureGroup = () => [
|
|
75
75
|
'(?<',
|
|
76
|
-
G.pattern(R.captureAs('name', R.oneOrMore(
|
|
76
|
+
G.pattern(R.captureAs('name', R.oneOrMore(identifierChar))),
|
|
77
77
|
'>',
|
|
78
78
|
this.disjunction,
|
|
79
79
|
')',
|
|
@@ -97,7 +97,7 @@ export class RegExpGrammar {
|
|
|
97
97
|
namedBackreference = () =>
|
|
98
98
|
G.pattern([
|
|
99
99
|
'\\k<',
|
|
100
|
-
R.captureAs('name',
|
|
100
|
+
R.captureAs('name', R.oneOrMore(identifierChar)),
|
|
101
101
|
'>',
|
|
102
102
|
])
|
|
103
103
|
|
|
@@ -148,6 +148,7 @@ export class RegExpGrammar {
|
|
|
148
148
|
this.charClass,
|
|
149
149
|
this.unicodeProperty,
|
|
150
150
|
this.notUnicodeProperty,
|
|
151
|
+
this.escapedCharacterClass,
|
|
151
152
|
this.charcodeOrEscapedChar,
|
|
152
153
|
this.unreservedCharLiteral
|
|
153
154
|
)
|
|
@@ -170,15 +171,26 @@ export class RegExpGrammar {
|
|
|
170
171
|
|
|
171
172
|
controlCharcode = () => G.pattern([
|
|
172
173
|
'\\c',
|
|
173
|
-
R.charRange('A', 'Z'),
|
|
174
|
+
R.anyOf(R.charRange('A', 'Z'), R.charRange('a', 'z')),
|
|
174
175
|
])
|
|
175
176
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
177
|
+
nullCharcode = () => G.pattern('\\0')
|
|
178
|
+
|
|
179
|
+
codepoint = () => G.anyOf(
|
|
180
|
+
G.pattern([
|
|
181
|
+
'\\u',
|
|
182
|
+
'{',
|
|
183
|
+
R.captureAs('value', R.repeated([1, 6], hexDigit)),
|
|
184
|
+
'}',
|
|
185
|
+
]),
|
|
186
|
+
G.pattern([
|
|
187
|
+
'\\u',
|
|
188
|
+
hexDigit,
|
|
189
|
+
hexDigit,
|
|
190
|
+
hexDigit,
|
|
191
|
+
hexDigit
|
|
192
|
+
])
|
|
193
|
+
)
|
|
182
194
|
|
|
183
195
|
codepointRange = () => G.pattern([
|
|
184
196
|
'\\u',
|
|
@@ -201,10 +213,10 @@ export class RegExpGrammar {
|
|
|
201
213
|
|
|
202
214
|
unicodePropertyBodyPattern: R.Pattern = [
|
|
203
215
|
'{',
|
|
204
|
-
R.captureAs('property', R.oneOrMore(
|
|
216
|
+
R.captureAs('property', R.oneOrMore(R.anyOf(letter, digit, '_', '-'))),
|
|
205
217
|
R.possibly([
|
|
206
218
|
'=',
|
|
207
|
-
R.captureAs('value', R.oneOrMore(
|
|
219
|
+
R.captureAs('value', R.oneOrMore(R.anyOf(letter, digit, '_', '-'))),
|
|
208
220
|
]),
|
|
209
221
|
'}',
|
|
210
222
|
]
|
|
@@ -217,9 +229,9 @@ export class RegExpGrammar {
|
|
|
217
229
|
G.oneOrMore(G.anyOf(
|
|
218
230
|
this.charRange,
|
|
219
231
|
this.codepointRange,
|
|
220
|
-
this.charClass,
|
|
221
232
|
this.unicodeProperty,
|
|
222
233
|
this.notUnicodeProperty,
|
|
234
|
+
this.escapedCharacterClass,
|
|
223
235
|
this.charcodeOrEscapedChar,
|
|
224
236
|
this.charClassChar
|
|
225
237
|
)),
|
|
@@ -235,7 +247,7 @@ export class RegExpGrammar {
|
|
|
235
247
|
|
|
236
248
|
charRangeElement = G.anyOf(
|
|
237
249
|
this.charcodeOrEscapedChar,
|
|
238
|
-
G.pattern(R.
|
|
250
|
+
G.pattern(R.notAnyOfChars(']')),
|
|
239
251
|
)
|
|
240
252
|
|
|
241
253
|
charRange = () => [
|
|
@@ -267,6 +279,8 @@ export class RegExpGrammar {
|
|
|
267
279
|
R.captureAs('nonWhitespace', escapedCharString.nonWhitespace),
|
|
268
280
|
R.captureAs('digit', escapedCharString.digit),
|
|
269
281
|
R.captureAs('nonDigit', escapedCharString.nonDigit),
|
|
282
|
+
R.captureAs('word', escapedCharString.word),
|
|
283
|
+
R.captureAs('nonWord', escapedCharString.nonWord),
|
|
270
284
|
R.captureAs('wordBoundary', escapedCharString.wordBoundary),
|
|
271
285
|
R.captureAs('nonWordBoundary', escapedCharString.nonWordBoundary),
|
|
272
286
|
R.captureAs('formFeed', escapedCharString.formFeed),
|
|
@@ -280,16 +294,16 @@ export class RegExpGrammar {
|
|
|
280
294
|
|
|
281
295
|
const digit = R.charRange('0', '9')
|
|
282
296
|
const letter = R.anyOf(R.charRange('a', 'z'), R.charRange('A', 'Z'))
|
|
283
|
-
const letterOrDigit = R.anyOf(letter, digit)
|
|
284
297
|
const hexDigit = R.anyOf(digit, R.charRange('a', 'f'), R.charRange('A', 'F'))
|
|
298
|
+
const identifierChar = R.anyOf(letter, digit, '_', '$')
|
|
285
299
|
|
|
286
300
|
const escapedCharString = {
|
|
287
301
|
whitespace: '\\s',
|
|
288
302
|
nonWhitespace: '\\S',
|
|
289
303
|
digit: '\\d',
|
|
290
304
|
nonDigit: '\\D',
|
|
291
|
-
word: '\\
|
|
292
|
-
nonWord: '\\
|
|
305
|
+
word: '\\w',
|
|
306
|
+
nonWord: '\\W',
|
|
293
307
|
wordBoundary: '\\b',
|
|
294
308
|
nonWordBoundary: '\\B',
|
|
295
309
|
formFeed: '\\f',
|