[C2hs] Re: making c2hs undrstand line pragmas

Manuel M T Chakravarty chak at cse.unsw.edu.au
Wed May 24 12:02:47 EDT 2006


Duncan,

I think this is still an outstanding issue.

> I've got a patch to c2hs to make it do something with C style line
> pragmas in .chs files, eg:
> 
> # 1 "gtk/Graphics/UI/Gtk/TreeList/TreeStore.chs.pp"
> 
> These are produced by the C preprocessor. Currently c2hs chokes on these
> and so people have to use the -P option to cpp to suppress them. They
> are actually rather useful if the code in fact does need preprocessing
> (as most of gtk2hs's .chs files do) because they point to the original
> file name and source locations. For example it means that ghc's errors
> will report accurate locations in the .chs.pp file rather than reporting
> locations in the .chs file.
> 
> c2hs already produces accurate Haskell line pragmas {-# LINE ... #-} in
> the .hs files it produces for exactly that reason. I want to extend that
> to the case that the .chs file itself has had a preprocessor used on it.
> 
> One other reason to preserve the original file name is that haddock can
> now include links to the source files, and it uses the line pragmas to
> find the original source file. It doesn't do much good however if
> haddock links to a non-existant .chs file when the real original file
> was .chs.pp.

Ok, I see how this would be useful.  Please push your patch.

> The only thing that's wrong is that c2hs doesn't recognise cpp
> directives as the first line in a .chs file. You can see why this is so
> from the code below:
> 
> cpp :: CHSLexer
> cpp = directive
>       where
>         directive = 
> 	  string "\n#" +> alt ('\t':inlineSet)`star` epsilon
> 	  `lexmeta` 
> 	     \(_:_:dir) pos s ->	-- strip off the "\n#"
> 	       case dir of
> 
> 		... etc
> 
> It's requires a cpp directive to start with a newline followed by a '#'
> character.
> 
> I'm not sufficiently familiar with the style of c2hs's chs lexer to
> figure out how to fix this. Perhaps it can be done by checking if we're
> at the beginning of a line in a different way. Perhaps it can be done by
> checking the current column rather than looking for a '\n' character.

Yes, that's an awkward bit in the code that has bothered me before.  The
lexer combinators have not neat way to check for characters appearing in
a particular column.  I see only two ways to proceed:

      * We could match on # alone and then check in the action what
        column we are in and do different things in dependence on this.
        I don't like this, as it messes up the longest match rule and
        might be fragile.
      * We can prepend a '\n' character to the source file before
        starting the lexing process by changing the triple passed to
        execLexer in the function lexCHS (and we must then also adjust
        the initial value of `pos' to still get accurate line numbers).
        This is a bit of a kludge, but it seems to be the more robust
        solution to me.

Manuel




More information about the C2hs mailing list