haskell / happy

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

Vendor `happy-codegen-common` into `happy-grammar` #286

Closed sgraf812 closed 2 months ago

sgraf812 commented 2 months ago

The package happy-codegen-common presently contains a single file:

/-----------------------------------------------------------------------------
The CommonOptions data type.

(c) 1993-2001 Andy Gill, Simon Marlow
-----------------------------------------------------------------------------

> module Happy.CodeGen.Common.Options (
>       ErrorHandlerType(..),
>       CommonOptions(..)
>       ) where

> data ErrorHandlerType
>   = ErrorHandlerTypeDefault
>   | ErrorHandlerTypeExpList

> data CommonOptions
>       = CommonOptions {
>               token_type        :: String,
>               imported_identity :: Bool,
>               monad             :: (Bool,String,String,String,String),
>               expect            :: Maybe Int,
>               lexer             :: Maybe (String,String),
>               error_handler     :: Maybe String,
>               error_sig         :: ErrorHandlerType
>       }

This data type describes pragmas to be used in happy's .y-files such as %expect, %monad, etc. Hence this file belongs in happy-grammar, which defines the remaining AST data types for happy's .y-files. Doing so has the nice benefit of cutting down on the jungle of happy-* packages. We will have just the following dependency structure

flowchart TD

    A("happy-grammar")
    B("happy-frontend")
    C("happy-tabular")
    D("happy-backend-lalr")
    E("happy-backend-glr")

    A --> B 
    A --> C --> D 
    A --> D
    A --> E
    C --> E

This will revert https://github.com/haskell/happy/pull/221 (Edit: Actually it doesn't. The new domain data type expressing pragmas is still there; good), but I do disagree with the opening statement

There was some extra information stuff in Grammar which had nothing to do with the grammar, but was simply there because Grammar was also playing the role of capturing all information from the abstract syntax.

As I said above, the pragmas whose AST representation CommonOptions encodes are very much part of the syntax of grammar files.

Ericson2314 commented 2 months ago

OK my thinking was this is that: Yes, this does reflect the syntax of happy grammars, but none of this stuff is about the grammar itself (a mathematical construct) and instead all this stuff is misc hooks for the backends. (It is somewhat comparable to inline assembly in being a sort of wormhole to talk to a later pipeline stage.)

I figured if we ever got things like a grammar or table "interpreter", those would not need any of these options, but just work on the grammar itself. Likewise I would try to decouple the assumption of grammers always having Haskell elimination rules, etc. from the grammer type, so you could do something like write just the grammar, and then separately write the elimination rules for a given grammer.

I should probably just admit I don't have time time to do any of these things, but I thought I would leave this comment for posterity.

sgraf812 commented 2 months ago

I totally agree with you in principle that we should strive for a decoupled design with small domain types. That's why I like the main part of #221: Introducing a type that captures pragmas. Maintaining good domain models especially pays dividends in projects that are likely to evolve much over time, but I don't see happy becoming one of these projects. Splitting off small domain types is fine still. Splitting off small domain packages containing these types, however, incurs a very real overhead on maintenance and decision making and does not deliver any tangible benefit. The original motivation was to enable re-use of the innards of happy. Let's stick to that motivation and try not to get lost in impactless refactorings that ultimately make the project progressing slower rather than faster.

On that front: for happy-rad it would be useful if we exposed the CLI in the library as well: https://github.com/haskell/happy/issues/239. It seems in arguing in what sub-library this functionality should end up, we ultimately succumbed to paralysis.

Ericson2314 commented 2 months ago

I do think a modular CLI is kinda a fraught concept because UI stuff is hard/complex/less naturally orthogonal, but I would be happy if if the RAD backend was just stuck in this repo and shipped by default.

sgraf812 commented 2 months ago

Well, that sounds quite antithetical to the whole purpose of modularisation. Why would you split everything into libraries, except the CLI, even if happy-rad is presently forced to copy happy's Main.lhs wholesale?

Apart from that, I think it's a bad idea to merge happy-rad into happy, because the former is unlikely to see much maintenance in the future. It will accumulate the same kind of bit rod as the GLR backend.