Expression/command ambiguity resolution
authorVladislav Zavialov <vlad.z.4096@gmail.com>
Fri, 1 Feb 2019 17:03:54 +0000 (20:03 +0300)
committerMarge Bot <ben+marge-bot@smart-cactus.org>
Sun, 24 Feb 2019 02:37:52 +0000 (21:37 -0500)
commite61f6e35e2fffb1e82e9559852481010fe84d8d3
tree0846f5666bf0553effbfa72facf3b8557f216492
parent6cce36f83aec33d33545e0ef2135894d22dff5ca
Expression/command ambiguity resolution

This patch removes 'HsArrApp' and 'HsArrForm' from 'HsExpr' by
introducing a new ambiguity resolution system in the parser.

Problem: there are places in the grammar where we do not know whether we
are parsing an expression or a command:

proc x -> do { (stuff) -< x }   -- 'stuff' is an expression
proc x -> do { (stuff) }        -- 'stuff' is a command

Until we encounter arrow syntax (-<) we don't know whether to parse
'stuff' as an expression or a command.

The old solution was to parse as HsExpr always, and rejig later:

checkCommand :: LHsExpr GhcPs -> P (LHsCmd GhcPs)

This meant polluting 'HsExpr' with command-related constructors. In
other words, limitations of the parser were affecting the AST, and
all other code (the renamer, the typechecker) had to deal with these
extra constructors by panicking.

We fix this abstraction leak by parsing into an intermediate
representation, 'ExpCmd':

data ExpCmdG b where
  ExpG :: ExpCmdG HsExpr
  CmdG :: ExpCmdG HsCmd

type ExpCmd = forall b. ExpCmdG b -> PV (Located (b GhcPs))

checkExp :: ExpCmd -> PV (LHsExpr GhcPs)
checkCmd :: ExpCmd -> PV (LHsCmd GhcPs)
checkExp f = f ExpG  -- interpret as an expression
checkCmd f = f CmdG  -- interpret as a command

See Note [Ambiguous syntactic categories] for details.

Now the intricacies of parsing have no effect on the hsSyn AST when it
comes to the expression/command ambiguity.

Future work: apply the same principles to the expression/pattern
ambiguity.
compiler/deSugar/DsExpr.hs
compiler/hieFile/HieAst.hs
compiler/hsSyn/HsExpr.hs
compiler/hsSyn/HsUtils.hs
compiler/parser/Parser.y
compiler/parser/RdrHsSyn.hs
compiler/rename/RnExpr.hs
compiler/typecheck/TcRnTypes.hs
hadrian/src/Settings/Builders/Happy.hs
mk/config.mk.in
testsuite/tests/ghci/scripts/T8959.stderr