Skip to content

Commit 6f55286

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

File tree

3 files changed

+89
-15
lines changed

3 files changed

+89
-15
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: 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 (mkReduceFun n "")]
922920

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

0 commit comments

Comments
 (0)