Skip to content

Commit 6398739

Browse files
committed
SyntaxLib: init, produceReduceArray
1 parent 4f4a011 commit 6398739

File tree

3 files changed

+90
-14
lines changed

3 files changed

+90
-14
lines changed

packages/backend-lalr/happy-backend-lalr.cabal

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@ library
4343

4444
exposed-modules: Happy.Backend.LALR,
4545
Happy.Backend.LALR.Target,
46-
Happy.Backend.LALR.ProduceCode
46+
Happy.Backend.LALR.ProduceCode,
47+
Happy.Backend.LALR.SyntaxLib
4748
build-depends: base < 5,
4849
array,
50+
pretty,
4951
happy-grammar == 1.21.0,
5052
happy-tabular == 1.21.0
5153

5254
default-language: Haskell98
5355
default-extensions: CPP, MagicHash, FlexibleContexts
5456
ghc-options: -Wall
55-
other-modules: Paths_happy_backend_lalr
57+
other-modules: Paths_happy_backend_lalr

packages/backend-lalr/src/Happy/Backend/LALR/ProduceCode.lhs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The code generator.
1111
> import Happy.Grammar
1212
> import Happy.Backend.LALR.Target ( Target(..) )
1313
> import Happy.Tabular.LALR
14+
> import Happy.Backend.LALR.SyntaxLib
1415

1516
> import Data.Maybe ( isJust, isNothing, fromMaybe )
1617
> import Data.Char ( ord, chr )
@@ -576,7 +577,7 @@ machinery to discard states in the parser...
576577
>
577578
> produceActionTable TargetArrayBased
578579
> = produceActionArray
579-
> . produceReduceArray
580+
> . renderDocDec produceReduceArray
580581
> . str "happy_n_terms = " . shows n_terminals . str " :: Prelude.Int\n"
581582
> . str "happy_n_nonterms = " . shows n_nonterminals . str " :: Prelude.Int\n\n"
582583
>
@@ -744,15 +745,13 @@ action array indexed by (terminal * last_state) + state
744745
>
745746
> table_size = length table - 1
746747
>
747-
> produceReduceArray
748-
> = {- str "happyReduceArr :: Array Int a\n" -}
749-
> str "happyReduceArr = Happy_Data_Array.array ("
750-
> . shows (n_starts :: Int) -- omit the %start reductions
751-
> . str ", "
752-
> . shows n_rules
753-
> . str ") [\n"
754-
> . interleave' ",\n" (map reduceArrElem [n_starts..n_rules])
755-
> . str "\n\t]\n\n"
748+
> produceReduceArray =
749+
> {- str "happyReduceArr :: Array Int a\n" -}
750+
> varBind "happyReduceArr" $
751+
> varE "Happy_Data_Array.array"
752+
> `appE` tupE [intE n_starts, -- omit the %start reductions
753+
> intE n_rules]
754+
> `appE` listE (map reduceArrElem [n_starts..n_rules])
756755

757756
> n_rules = length prods - 1 :: Int
758757

@@ -917,8 +916,7 @@ directive determins the API of the provided function.
917916
> Just _ -> str "(\\(tokens, explist) -> happyError)"
918917

919918
> reduceArrElem n
920-
> = str "\t(" . shows n . str " , "
921-
> . str "happyReduce_" . shows n . char ')'
919+
> = tupE [intE n, varE ("happyReduce_" ++ show n)]
922920

923921
-----------------------------------------------------------------------------
924922
-- Produce the parser entry and exit points
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
2+
3+
module Happy.Backend.LALR.SyntaxLib (
4+
DocExp,
5+
varE,
6+
intE,
7+
appE,
8+
tupE,
9+
listE,
10+
varBind,
11+
-- DocStmt,
12+
DocDec,
13+
renderDocDec
14+
) where
15+
16+
import qualified Text.PrettyPrint as PP
17+
18+
newtype Prec = Prec Int
19+
deriving (Eq, Ord, Num, Bounded)
20+
21+
atomPrec, appPrec, noPrec :: Prec
22+
atomPrec = maxBound
23+
appPrec = 10
24+
noPrec = (-1)
25+
26+
type StringBuilder = String -> String
27+
28+
fromTextDetails :: PP.TextDetails -> StringBuilder
29+
fromTextDetails td =
30+
case td of
31+
PP.Chr c -> (c:)
32+
PP.Str str -> (str++)
33+
PP.PStr str -> (str++)
34+
35+
renderDocDec :: DocDec -> StringBuilder
36+
renderDocDec (DocDec d) =
37+
PP.fullRender PP.PageMode 80 1.5 (\td s -> fromTextDetails td . s) id d
38+
. (\s -> '\n' : '\n' : s)
39+
40+
newtype DocExp = DocExp (Prec -> PP.Doc)
41+
42+
-- newtype DocStmt = DocStmt Doc
43+
44+
newtype DocDec = DocDec PP.Doc
45+
46+
varE :: String -> DocExp
47+
varE str = DocExp (\_ -> PP.text str)
48+
49+
intE :: Int -> DocExp
50+
intE n = DocExp (\_ -> parensIf (n < 0) (PP.int n))
51+
52+
appE :: DocExp -> DocExp -> DocExp
53+
appE (DocExp e1) (DocExp e2) =
54+
DocExp $ \p -> parensIf (p > appPrec) $
55+
PP.sep [e1 appPrec, e2 atomPrec]
56+
57+
tupE :: [DocExp] -> DocExp
58+
tupE ds =
59+
DocExp $ \_ ->
60+
PP.parens $ PP.sep $ PP.punctuate PP.comma $
61+
[d noPrec | DocExp d <- ds]
62+
63+
listE :: [DocExp] -> DocExp
64+
listE ds =
65+
DocExp $ \_ ->
66+
PP.brackets $ PP.sep $ PP.punctuate PP.comma $
67+
[d noPrec | DocExp d <- ds]
68+
69+
varBind :: String -> DocExp -> DocDec
70+
varBind lhs (DocExp rhs) =
71+
DocDec $
72+
PP.hang (PP.text lhs PP.<+> PP.text "=") 2 (rhs noPrec)
73+
74+
parensIf :: Bool -> PP.Doc -> PP.Doc
75+
parensIf True = PP.parens
76+
parensIf False = id

0 commit comments

Comments
 (0)