clarity-pattern-parser 11.0.1 → 11.0.3

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.
@@ -10,7 +10,6 @@ export declare class Context implements Pattern {
10
10
  private _children;
11
11
  private _pattern;
12
12
  private _patterns;
13
- shouldCompactAst: boolean;
14
13
  get id(): string;
15
14
  get type(): string;
16
15
  get name(): string;
@@ -0,0 +1,31 @@
1
+ import { Node } from "../ast/Node";
2
+ import { Cursor } from "./Cursor";
3
+ import { ParseResult } from "./ParseResult";
4
+ import { Pattern } from "./Pattern";
5
+ export declare class RightAssociatedPattern implements Pattern {
6
+ private _id;
7
+ private _type;
8
+ private _name;
9
+ private _parent;
10
+ private _children;
11
+ get id(): string;
12
+ get type(): string;
13
+ get name(): string;
14
+ get parent(): Pattern | null;
15
+ set parent(pattern: Pattern | null);
16
+ get children(): Pattern[];
17
+ get startedOnIndex(): number;
18
+ constructor(pattern: Pattern);
19
+ parse(cursor: Cursor): Node | null;
20
+ exec(text: string, record?: boolean | undefined): ParseResult;
21
+ test(text: string, record?: boolean | undefined): boolean;
22
+ clone(_name?: string | undefined): Pattern;
23
+ getTokens(): string[];
24
+ getTokensAfter(_childReference: Pattern): string[];
25
+ getNextTokens(): string[];
26
+ getPatterns(): Pattern[];
27
+ getPatternsAfter(_childReference: Pattern): Pattern[];
28
+ getNextPatterns(): Pattern[];
29
+ find(predicate: (pattern: Pattern) => boolean): Pattern | null;
30
+ isEqual(pattern: Pattern): boolean;
31
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clarity-pattern-parser",
3
- "version": "11.0.1",
3
+ "version": "11.0.3",
4
4
  "description": "Parsing Library for Typescript and Javascript.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.esm.js",
@@ -584,4 +584,15 @@ describe("Grammar", () => {
584
584
  expect(result).toBe(result);
585
585
  });
586
586
 
587
+ test("Expression Pattern With Right Association", () => {
588
+ const { expression } = patterns`
589
+ variables = "a" | "b" | "c" | "d" | "e"
590
+ ternary = expression + " ? " + expression + " : " + expression
591
+ expression = ternary right | variables
592
+ `;
593
+ let result = expression.exec("a ? b : c ? d : e");
594
+ debugger;
595
+ expect(result).toBe(result);
596
+ });
597
+
587
598
  });
@@ -11,7 +11,8 @@ import { Repeat, RepeatOptions } from "../patterns/Repeat";
11
11
  import { AutoComplete } from "../intellisense/AutoComplete";
12
12
  import { Optional } from "../patterns/Optional";
13
13
  import { Context } from "../patterns/Context";
14
- import {ExpressionPattern} from "../patterns/ExpressionPattern";
14
+ import { ExpressionPattern } from "../patterns/ExpressionPattern";
15
+ import { RightAssociatedPattern } from "../patterns/RightAssociatedPattern";
15
16
 
16
17
  let anonymousIndexId = 0;
17
18
 
@@ -248,14 +249,22 @@ export class Grammar {
248
249
  private _buildOptions(name: string, node: Node) {
249
250
  const patternNodes = node.children.filter(n => n.name !== "default-divider" && n.name !== "greedy-divider");
250
251
  const isGreedy = node.find(n => n.name === "greedy-divider") != null;
251
- const patterns = patternNodes.map(n => this._buildPattern(n));
252
- const hasRecursivePattern = patterns.some(p=>this._isRecursive(name, p));
252
+ const patterns = patternNodes.map(n => {
253
+ const rightAssociated = n.find(n => n.name === "right-associated");
254
+ if (rightAssociated != null) {
255
+ return new RightAssociatedPattern(this._buildPattern(n.children[0]));
256
+ } else {
257
+ return this._buildPattern(n.children[0]);
258
+ }
253
259
 
254
- if (hasRecursivePattern && !isGreedy){
260
+ });
261
+
262
+ const hasRecursivePattern = patterns.some(p => this._isRecursive(name, p));
263
+ if (hasRecursivePattern && !isGreedy) {
255
264
  try {
256
265
  const expression = new ExpressionPattern(name, patterns);
257
266
  return expression;
258
- } catch{}
267
+ } catch { }
259
268
  }
260
269
 
261
270
  const or = new Options(name, patterns, isGreedy);
@@ -271,10 +280,16 @@ export class Grammar {
271
280
  }
272
281
 
273
282
  private _isRecursivePattern(name: string, pattern: Pattern) {
274
- return pattern.type === "sequence" &&
275
- pattern.children[0].type === "reference" &&
276
- pattern.children[0].name === name &&
277
- pattern.children.length > 2;
283
+ if (pattern.children.length === 0){
284
+ return false;
285
+ }
286
+
287
+ const firstChild = pattern.children[0];
288
+ const lastChild = pattern.children[pattern.children.length - 1];
289
+ const isLongEnough = pattern.children.length >= 2;
290
+ return pattern.type === "sequence" && isLongEnough &&
291
+ (firstChild.type === "reference" && firstChild.name === name) ||
292
+ (lastChild.type === "reference" && lastChild.name === name);
278
293
  }
279
294
 
280
295
  private _buildPattern(node: Node): Pattern {
@@ -3,11 +3,17 @@ import { Regex } from "../../patterns/Regex";
3
3
  import { name } from "./name";
4
4
  import { anonymousPattern } from "./anonymousPattern";
5
5
  import { Options } from "../../patterns/Options";
6
+ import { Sequence } from "../../patterns/Sequence";
7
+ import { Optional } from "../../patterns/Optional";
8
+ import { Literal } from "../../patterns/Literal";
6
9
 
7
10
  const patternName = name.clone("pattern-name");
8
11
  patternName.setTokens(["[PATTERN_NAME]"]);
9
12
 
10
- const patterns = new Options("options-patterns", [patternName, anonymousPattern]);
13
+ const patterns = new Sequence("patterns", [
14
+ new Options("options-patterns", [patternName, anonymousPattern]),
15
+ new Optional("optional-right-associated", new Literal("right-associated", " right"))
16
+ ]);
11
17
  const defaultDivider = new Regex("default-divider", "\\s*[|]\\s*");
12
18
  defaultDivider.setTokens(["|"]);
13
19
 
@@ -14,8 +14,6 @@ export class Context implements Pattern {
14
14
  private _pattern: Pattern;
15
15
  private _patterns: Record<string, Pattern>;
16
16
 
17
- shouldCompactAst = false;
18
-
19
17
  get id(): string {
20
18
  return this._id;
21
19
  }
@@ -82,7 +80,6 @@ export class Context implements Pattern {
82
80
  clone(name = this._name): Pattern {
83
81
  const clone = new Context(name, this._pattern, Object.values(this._patterns));
84
82
  clone._id = this._id;
85
- clone.shouldCompactAst = this.shouldCompactAst;
86
83
  return clone;
87
84
  }
88
85
 
@@ -416,8 +416,8 @@ export class ExpressionPattern implements Pattern {
416
416
 
417
417
  break;
418
418
  } else {
419
- cursor.resolveError();
420
419
  cursor.moveTo(onIndex);
420
+ cursor.resolveError();
421
421
  }
422
422
  }
423
423
 
@@ -147,7 +147,7 @@ export class PrecedenceTree {
147
147
  let node = this._atomNode;
148
148
 
149
149
  if (this._prefixNode != null && this._atomNode != null) {
150
- node = this._prefixNode;
150
+ node = this._prefixNode.findRoot();
151
151
  this._prefixPlaceholder.replaceWith(this._atomNode);
152
152
  }
153
153
 
@@ -12,8 +12,6 @@ export class RightAssociatedPattern implements Pattern {
12
12
  private _parent: Pattern | null;
13
13
  private _children: Pattern[];
14
14
 
15
- shouldCompactAst = false;
16
-
17
15
  get id(): string {
18
16
  return this._id;
19
17
  }