-
Notifications
You must be signed in to change notification settings - Fork 5
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
formatter continued 01 #22
base: main
Are you sure you want to change the base?
Conversation
@@ -363,6 +363,7 @@ fn expr_binding(parser: &mut Parser, separator: SyntaxKind) { | |||
expr_where(parser); | |||
marker.end(parser, SyntaxKind::UnconditionalBinding); | |||
} else { | |||
// NOTE[et]: We get an infinet loop here since `expr_guarded` needs to beable to match an empty expression, so we just abort this loop if we have looped. It's a crude solution but it works to eliminate infinet loops in the parser. This logic lies inside the `one_or_more` parser |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have an example file that can cause this infinite loop?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A minimum reproduction that I conjured is:
b | if 0 else 1 then 2 = 0
This fails due to how expr_if
is defined:
fn expr_if(parser: &mut Parser) {
let mut marker = parser.start();
parser.expect(SyntaxKind::IfKw);
expr_0(parser);
parser.expect(SyntaxKind::ThenKw);
expr_0(parser);
parser.expect(SyntaxKind::ElseKw);
expr_0(parser);
marker.end(parser, SyntaxKind::IfThenElseExpression);
}
More specifically, expect
is basically eat
but it emits an error if it isn't able to consume the current token. The new expect_recover
function is more suitable for this, where it eats the current token indiscriminately while also emitting an error node for the CST.
That being said, loop-safety in the parser is definitely something we should strive for; checking if the parser made progress is a good solution, and I think we should also look into "recovering" as much as possible in the parsing rules.
Start { kind: ConstrainedType } | ||
Start { kind: TypeOperatorChain } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since =>
is built-in and cannot be re-defined, I think this should be parsed as ConstrainedType
. I haven't implemented desugaring for TypeOperatorChain
in the analyzer yet but ConstrainedType
and ArrowType
should be kept as-is.
Looks good so far, though I'd advise staying away from the |
I continued my routine of trying to parse purescript code and fixing what is missing or broken.
During my fixing I added more debug info to the tests and handled crashes more transparently so they'll be easier trouble shooted in the future - the code is a bit ugly but I think it does the jobb.
We also have trouble with infinet loops in the parser - I've found one of them and did something that might or might not be a fix. I check the number of tokens we've eaten and if it stays constant we're stuck and I simply break out of the loop - now this method is not that sophisticated but solved some of the problems I have.
I also noticed we don't check that we've parsed the entire file when we generate our tests, that's something that we should look into if we are striving for correctness.