-
Notifications
You must be signed in to change notification settings - Fork 6
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
Question about the implementation of the parser #7
Comments
If you do not want to generate it, then here is a temporary link to a ready-made parser. I am ready to answer any questions you may have. |
@mezoni: for a while now, what I was mostly interested was a lenient query parser: users may provide badly formatted queries, and rejecting them may or may not be with the desired output. Would your parser and grammar provide that feature? |
No. Only simple cases. When a possible error is taken into account in the grammar and a special parsing rule is created for this. Not the most convenient way. You can read on the Internet, so many interesting articles. All of them are theoretical. |
Can you provide examples? |
Sorry for disturbing you. |
Anything that mixes and does not close subqueries, e.g. |
Your case is very simple and not simple at the same time. A malformed string can only be recovered only at the position of an invalid character (such as a newline) and at the end of the file. The missing For example, it is easier to recovred it in a
But recovering it in Well formed:
Malformed
How to recover? Only in this way.
But this is no correct if it was missing after
Dart analyzer also cannot recover this correctly. |
But I changed the grammar and it doesn't throw errors in simple cases. test('missign )', () {
expect(debugQuery('('), '(<>)');
expect(debugQuery('(a b'), '((<a> <b>))');
expect(debugQuery('-(-(a OR -b) -c) | -(d'),
'(-((-((<a> OR -<b>)) -<c>)) OR -(<d>))');
// Missing after `c`
// The parser parses, but the result is unpredictable.
debugQuery('-(-(a OR -b) -c | -(d)');
}); 00:00 +0: Base expressions missign )
|
Passed group('Base expressions', () {
test('missing `) or `"`', () {
expect(debugQuery('(field: "x'), '(field:"<x>")');
expect(debugQuery('("x'), '("<x>")');
expect(debugQuery('('), '(<>)');
expect(debugQuery('(a b'), '((<a> <b>))');
expect(debugQuery('-(-(a OR -b) -c) | -(d'),
'(-((-((<a> OR -<b>)) -<c>)) OR -(<d>))');
// Missing after `c`
// The parser parses, but the result is unpredictable.
debugQuery('-(-(a OR -b) -c | -(d)');
});
Send you a grammar? |
Error Handling in PEG Parsers |
I edited the grammar here: |
Of course, for such purposes, I could even write a separate parser builder. And then the generated parser will do it instead of you and for you. Here I posted a post about the performance test. |
Instead of this code. const _group = Named(
'_group',
Preceded(
_openParen,
Alt2(
Map1(Terminated(_and, _recoveryCloseParen),
Expr<GroupQuery>(['child'], 'GroupQuery({{child}})')),
Map1(_recoveryCloseParen,
Expr<TextQuery>(['_'], "GroupQuery(TextQuery(''))")),
))); Thisi code should be used. For recovering. const _group = Named(
'_group',
Map3(
_openParen,
Opt(_and),
_recoveryCloseParen,
Expr<GroupQuery>(['open', 'child', 'close'],
''' GroupQuery({{child}} ?? TextQuery('')) '''))); This generates simple and understandable code. GroupQuery? _group(State<String> state) {
GroupQuery? $0;
final $pos = state.pos;
String? $1;
$1 = _openParen(state);
if (state.ok) {
Query? $2;
final $log = state.log;
state.log = false;
Query? $3;
$3 = _and(state);
if (state.ok) {
$2 = $3!;
} else {
state.ok = true;
$2 = null;
}
state.log = $log;
if (state.ok) {
String? $4;
$4 = _recoveryCloseParen(state);
if (state.ok) {
$0 = GroupQuery($2 ?? TextQuery(''));
}
}
}
if (!state.ok) {
state.pos = $pos;
}
return $0;
} And it works. |
A new version is available. |
Initially, a trace implementation feature is available. The way you want it, because it's a code generator and nothing is impossible (almost not). The trace will show you how the parsing process goes and where something goes wrong (in your opinion). And all this can be debugged (that is, use deep analysis). |
Hello, István!
For the sake of interest, I implemented a parser for your queries specification.
To be honest, your specification does not specify everything, so I took some liberties in interpreting the missing definitions.
But this is not a problem, because it can be fixed in a few minutes in the parser definition.
Most of the time was spent studying the source code in order to understand the grammar (and specification too).
It took me no more than a few hours to write the parser definition, and then only because the specification is not comprehensive.
Below is the source code for the parser definition. The source code of the tests are included (for simplicity) in the source code of the parser. By running the generated parser, you are essentially running tests.
To be able to generate this parser, you need to add the package from the Github repository into dependencies.
The text was updated successfully, but these errors were encountered: