| Hi Guillaume Smet It is message from Dmitry Masherov (Dmitry_Masherov@epam.com) : We made some changes to overcome what we think are limitations of the current parser implementation:
- The parser considers any input to be valid
The main rule for the grammar is the rule Query, in which two rules are used: ParsedQuery and CriteriaOnlyFindQuery. When parsing of the Query rule is invoked, parser tests either ParsedQuery or CriteriaOnlyFindQuery. If one of the rules matches the whole input, overall parsing succeeds.
When ParsedQuery fails, the rule CriteriaOnlyFindQuery is tested. But since this rule matches everything ( ZeroOrMore(ANY) ), the parser succeeds in matching Query rule for any input.
public Rule CriteriaOnlyFindQuery() {
return Sequence( ZeroOrMore( ANY ), builder.setOperation( Operation.FIND ), builder.setCriteria( match() ) );
}
In order to make parser fail we modified CriteriaOnlyFindQuery to match JsonObjects. This way the rule Query will fail and parser will yield "matched == false" and a list of parse errors for not CLI queries or just JSON object.
- There are almost identical rules for every type of operation
The rules for every operation and it processing look very similar to each other, so we thought it would be easier to collect the certain parts of the string like operation name and arguments and then process all these parts in one place after matching the whole input, rather to use almost identical rules for each case. To do this we added custom actions to various stages of CliQuery rule execution:
public Rule CliQuery() {
return Sequence(
ZeroOrMore( WhiteSpace() ),
PathExpression(), processPathExpression,
ZeroOrMore( WhiteSpace() ),
"( ", Arguments(), ") ", processCliQueryInfo
);
}
Actions `processPathExpression` and `processCliQueryInfo` construct all the parts which will be passed to builder and fill the builder with all the neccessary information. If there is something wrong we add the appropriate error to the list of parse errors and manually fail the rule. Also it is difficult to add new type of operations (not sure if needed now though) since you have to add it to Reserved rule, to Operation rule and use appropriate builder command in the rule itself.
- There is no custom error reporting.
To add the custom error we add it to the list of part errors during an action execution.
context.getParseErrors().add(
createParseError(
context, 2, "CLI query should match 'db.<COLLECTION>.<OPERATION>'"
)
);
|