clarity-pattern-parser 11.4.0 → 11.4.2

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.
@@ -0,0 +1,23 @@
1
+ import { GrammarFile } from "../../grammar/Grammar";
2
+ import { Pattern } from "../../patterns/Pattern";
3
+ export type Decorator = (pattern: Pattern, arg?: string | boolean | number | null | Record<string, any> | any[]) => void;
4
+ export interface GrammarOptions {
5
+ resolveImport?: (resource: string, originResource: string | null) => Promise<GrammarFile>;
6
+ resolveImportSync?: (resource: string, originResource: string | null) => GrammarFile;
7
+ originResource?: string | null;
8
+ params?: Pattern[];
9
+ decorators?: Record<string, Decorator>;
10
+ }
11
+ export declare class Grammar {
12
+ private _options;
13
+ private _parseContext;
14
+ private _resolveImportSync;
15
+ constructor(options: GrammarOptions);
16
+ private _resolveImportsSync;
17
+ private _processImportSync;
18
+ private _getWithParams;
19
+ private _processUseParams;
20
+ private _tryToParse;
21
+ private _flattenExpressions;
22
+ private _unwrapNode;
23
+ }
@@ -0,0 +1,87 @@
1
+ import { Expression } from "../../../patterns/Expression";
2
+ import { Literal } from "../../../patterns/Literal";
3
+ import { Optional } from "../../../patterns/Optional";
4
+ import { Options } from "../../../patterns/Options";
5
+ import { Regex } from "../../../patterns/Regex";
6
+ import { Repeat } from "../../../patterns/Repeat";
7
+ import { Sequence } from "../../../patterns/Sequence";
8
+ export declare const syntax: Literal;
9
+ export declare const imprt: Literal;
10
+ export declare const useParams: Literal;
11
+ export declare const withParams: Literal;
12
+ export declare const from: Literal;
13
+ export declare const right: Literal;
14
+ export declare const ws: Regex;
15
+ export declare const ls: Regex;
16
+ export declare const assign: Literal;
17
+ export declare const bar: Literal;
18
+ export declare const greedyBar: Literal;
19
+ export declare const concat: Literal;
20
+ export declare const colon: Literal;
21
+ export declare const openParen: Literal;
22
+ export declare const closeParen: Literal;
23
+ export declare const openSquareBracket: Literal;
24
+ export declare const closeSquareBracket: Literal;
25
+ export declare const openBracket: Literal;
26
+ export declare const closeBracket: Literal;
27
+ export declare const comma: Regex;
28
+ export declare const trim: Literal;
29
+ export declare const not: Literal;
30
+ export declare const optional: Literal;
31
+ export declare const newLine: Regex;
32
+ export declare const syntaxVersion: Regex;
33
+ export declare const at: Literal;
34
+ export declare const optionalWS: Optional;
35
+ export declare const optionalLS: Optional;
36
+ export declare const literal: Regex;
37
+ export declare const regex: Regex;
38
+ export declare const integer: Regex;
39
+ export declare const name: Regex;
40
+ export declare const patternName: Regex;
41
+ export declare const patternIdentifier: Regex;
42
+ export declare const resource: Regex;
43
+ export declare const comment: Regex;
44
+ export declare const jsonString: Regex;
45
+ export declare const jsonNumber: Regex;
46
+ export declare const trueLiteral: Literal;
47
+ export declare const falseLiteral: Literal;
48
+ export declare const jsonBoolean: Options;
49
+ export declare const jsonNull: Literal;
50
+ export declare const jsonArrayItems: Repeat;
51
+ export declare const jsonArray: Sequence;
52
+ export declare const jsonObjectPropertyName: Regex;
53
+ export declare const jsonObjectProperty: Sequence;
54
+ export declare const jsonObjectProperties: Repeat;
55
+ export declare const jsonObject: Sequence;
56
+ export declare const jsonValue: Options;
57
+ export declare const syntaxStatement: Sequence;
58
+ export declare const decorationName: Regex;
59
+ export declare const decorationStatement: Sequence;
60
+ export declare const useParamPatterns: Repeat;
61
+ export declare const useParamsStatement: Sequence;
62
+ export declare const withParamStatements: Repeat;
63
+ export declare const withParamsExpr: Sequence;
64
+ export declare const patternNames: Repeat;
65
+ export declare const importedPatterns: Sequence;
66
+ export declare const importStatement: Sequence;
67
+ export declare const notExpr: Sequence;
68
+ export declare const optionalExpr: Sequence;
69
+ export declare const rightAssociationExpr: Sequence;
70
+ export declare const unaryPatternExpr: Expression;
71
+ export declare const repeatBounds: Sequence;
72
+ export declare const oneOrMore: Literal;
73
+ export declare const zeroOrMore: Literal;
74
+ export declare const repeatOptions: Options;
75
+ export declare const delimiter: Sequence;
76
+ export declare const repeatExpr: Sequence;
77
+ export declare const sequenceExpr: Sequence;
78
+ export declare const optionsExpr: Sequence;
79
+ export declare const greedyOptionsExpr: Sequence;
80
+ export declare const patternGroupExpr: Sequence;
81
+ export declare const exportPattern: Regex;
82
+ export declare const patternExpr: Expression;
83
+ export declare const patternAssignment: Sequence;
84
+ export declare const statement: Options;
85
+ export declare const statements: Repeat;
86
+ export declare const cpat: Sequence;
87
+ export declare const grammar: Sequence;
@@ -433,6 +433,7 @@
433
433
  }
434
434
  }
435
435
 
436
+ const segmenter = new Intl.Segmenter("und", { granularity: "grapheme" });
436
437
  class Cursor {
437
438
  get text() {
438
439
  return this._text;
@@ -483,33 +484,55 @@
483
484
  return this._history.error != null;
484
485
  }
485
486
  get currentChar() {
486
- return this._text[this._index];
487
+ const index = this.getCharStartIndex(this._index);
488
+ return this.text.slice(index, index + this._charSize[index]);
487
489
  }
488
490
  constructor(text) {
489
491
  this._text = text;
492
+ this._length = text.length;
493
+ this._charSize = [];
494
+ this._charMap = [];
490
495
  this._index = 0;
491
- this._length = [...text].length;
492
496
  this._history = new CursorHistory();
497
+ let index = 0;
498
+ for (const segment of segmenter.segment(text)) {
499
+ const size = segment.segment.length;
500
+ for (let i = 0; i < size; i++) {
501
+ this._charMap.push(index);
502
+ this._charSize.push(size);
503
+ }
504
+ index += size;
505
+ }
493
506
  }
494
507
  hasNext() {
495
- return this._index + 1 < this._length;
508
+ const index = this._charMap[this._index];
509
+ const charSize = this._charSize[index];
510
+ return index + charSize < this._length;
496
511
  }
497
512
  next() {
498
513
  if (this.hasNext()) {
499
- this._index++;
514
+ const index = this._charMap[this._index];
515
+ const size = this._charSize[index];
516
+ this.moveTo(index + size);
500
517
  }
501
518
  }
502
519
  hasPrevious() {
503
- return this._index - 1 >= 0;
520
+ var _a;
521
+ const index = this._charMap[this._index];
522
+ const previousIndex = (_a = this._charMap[index - 1]) !== null && _a !== void 0 ? _a : -1;
523
+ return previousIndex >= 0;
504
524
  }
505
525
  previous() {
526
+ var _a;
506
527
  if (this.hasPrevious()) {
507
- this._index--;
528
+ const index = this._charMap[this._index];
529
+ const previousIndex = (_a = this._charMap[index - 1]) !== null && _a !== void 0 ? _a : -1;
530
+ this.moveTo(previousIndex);
508
531
  }
509
532
  }
510
533
  moveTo(position) {
511
534
  if (position >= 0 && position < this._length) {
512
- this._index = position;
535
+ this._index = this._charMap[position];
513
536
  }
514
537
  }
515
538
  moveToFirstChar() {
@@ -521,7 +544,7 @@
521
544
  getLastIndex() {
522
545
  return this._length - 1;
523
546
  }
524
- getChars(first, last) {
547
+ substring(first, last) {
525
548
  return this._text.slice(first, last + 1);
526
549
  }
527
550
  recordMatch(pattern, node) {
@@ -539,6 +562,18 @@
539
562
  stopRecording() {
540
563
  this._history.stopRecording();
541
564
  }
565
+ getCharStartIndex(index) {
566
+ return this._charMap[index];
567
+ }
568
+ getCharEndIndex(index) {
569
+ var _a;
570
+ let startIndex = this.getCharStartIndex(index);
571
+ return (_a = startIndex + this._charSize[startIndex]) !== null && _a !== void 0 ? _a : 1;
572
+ }
573
+ getCharLastIndex(index) {
574
+ var _a;
575
+ return (_a = this.getCharEndIndex(index) - 1) !== null && _a !== void 0 ? _a : 0;
576
+ }
542
577
  }
543
578
 
544
579
  function execPattern(pattern, text, record = false) {
@@ -604,11 +639,9 @@
604
639
  this._type = "literal";
605
640
  this._name = name;
606
641
  this._token = value;
607
- this._runes = Array.from(value);
608
642
  this._parent = null;
609
643
  this._firstIndex = 0;
610
644
  this._lastIndex = 0;
611
- this._endIndex = 0;
612
645
  }
613
646
  test(text, record = false) {
614
647
  return testPattern(this, text, record);
@@ -618,6 +651,7 @@
618
651
  }
619
652
  parse(cursor) {
620
653
  this._firstIndex = cursor.index;
654
+ this._lastIndex = cursor.index;
621
655
  const passed = this._tryToParse(cursor);
622
656
  if (passed) {
623
657
  cursor.resolveError();
@@ -625,31 +659,28 @@
625
659
  cursor.recordMatch(this, node);
626
660
  return node;
627
661
  }
628
- cursor.recordErrorAt(this._firstIndex, this._endIndex, this);
662
+ cursor.recordErrorAt(this._firstIndex, this._lastIndex, this);
629
663
  return null;
630
664
  }
631
665
  _tryToParse(cursor) {
632
- let passed = false;
633
- const literalRuneLength = this._runes.length;
634
- for (let i = 0; i < literalRuneLength; i++) {
635
- const literalRune = this._runes[i];
636
- const cursorRune = cursor.currentChar;
637
- if (literalRune !== cursorRune) {
638
- this._endIndex = cursor.index;
639
- break;
640
- }
641
- if (i + 1 === literalRuneLength) {
642
- this._lastIndex = this._firstIndex + this._token.length - 1;
643
- passed = true;
644
- break;
645
- }
646
- if (!cursor.hasNext()) {
647
- this._endIndex = cursor.index + 1;
648
- break;
666
+ const token = this._token;
667
+ const compareToToken = cursor.text.slice(this._firstIndex, this._firstIndex + this._token.length);
668
+ const length = Math.min(token.length, compareToToken.length);
669
+ for (let i = 0; i < length; i++) {
670
+ if (token[i] !== compareToToken[i]) {
671
+ this._lastIndex = this._firstIndex + i;
672
+ cursor.moveTo(this._lastIndex);
673
+ return false;
649
674
  }
650
- cursor.next();
651
675
  }
652
- return passed;
676
+ if (token != compareToToken) {
677
+ this._lastIndex = this._firstIndex + compareToToken.length - 1;
678
+ cursor.moveTo(this._lastIndex);
679
+ return false;
680
+ }
681
+ this._lastIndex = this._firstIndex + this._token.length - 1;
682
+ cursor.moveTo(this._lastIndex);
683
+ return true;
653
684
  }
654
685
  _createNode() {
655
686
  return new Node("literal", this._name, this._firstIndex, this._lastIndex, undefined, this._token);
@@ -728,7 +759,7 @@
728
759
  this._name = name;
729
760
  this._parent = null;
730
761
  this._originalRegexString = regex;
731
- this._regex = new RegExp(`^${regex}`, "g");
762
+ this._regex = new RegExp(`^${regex}`, "gu");
732
763
  this.assertArguments();
733
764
  }
734
765
  assertArguments() {
@@ -757,7 +788,7 @@
757
788
  resetState(cursor) {
758
789
  this._cursor = cursor;
759
790
  this._regex.lastIndex = 0;
760
- this._substring = this._cursor.text.substr(this._cursor.index);
791
+ this._substring = this._cursor.text.slice(this._cursor.index);
761
792
  this._node = null;
762
793
  }
763
794
  tryToParse(cursor) {
@@ -771,9 +802,10 @@
771
802
  }
772
803
  processResult(cursor, result) {
773
804
  const currentIndex = cursor.index;
774
- const newIndex = currentIndex + result[0].length - 1;
775
- this._node = new Node("regex", this._name, currentIndex, newIndex, undefined, result[0]);
776
- cursor.moveTo(newIndex);
805
+ const match = result[0];
806
+ const lastIndex = cursor.getCharLastIndex(currentIndex + match.length - 1);
807
+ this._node = new Node("regex", this._name, currentIndex, lastIndex, undefined, result[0]);
808
+ cursor.moveTo(lastIndex);
777
809
  cursor.recordMatch(this, this._node);
778
810
  }
779
811
  processError(cursor) {
@@ -3301,7 +3333,7 @@
3301
3333
  }
3302
3334
  if (foundMatch) {
3303
3335
  cursor.moveTo(cursorIndex - 1);
3304
- const value = cursor.getChars(this.startedOnIndex, cursorIndex - 1);
3336
+ const value = cursor.substring(this.startedOnIndex, cursorIndex - 1);
3305
3337
  const node = Node.createValueNode(this._type, this._name, value);
3306
3338
  cursor.recordMatch(this, node);
3307
3339
  return node;
@@ -3453,7 +3485,7 @@
3453
3485
  }
3454
3486
  const lastPattern = furthestMatch.pattern;
3455
3487
  const suggestions = cleanSuggestions(lastPattern.getNextTokens());
3456
- const strUpToError = cursor.getChars(0, endIndex);
3488
+ const strUpToError = cursor.substring(0, endIndex);
3457
3489
  const lines = strUpToError.split("\n");
3458
3490
  const lastLine = lines[lines.length - 1];
3459
3491
  const line = lines.length;
@@ -4191,9 +4223,9 @@
4191
4223
  }
4192
4224
  _createSuggestionOptionsFromErrors() {
4193
4225
  // These errored because the length of the string.
4194
- const errors = this._cursor.errors.filter(e => e.lastIndex === this._cursor.length);
4226
+ const errors = this._cursor.errors.filter(e => e.lastIndex === this._cursor.length - 1);
4195
4227
  const errorSuggestionOptions = errors.map(parseError => {
4196
- const currentText = this._cursor.getChars(parseError.startIndex, parseError.lastIndex);
4228
+ const currentText = this._cursor.substring(parseError.startIndex, parseError.lastIndex);
4197
4229
  const compositeSuggestions = this._getCompositeSuggestionsForPattern(parseError.pattern);
4198
4230
  const trimmedErrorCompositeSuggestions = this._trimSuggestionsByExistingText(currentText, compositeSuggestions);
4199
4231
  return this._createSuggestions(parseError.lastIndex, trimmedErrorCompositeSuggestions);
@@ -4249,7 +4281,7 @@
4249
4281
  * ie. sequence pattern segments ≈ [{look}, {an example}, {phrase}]
4250
4282
  * fullText = "look an"
4251
4283
  * remove {look} segment as its already been completed by the existing text.
4252
- */
4284
+ */
4253
4285
  _filterCompletedSubSegments(currentText, compositeSuggestion) {
4254
4286
  let elementsToRemove = [];
4255
4287
  let workingText = currentText;
@@ -4352,7 +4384,7 @@
4352
4384
  return unique;
4353
4385
  }
4354
4386
  _createSuggestions(lastIndex, compositeSuggestionList) {
4355
- let textToIndex = lastIndex === -1 ? "" : this._cursor.getChars(0, lastIndex);
4387
+ let textToIndex = lastIndex === -1 ? "" : this._cursor.substring(0, lastIndex);
4356
4388
  const options = [];
4357
4389
  for (const compositeSuggestion of compositeSuggestionList) {
4358
4390
  // concatenated for start index identification inside createSuggestion