Skip to content
This repository was archived by the owner on May 22, 2019. It is now read-only.

Commit c1fdf2e

Browse files
committed
Refactor some productions
1 parent 2af39ca commit c1fdf2e

File tree

1 file changed

+27
-29
lines changed

1 file changed

+27
-29
lines changed

src/Language/PureScript/CST/Parser.y

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,22 @@ import Language.PureScript.CST.Utils
2424
import qualified Language.PureScript.Names as N
2525
}
2626
27+
%expect 75
28+
2729
%name parseKind kind
2830
%name parseType type
2931
%name parseExpr expr
3032
%name parseModuleBody moduleBody
3133
%partial parseModuleHeader moduleHeader
3234
%partial parseDoStatement doStatement
33-
%partial parseDoBinder doBinder
3435
%partial parseDoExpr doExpr
3536
%partial parseDoNext doNext
36-
%partial parseGuardBinder guardBinder
3737
%partial parseGuardExpr guardExpr
3838
%partial parseGuardNext guardNext
39+
%partial parseGuardStatement guardStatement
3940
%partial parseClassSuper classSuper
4041
%partial parseClassNameAndFundeps classNameAndFundeps
42+
%partial parseBinderAndArrow binderAndArrow
4143
%tokentype { SourceToken }
4244
%monad { Parser }
4345
%error { parseError }
@@ -343,7 +345,7 @@ exprBacktick :: { Expr () }
343345
344346
expr2 :: { Expr () }
345347
: expr3 { $1 }
346-
| '-' expr3 { ExprNegate () $1 $2 }
348+
| '-' expr2 { ExprNegate () $1 $2 }
347349
348350
expr3 :: { Expr () }
349351
: expr4 { $1 }
@@ -439,10 +441,10 @@ guardedExpr(a) :: { GuardedExpr () }
439441
-- productions to parse it, so we'd have to maintain an ad-hoc handwritten
440442
-- parser which is very difficult to audit.
441443
--
442-
-- As an alternative we introduce some backtracking. Using %partial parsers,
443-
-- we can encode the state transitions and use the backtracking `tryPrefix`
444-
-- combinator. Binders are generally very short in comparison to expressions,
445-
-- so the cost is modest.
444+
-- As an alternative we introduce some backtracking. Using %partial parsers and
445+
-- monadic reductions, we can invoke productions manually and use the
446+
-- backtracking `tryPrefix` combinator. Binders are generally very short in
447+
-- comparison to expressions, so the cost is modest.
446448
--
447449
-- doBlock
448450
-- : 'do' '\{' manySep(doStatement, '\;') '\}'
@@ -459,24 +461,24 @@ guardedExpr(a) :: { GuardedExpr () }
459461
-- : expr0
460462
-- | binder '<-' expr0
461463
--
462-
doBlock
464+
doBlock :: { DoBlock () }
463465
: 'do' '\{'
464466
{%% revert $ do
465467
res <- parseDoStatement
466468
when (null res) $ addFailure [$2] ErrEmptyDo
467469
pure $ DoBlock $1 $ NE.fromList res
468470
}
469471

470-
adoBlock
472+
adoBlock :: { (SourceToken, [DoStatement ()]) }
471473
: 'ado' '\{'
472474
{%% revert $ fmap ($1,) parseDoStatement }
473475

474-
doStatement
476+
doStatement :: { [DoStatement ()] }
475477
: 'let' '\{' manySep(letBinding, '\;') '\}'
476478
{%^ revert $ fmap (DoLet $1 $3 :) parseDoNext }
477-
| error
479+
| {- empty -}
478480
{%^ revert $ do
479-
stmt <- tryPrefix parseDoBinder parseDoExpr
481+
stmt <- tryPrefix parseBinderAndArrow parseDoExpr
480482
let
481483
ctr = case stmt of
482484
(Just (binder, sep), expr) ->
@@ -486,37 +488,33 @@ doStatement
486488
fmap ctr parseDoNext
487489
}
488490

489-
doBinder
490-
: binder '<-' {%^ revert $ pure ($1, $2) }
491-
492-
doExpr
491+
doExpr :: { Expr () }
493492
: expr {%^ revert $ pure $1 }
494493

495-
doNext
494+
doNext :: { [DoStatement ()] }
496495
: '\;' {%^ revert parseDoStatement }
497496
| '\}' {%^ revert $ pure [] }
498497

499498
guard :: { (SourceToken, Separated (PatternGuard ())) }
500-
: '|'
501-
{%% revert $ do
502-
(binder, expr) <- tryPrefix parseGuardBinder parseGuardExpr
503-
fmap (($1,) . Separated (PatternGuard binder expr)) parseGuardNext
504-
}
499+
: '|' {%% revert $ fmap (($1,) . uncurry Separated) parseGuardStatement }
505500

506-
guardBinder :: { (Binder (), SourceToken) }
507-
: binder '<-' {%^ revert $ pure ($1, $2) }
501+
guardStatement :: { (PatternGuard (), [(SourceToken, PatternGuard ())]) }
502+
: {- empty -}
503+
{%^ revert $ do
504+
grd <- fmap (uncurry PatternGuard) $ tryPrefix parseBinderAndArrow parseGuardExpr
505+
fmap (grd,) parseGuardNext
506+
}
508507

509508
guardExpr :: { Expr() }
510509
: expr0 {%^ revert $ pure $1 }
511510

512511
guardNext :: { [(SourceToken, PatternGuard ())] }
513-
: ','
514-
{%^ revert $ do
515-
(binder, expr) <- tryPrefix parseGuardBinder parseGuardExpr
516-
fmap (($1, PatternGuard binder expr) :) parseGuardNext
517-
}
512+
: ',' {%^ revert $ fmap (\(g, gs) -> ($1, g) : gs) parseGuardStatement }
518513
| {- empty -} {%^ revert $ pure [] }
519514

515+
binderAndArrow :: { (Binder (), SourceToken) }
516+
: binder '<-' {%^ revert $ pure ($1, $2) }
517+
520518
binder :: { Binder () }
521519
: binder0 { $1 }
522520
| binder0 '::' type { BinderTyped () $1 $2 $3 }

0 commit comments

Comments
 (0)