Question

I am trying to generate a GLR parser from happy, but I am getting errors once the files are generated.

Here is an example, ABC.y , so it's clear what I am trying:

{
module Main where
}
%name ps1 s1
%tokentype { ABC }
%error { parseError }
%token
  a { A }
  b { B }
  c { C }
%%

s1: a a a b {} | b s2 a {}
s2: b a b s2 {} | c {}
{
data ABC = A | B | C
parseError _ = error "bad"
main = getContents >>= print . ps1 . lexer
lexer ('a':xs) = A : lexer xs
ETC
}

This example works just fine with

happy ABC.y

However, happy'd with --glr, I cannot build the result. I am wondering if I am doing it wrong. To be precise, happy --glr, produces the two outputs, ABC.hs. ABCData.hs, however,

ghc --make ABC.hs ABCData.hs

fails now. The error I get is Could not find module 'System', It is a hidden member of haskell-98... I tried adding package haskell98, and got ambiguous prelude problems. I also tried coding the grammar into BNFC and using their -glr option, but I still get other errors, like dependency on Data.FiniteMap which is apparently deprecated. Is there a way to get this compiling?

Was it helpful?

Solution

happy --glr

Works fine -- there is just one thing that must be manually changed in the output. Note however, it is different from using Happy on a typical _.y file.

Basically, there are a bunch of differences you have to take into consideration. The type of the expected lexer result is different. The type of return from the parser is less controllable and different. And the way you use the parser is slightly different. The necessary information can be found on : http://www.haskell.org/happy/doc/html/sec-glr-using.html and it's really important to understand that web-page to correctly use the glr option.

Here is how you can use Happy with the glr option to produce a standalone parser; all we will care about is if the parse was successful -- you can read more about the results of parsing and how to interpret them on the above page. We will do this for the parser above, ABC. First, create a file called ABCMain.hs:

module Main where

import ABC
import ABCData

main = do
    inp <- getContents
    case happyParse (lexer inp) of
        ParseOK _ _ -> putStrLn "success"
        _ -> putStrLn " success"
lexer ('a':xs) = [A] : lexer xs
ETC -- note that it is [[Token]] instead of [Token]

And the ABC.y file is simply:

%tokentype { ABC }
%error { parseError }
%token 
    a { A }
    b { B }
    c { C }
%%
s1 : a a a b {} | b s2 a {}
s2: b a b s2 {} | c {}
{
data ABC = A | B | C deriving (Eq,Ord,Show) -- you must have Eq and Ord
parseError _ = error "bad"
}

Run

happy --glr ABC.y

Producing the two files. Now, there is one point I would love someone to comment about -- essentially you have to manually change, in the generated file ABC.hs, the line

import System

to

import System.IO

Then, the following works for me:

ghc --make ABCMain.hs

Everything compiles and the parser works as expected. Feel free to let me know if I am doing correctly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top