Chevrotain / chevrotain

Parser Building Toolkit for JavaScript
https://chevrotain.io
Apache License 2.0
2.44k stars 200 forks source link

Question about computeContentAssist() #1925

Closed appocalypseltd closed 1 year ago

appocalypseltd commented 1 year ago

This is more of a question than a bug or an error...not quite understanding the meaning of occurrenceStack returned as part of ISyntacticContentAssistPath[] from computeContentAssist().

The source code says:

The occurrence index (SUBRULE1/2/3/5/…) of each Grammar rule invoked and still unterminated. Used to distinguish between different invocations of the same subrule at the same top level rule.

So I don't understand how it can be an array like this:

[1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]

If the rule at index 4 is unterminated, then why are the preceding rules also not indicated as unterminated?

For context, here is one of the elements of the array:

{
  "nextTokenType": {
    "name": "OpenBracket",
    "PATTERN": {},
    "tokenTypeIdx": 12,
    "CATEGORIES": [],
    "categoryMatches": [],
    "categoryMatchesMap": {},
    "isParent": false
  },
  "nextTokenOccurrence": 0,
  "ruleStack": [
    "booleanExpression",
    "booleanTerm",
    "booleanFactor",
    "comparison",
    "additionExpression",
    "multiplicationExpression",
    "atomicExpression",
    "parenthesisExpression",
    "additionExpression",
    "multiplicationExpression",
    "atomicExpression",
    "parenthesisExpression"
  ],
  "occurrenceStack": [1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]
}

1 corresponds to booleanExpression, and 2 to additionExpression, defined like this:

public booleanExpression = this.RULE("booleanExpression", () => {
  this.SUBRULE(this.booleanTerm);
  this.MANY(() => {
    this.CONSUME(RuleLexer.Or);
    this.SUBRULE2(this.booleanTerm);
  });
});

public additionExpression = this.RULE("additionExpression", () => {
  this.SUBRULE(this.multiplicationExpression, { LABEL: "lhs" });
  this.MANY(() => {
    this.CONSUME(AdditionOperator);
    this.SUBRULE2(this.multiplicationExpression, { LABEL: "rhs" });
  });
});

(actually think that rule has a bug in it, just noticed 🤣)

So if additionExpression is unterminated, why is the preceding comparison also not unterminated?

public comparison = this.RULE("comparison", () => {
  this.SUBRULE(this.additionExpression);
  this.SUBRULE(this.comparisonOperator);
  this.SUBRULE2(this.additionExpression);
});

I'm just trying out lots of partial source snippets to see if I can get my head around what this object is telling me.