Refactor importdecls/topdecls parsing.
authorEdward Z. Yang <ezyang@cs.stanford.edu>
Mon, 2 Jan 2017 22:03:42 +0000 (17:03 -0500)
committerBen Gamari <ben@smart-cactus.org>
Mon, 2 Jan 2017 22:44:50 +0000 (17:44 -0500)
commit8d63ca981f689463655766c252160d3fec160264
tree8349553ae3e7fdeea0f1a72442d888891b5a7c6b
parentb28ca38e6e1d75f3c10cc593cdd2ac80ec29690f
Refactor importdecls/topdecls parsing.

Previously, we had the following parser:

    xs : xs ';' x
       | xs ';'
       | x

This is a very clever construction that handles duplicate,
leading and trailing semicolons well, but it didn't work very
well with annotations, where we wanted to attach the annotation
for a semicolon to the *previous* x in the list.  This lead
to some very disgusting code in the parser.

This commit refactors the parser into this form:

    semis1 : semis1 ';'
           | ';'
    xs_semi : xs x semis1
            | {- empty -}
    xs : xs_semi x

Now, when we parse one or more semicolons after an x, we can
attach them immediately, eliminating some very grotty annotations
swizzling that was previously in the parser.

We now need to write the top-level parser for imports and then
declarations in a slightly special way now:

    top : semis top1
    top1 : importdecls_semi topdecls_semi
         | importdecls_semi topdecls
         | importdecls

This is because the *_semi parsers always require a semicolon,
but we're allowed to omit that last newline.  So we need
special cases to handle each of the possible cases where we
may run out of semicolons. I don't know if there is a better
way to structure this, but it is not much more complicated
than what we had before for top (and asymptotically better!)

Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
Test Plan: validate

Reviewers: simonmar, austin, alanz, bgamari

Reviewed By: alanz, bgamari

Subscribers: thomie, mpickering

Differential Revision: https://phabricator.haskell.org/D2893
compiler/parser/Parser.y