Friday, June 11, 2021

Modular Happy Packages

I am so happy to find modular Happy packages. 


Happy is a parser generator system for Haskell, similar to the tool Yacc for C, OCamlYacc for OCaml, and so on. It has been used for generating a GHC's Haskell parser. 


Since its birth, it has been a monolithic architecture. Now it is time to make it modular so that Happy can be used more than just GHC's Haskell parser. 

- [PR] Modularize happy #191

- piknotech/happy{modularization branch}


It consists of happy-{frontend,middleend,backend,core,test} packages. Happy-frontend is for reading .y files and parsing them into the Grammar datatype. Happy-middleend applies LR/GLR parsing algorithms to the grammar to have action tables and goto tables. Happy-backend generates template-based Haskell code using these tables. Happy-core defines common interfaces among these packages, and Happy-test is about a testing framework. It is said to have the same CLI as the original monolithic Happy so that the transition from the existing one to this one can be as smooth as possible. Isn't it great?


This is how to install this modular Happy packages in modular_happy directory.

$ mkdir modular_happy; cd modular_happy

$ git init

$ git remote add origin https://github.com/piknotech/happy

$ git pull origin modularization 

(You don't have to build it for now.)


You can test these packages with GHC's Parser:

- Parser.y


Just to read this Parser.y and to print it in Grammar datatype, this simple program is enough.

$ stack new example; cd example       (Assume example and modular_happy are in the same level)

(Include the following in package.yaml)

dependencies:

- base >= 4.7 && < 5

- happy-frontend >= 1.21.0

- happy-middleend >= 1.21.0

- happy-backend >= 1.21.0

- happy-core >= 1.21.0

(Include the following in stack.yaml)
packages:
- .
- ../modular_happy/packages/frontend
- ../modular_happy/packages/middleend
- ../modular_happy/packages/backend
- ../modular_happy/packages/core

(Edit app/Main.hs as this)
module Main where

import Happy.Frontend.CLI
import Happy.Core.Grammar

main :: IO ()
main = do
  either <- parseAndRun [] "Parser.y" "Parser"
  case either of
    Left error -> putStrLn error
    Right grammar -> putStrLn $ show $ grammar
    
$ stack build

(Download the Parser.y into the top-level directory of stack project)

$ stack exec example-exe

(It will be able to read Parser.y and to print it.)

Yeah!!

Note: If you have a build error, it might be caused by the absence of alex and happy in your system.

 - sudo apt-get install alex happy


(Special thanks to the author of the modular Happy packages, David Knothe.)

On 25 March 2023, David Knothe's proposal seems to be gradually accepted to Happy as: