-
Notifications
You must be signed in to change notification settings - Fork 200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Empty Alternative inside Nested Repetitions causes infinite loops on Parser initilization #1200
Comments
Thanks for reporting this @matthew-dean Do you have a small grammar that reproduces the issue?
Maybe another check for invalid grammars could be added, but I need to reproduce the scenario first... |
@bd82 Sorry for the incomplete information. Yes, it was fixable by changing grammar. I'm trying to think of the scenarios where I encountered this. It's happened to me a few times. Each time, there was a clearer way to express the grammar that didn't trigger this, but unfortunately, no, I don't have a simple grammar to trigger it. I just wanted to raise the issue that these loops are not detected by analysis. Sorry there's not more to go on! |
@bd82 IIRC, I do have a commit somewhere for Less grammar where this was happening... but it wouldn't be a simple reproduction. Hmm, I can look for it. If it happens again, I'll definitely make a branch and commit it. |
o.k. if you can reproduce in the future even with a more complex example I will try to debug. reopen this issue if/when you have a reproducible case. |
@bd82 Just had this happen again! So I immediately pushed the commit. This rule |
|
If I change the block in mixin to: $.MANY(() => {
$.OR([
{ ALT: () => $.SUBRULE($.expressionList) },
{ ALT: () => $.SUBRULE($.curlyBlock) }
])
$.OPTION(() => {
$.CONSUME($.T.SemiColon)
$.isSemiColonSeparated = true
})
}) I get, However, this is false. The curlyBlock must start with a (The mixin test was basically working except for accepting curly blocks. If I remove the |
Oh wait! If I flip the order (put curlyBlock first), it works! EDIT: No wait, it doesn't..... or does it? Anyway, curious that it doesn't have the same error if it's ambiguous. |
I'll try to play with this on the weekend |
This may be related to: #855 Debugging such a large example is complicated and I am not making much headway, I may try to resolve the issue linked above (which includes a small reproducible case) instead and see if also resolves this issue. |
I can reproduce the issue with this small example: const { CstParser, createToken, EMPTY_ALT } = require("chevrotain")
// ----------------- lexer -----------------
const Comma = createToken({ name: "Comma", pattern: /,/ })
const allTokens = [
Comma
]
class NestedManyEmptyAltBugParser extends CstParser {
constructor() {
super(allTokens)
const $ = this
// the parsing methods
$.RULE("A", () => {
$.MANY(() => {
$.SUBRULE($.B)
});
});
$.RULE("B", () => {
$.MANY(() => {
$.SUBRULE($.C)
});
});
$.RULE("C", () => {
$.OR([
{ ALT: () => $.CONSUME(Comma) },
{ ALT: () => EMPTY_ALT }
]);
});
this.performSelfAnalysis()
}
}
const parser = new NestedManyEmptyAltBugParser()
|
In the meanwhile I suggest you try to refactor your grammar to avoid the empty alternative or avoid the MANY inside MANY. (even if it means duplicated grammar parts). |
@bd82 So you think it's the I think the problem in my case is the use of |
The phase that causes the infinite loop does not take into account the GATEs at all. |
I'm sure this was a grammar error on my part, but just wanted to let you know it's possible to get into a loop state while performing self-analysis.
The loop is like this:
The text was updated successfully, but these errors were encountered: