How to AT_LEAST_ONE without repeats #2008
-
Hi, First of all - I very much love Chevrotain, great work thank you! ❤️ I'm trying to parse this PostgreSQL command:https://www.postgresql.org/docs/current/sql-grant.html For example, in this form:
...we can see this is valid:
However, I'm not sure how to model/express
Any pointers warmly welcomed! Thanks |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
Hey @timneedham, I usually don't recommend performing this sort of work in the parser at all. Of course it depends on your use case, but in my line of work (writing language support for language servers/IDEs), building such "no repeats" rules into the parser usually yields uninterpreterable parser errors for the user. My personal recommendation would be to have a validation phase performed on the output of the parser to validate that certain rules are being followed by the input. If you're dead set on doing this work in the parser, here's my advice:
Yes, that would probably be the way to go. We do something similar in Langium with unordered groups. The implementation is relatively straightforward: const set = new Set<number>();
this.AT_LEAST_ONE(() => {
this.OR([
{
GATE: () => !set.has(0),
ALT: () => {
set.add(0);
this.CONSUME(SELECT_TOKEN);
}
},
{
GATE: () => !set.has(1),
ALT: () => {
set.add(1);
this.CONSUME(INSERT_TOKEN);
}
},
{
GATE: () => !set.has(2),
ALT: () => {
set.add(2);
this.CONSUME(UPDATE_TOKEN);
}
},
...
]);
}); If you are doing the |
Beta Was this translation helpful? Give feedback.
Are
GRANT ... ON TABLE
andGRANT ... ON SEQUENCE
separate rules? In this case you'll always get an ambiguity error in Chevrotain due to the unknown-length common prefix. You should definitely refactor this into a single rule to prevent the prefix issue.Essentially, yes.