haskell / happy

The Happy parser generator for Haskell
Other
282 stars 84 forks source link

version 2.1: unrecognised directive: %errorhandlertype #320

Open yav opened 2 days ago

yav commented 2 days ago

It appears that as of version 2.1 happy reports:

unrecognised directive: %errorhandlertype

This directive is still in the docs, so if it is removed indeed, it'd be nice to update the docs to say what changed, and what to do instead.

int-index commented 2 days ago

Its removal is not in the changelog, so I'd assume it was unintentional.

318 is likely the culprit.

Ericson2314 commented 2 days ago

https://github.com/haskell/happy/pull/318/files#diff-afd5c13988aad40ea499045febecb363cc647906c5241ae478543521d39b5daa OK that test update looks it is the culprit

CC @sgraf812 you mentioned changing an undocumented thing, but this is different?

sgraf812 commented 1 day ago

Thanks for the bug report and sorry for inflicting it upon you on a Friday! I deprecated 2.1.

I was not aware that the old %errorhandlertype was documented (it appears I looked in the wrong file ...), so I removed it without replacement. It is superseded by the simple flag %error.expected.

I had thought I could simply bring back the old flag in a backwards compatible way, but the feature was implemented weirdly enough that this is not as simple to achieve.

I'm inclined to bump the version of happy to 3.0 and emit a warning that %errorhandlertype was overhauled and superseded by %error.expected.

sgraf812 commented 1 day ago

@yav I would be glad if you gave the user guide changes in #322 a read to see if they make sense to you. It appears you are a very rare client of this feature :) I assure you that its functionality in 3.0 has been improved.

yav commented 1 day ago

The description of %error.expected is nice, as a standalone feature. I don't know the technical details, but from the description it sounds like %error.expected does a very similar thing to %errorhandlertype expect%.

I imagine that %error.expected turns on some boolean flag that is used by happy when it detects errors. Is there really no way to set the same internal flag with %errorhandlertype expect%, instead of having to rename the directive?

I think this would be much better, because we'd remain somewhat backward compatible, even if the new behavior is a bit different somehow. And, if it is, then the docs should emphasize the difference to the old behavior, at least for a little while, until the old behavior is far enough in the past that is unlikely ti be used.

sgraf812 commented 1 day ago

I don't know the technical details, but from the description it sounds like %error.expected does a very similar thing to %errorhandlertype expect%.

Indeed, I intended to fix a few things in the implementation of %errorhandlertype:

Neither issue would require a backwards incompatible change.

However, the main problem (and the reason for the incompatibility) is that %errorhandlertype explist passes the additional token list parameter to the error handler by turning the Token parameter into (Token, [String]) -> P a. The main payload of 2.1 is the new catch mechanism for resumptive parsing, which requires passing the resumption as a parameter to the error handler. I don't think it's good design to turn the pair into a triple (Token, [String], P a) -> P a, where the first P a is the resumption, and then into a quadruple when the next extension to happy comes along. I would rather pass these parameters individually, Token -> [String] -> P a -> P a.

However I can see that backwards compatibility is an important virtue. Perhaps I can try to mimic the old behavior when %errorhandlertype explist is used. Presumably with resumptions we would get (Token, [String]) -> P a -> P a, but that would work with Happy 2.1 anyway in which case one could use %error.expected instead. Your (catch-free) use case with %errorhandlertype explist would keep working across multiple versions of Happy.

Will try something on Monday.