Skip to content
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

Parse error should close layout block #426

Open
andreasabel opened this issue Oct 5, 2022 · 0 comments
Open

Parse error should close layout block #426

andreasabel opened this issue Oct 5, 2022 · 0 comments
Labels
layout Concerning layout (keywords)
Milestone

Comments

@andreasabel
Copy link
Member

andreasabel commented Oct 5, 2022

BNFC's layout handling does not implement the following clause, taken from the Haskell 98 report:

A close brace is also inserted whenever the syntactic category containing the layout list ends; that is, if an illegal lexeme is encountered at a point where a close brace would be legal, a close brace is inserted.

Consider this small (artificial) expression grammar with a sum construct that can use layout.

ETimes.   Exp   ::= Exp "*" Exp1;
ESum.     Exp1  ::= "sum" "{" [Exp] "}";
EInt.     Exp1  ::= Integer;

_.        Exp   ::= Exp1;
_.        Exp1  ::= "begin" Exp "end";

separator Exp ";";

layout "sum";

As BNFC has a workaround for parentheses "(...)", we use "begin ... end" here instead.

This grammar handles e.g. sum { 1; 2; sum { 3;4;5 } * 6 } * 7. It fails on:

begin sum
  begin 1 end
  2 end * 3

The correct reconstruction of the block would be:

begin sum
  { begin 1 end
  ; 2 } end * 3

However, he token stream generated by the layout pass does not respect the bracketing begin ... end:

1:01	"begin"
1:07	"sum"
1:11	"{"
2:03	"begin"
2:09	"1"
2:11	"end"
2:15	";"
3:03	"2"
3:05	"end"
3:09	"*"
3:11	"3"
3:13	"}"

This is because the closing brace } is inserted mechanically according to the off-side rule, yet it should be inserted more dynamically by the parser to fix the parse error generated by the end token in line 3. Basically, the closing bracket is not inserted by dedentation but also by parse errors.

A layout stop "end" instruction does not help here, as we then close the layout block too early, before the first end, rather than the second end:

1:01	"begin"
1:07	"sum"
1:11	"{"
2:03	"begin"
2:09	"1"
2:11	"}"
2:11	"end"
3:03	"2"
3:05	"end"
3:09	"*"
3:11	"3"
@andreasabel andreasabel added the layout Concerning layout (keywords) label Oct 5, 2022
@andreasabel andreasabel added this to the 3.0 milestone Oct 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
layout Concerning layout (keywords)
Projects
None yet
Development

No branches or pull requests

1 participant