Handling of non-layout sections in HsParser

Anders Lau Olsen alauo at mip.sdu.dk
Tue Oct 16 05:24:41 EDT 2001


HsParser fails on any of these 6 examples:

    data Data = A {
    x :: Int
    }

    f1 x = let {
    s = x
    } in s

    f2 x = do {
    x
    }

    f3 x = case x of {
    _ -> 12
    }

    f4 x = s where {
    s = 12
    }

    f5 y = A {
    x = 45
    }

The problem seems to be the production (copied from HsParser.ly)

    > layout_off :: { () }	:	{% pushContext NoLayout }

This production is supposed to make the parser enter a NoLayout
context every time the lexer reaches an open brace '{'. It is used in
other productions such as

    > decllist :: { [HsDecl] }
    >	: '{' layout_off decls '}'	{ $3 }
    >	|     layout_on  decls close	{ $2 }

For some reason the use of layout_off only takes effect _after_ the
lexer has produced the next token. When the lexer reaches the second x
in

    f2 x = do {
    x
    }

the NoLayout hasn't been pushed yet. Since x is indented to the same
column as f2, the lexer therefore inserts a ';'. The '{' followed by a ';'
causes the parser to fail. In code with a more normal indentation

    f2 x = do {
        x
    }

the parser works fine, because the lexer in this case doesn't insert
an extra ';' or '}'.

One way of fixing this is to remove all uses of layout_off, and
instead delegate the pushing of NoLayouts to the lexer. I have
attached a patch of HsParser.ly and HsLexer.lhs to show what I had in
mind.

Anders
-------------- next part --------------
233c233
<         '{' -> special LeftCurly
---
>         '{' -> \ctxt -> special LeftCurly (NoLayout : ctxt)
-------------- next part --------------
130c130
< >	:  '{' layout_off bodyaux '}'			{ $3 }
---
> >	:  '{' bodyaux '}'				{ $2 }
286c286
< >	: '{' layout_off decls '}'	{ $3 }
---
> >	: '{' decls '}'			{ $2 }
370,371c370,371
< >	| srcloc con '{' layout_off fielddecls '}' 
< >					{ HsRecDecl $1 $2 (reverse $5) }
---
> >	| srcloc con '{' fielddecls '}' 
> >					{ HsRecDecl $1 $2 (reverse $4) }
417c417
< >	: 'where' '{' layout_off cbody '}'	{ $4 }
---
> >	: 'where' '{' cbody '}'			{ $3 }
438c438
< >	: 'where' '{' layout_off valdefs '}'	{ $4 }
---
> >	: 'where' '{' valdefs '}'		{ $3 }
506c506
< >  	: aexp '{' layout_off fbinds '}' {% mkRecConstrOrUpdate $1 (reverse $4) }
---
> >  	: aexp '{' fbinds '}' 		{% mkRecConstrOrUpdate $1 (reverse $3) }
571c571
< >	: '{' layout_off alts optsemi '}'	{ reverse $3 }
---
> >	: '{' alts optsemi '}'			{ reverse $2 }
601c601
< >	  : '{' layout_off stmts '}'	{ $3 }
---
> >	  : '{' stmts '}'		{ $2 }
738d737
< > layout_off :: { () }	:	{% pushContext NoLayout }


More information about the Glasgow-haskell-bugs mailing list