haskell / alex

A lexical analyser generator for Haskell
https://hackage.haskell.org/package/alex
BSD 3-Clause "New" or "Revised" License
297 stars 82 forks source link

Supporting alex <3.2 and >= 3.2 in the same file #102

Closed ethercrow closed 7 years ago

ethercrow commented 7 years ago

It seems like one must handle AlexLastAcc like this with alex <3.2

  AlexLastAcc k input len -> ... AlexToken input len k ...

and like this with alex >= 3.2

  AlexLastAcc k input len -> ... AlexToken input len (alex_actions ! k) ...

Is there a CPP define for alex version so I can at least put this line under #ifdef?

Or maybe is there another way to write it so it works with both versions like a typeclass with instances for Int and a type of alex_action?

Problem is that stackage LTS provides 3.1.7 and stackage nightly provides 3.2.1 and I'd like very much for yi to compile with both.

ethercrow commented 7 years ago

The relevant line: https://github.com/yi-editor/yi/blob/master/yi-language/src/Yi/Lexer/common.hsinc#L39

Here act is either an action or an index for alex_actions.

simonmar commented 7 years ago

Can you do something like this in your .cabal file?

flag alex32
  default: True

if flag(alex32)
  build-depends: alex >= 3.2
  ghc-options: -DALEX_3_2
else
  build-depends: alex < 3.2
ethercrow commented 7 years ago

I can but this would put the burden of knowing their alex version and supplying this flag on users, who most likely don't even know what alex is.

I'll do that if there's no other option.

@snoyberg @juhp Does stack by any chance expose alex version in some #define?

simonmar commented 7 years ago

I can but this would put the burden of knowing their alex version and supplying this flag on users, who most likely don't even know what alex is.

No - Cabal infers the value of flags automatically, users wouldn't need to do anything.

snoyberg commented 7 years ago

I'm not sure this will work; build-depends doesn't play nicely with executable-only packages.

simonmar commented 7 years ago

If it doesn't, then you could use another package as a proxy. (a gross hack, but it would probably work)

ethercrow commented 7 years ago

@qnikst proposed to use TOOL_VERSION_alex defined by Cabal

ethercrow commented 7 years ago

I'll leave this here in case someone will have the same question.

 +#if MIN_TOOL_VERSION_alex(3,2,0)
 +      (AlexLastAcc k input'' len, _, lookahead) -> (AlexToken input'' len (alex_actions ! k), lookahead)
 +#else
        (AlexLastAcc k input'' len, _, lookahead) -> (AlexToken input'' len k, lookahead)
 +#endif