Skip to content

Commit 6ab57ab

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

File tree

3 files changed

+108
-17
lines changed

3 files changed

+108
-17
lines changed

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

Lines changed: 5 additions & 3 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
53-
default-extensions: CPP, MagicHash, FlexibleContexts
55+
default-extensions: CPP, MagicHash, FlexibleContexts, GeneralizedNewtypeDeriving
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: 21 additions & 14 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,9 +577,18 @@ machinery to discard states in the parser...
576577
>
577578
> produceActionTable TargetArrayBased
578579
> = produceActionArray
579-
> . produceReduceArray
580-
> . str "happy_n_terms = " . shows n_terminals . str " :: Prelude.Int\n"
581-
> . str "happy_n_nonterms = " . shows n_nonterminals . str " :: Prelude.Int\n\n"
580+
> . renderDocDecs [
581+
> [produceReduceArray],
582+
> [
583+
> sigD "happy_n_terms" (varE "Prelude.Int"),
584+
> varBind "happy_n_terms" (intE n_terminals)
585+
> ],
586+
> [
587+
> sigD "happy_n_nonterms" (varE "Prelude.Int"),
588+
> varBind "happy_n_nonterms" (intE n_nonterminals)
589+
> ]
590+
> ]
591+
> . nl
582592
>
583593
> produceExpListPerState
584594
> = produceExpListArray
@@ -744,15 +754,13 @@ action array indexed by (terminal * last_state) + state
744754
>
745755
> table_size = length table - 1
746756
>
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"
757+
> produceReduceArray =
758+
> {- str "happyReduceArr :: Array Int a\n" -}
759+
> varBind "happyReduceArr" $
760+
> varE "Happy_Data_Array.array"
761+
> `appE` tupE [intE n_starts, -- omit the %start reductions
762+
> intE n_rules]
763+
> `appE` listE (map reduceArrElem [n_starts..n_rules])
756764

757765
> n_rules = length prods - 1 :: Int
758766

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

919927
> reduceArrElem n
920-
> = str "\t(" . shows n . str " , "
921-
> . str "happyReduce_" . shows n . char ')'
928+
> = tupE [intE n, varE (mkReduceFun n "")]
922929

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

0 commit comments

Comments
 (0)