Skip to content

Commit bf85aca

Browse files
committed
Move GenUtils out of happy-grammar
- Move mapDollarDollar to Grammar: the $$ feature is on grammar level - Move mkClosure into tabular as it is only used there
1 parent 61626b0 commit bf85aca

File tree

12 files changed

+60
-53
lines changed

12 files changed

+60
-53
lines changed

happy.cabal

+1
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ executable happy
169169
other-modules:
170170
Paths_happy
171171
AbsSyn
172+
GenUtils
172173
Lexer
173174
Mangler
174175
ParseMonad

packages/grammar/happy-grammar.cabal

+1-2
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ tested-with:
3535
library
3636
hs-source-dirs: src
3737

38-
exposed-modules: Happy.Grammar.Grammar,
39-
Happy.Grammar.GenUtils
38+
exposed-modules: Happy.Grammar.Grammar
4039
build-depends: base < 5,
4140
array
4241

packages/grammar/src/Happy/Grammar/Grammar.lhs

+26-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ The Grammar data type.
1212
> Assoc(..),
1313
>
1414
> errorName, errorTok, startName, dummyName, firstStartTok, dummyTok,
15-
> eofName, epsilonTok
15+
> eofName, epsilonTok,
16+
>
17+
> mapDollarDollar
1618
> ) where
1719

1820
> import Data.Array
21+
> import Data.Char (isAlphaNum)
1922

2023
> type Name = Int
2124

@@ -125,4 +128,25 @@ In hindsight, this was probably a bad idea.
125128
> firstStartTok = 3
126129
> dummyTok = 2
127130
> errorTok = 1
128-
> epsilonTok = 0
131+
> epsilonTok = 0
132+
133+
-----------------------------------------------------------------------------
134+
135+
Replace $$ with an arbitrary string, being careful to avoid ".." and '.'.
136+
137+
> mapDollarDollar :: String -> Maybe (String -> String)
138+
> mapDollarDollar code0 = go code0 ""
139+
> where go code acc =
140+
> case code of
141+
> [] -> Nothing
142+
>
143+
> '"' :r -> case reads code :: [(String,String)] of
144+
> [] -> go r ('"':acc)
145+
> (s,r'):_ -> go r' (reverse (show s) ++ acc)
146+
> a:'\'' :r | isAlphaNum a -> go r ('\'':a:acc)
147+
> '\'' :r -> case reads code :: [(Char,String)] of
148+
> [] -> go r ('\'':acc)
149+
> (c,r'):_ -> go r' (reverse (show c) ++ acc)
150+
> '\\':'$':r -> go r ('$':acc)
151+
> '$':'$':r -> Just (\repl -> reverse acc ++ repl ++ r)
152+
> c:r -> go r (c:acc)

packages/tabular/src/Happy/Tabular.hs

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ module Happy.Tabular(
55
) where
66

77
import Happy.Grammar.Grammar
8-
import Happy.Grammar.GenUtils
98
import Happy.Tabular.NameSet (NameSet)
109
import Happy.Tabular.Tables
1110
import Happy.Tabular.First
@@ -16,6 +15,7 @@ import Happy.Tabular.Info
1615
import Data.Set (Set)
1716
import Data.Array (Array)
1817
import System.IO
18+
import System.Exit
1919
import Control.Monad
2020

2121
-------- Pure tabular functions, may be called without creating TabularArgs --------
@@ -76,6 +76,9 @@ runTabular args g =
7676
writeInfoFile sets g action goto conflictArray (inFile args) (infoFile args) unused_rules unused_terminals
7777
reportConflicts g sr rr
7878
return (action, goto, items2, unused_rules)
79+
where
80+
optPrint b io = when b (putStr "\n---------------------\n" >> io)
81+
7982

8083
-------- Helpers --------
8184

@@ -103,6 +106,9 @@ reportConflicts g sr rr = case expect g of
103106
if rr /= 0
104107
then hPutStrLn stderr ("reduce/reduce conflicts: " ++ show rr)
105108
else return ()
109+
#if !MIN_VERSION_base(4,8,0)
110+
where die s = hPutStr stderr s >> exitWith (ExitFailure 1)
111+
#endif
106112

107113
type ItemSetWithGotos = (Set Lr0Item, [(Name,Int)])
108114
writeInfoFile :: [ItemSetWithGotos] -> Grammar -> ActionTable -> GotoTable -> Array Int (Int,Int) -> String -> Maybe String -> [Int] -> [String] -> IO ()

packages/tabular/src/Happy/Tabular/First.lhs

+12-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@ Implementation of FIRST
44
(c) 1993-2001 Andy Gill, Simon Marlow
55
-----------------------------------------------------------------------------
66

7-
> module Happy.Tabular.First ( mkFirst ) where
7+
> module Happy.Tabular.First ( mkFirst, mkClosure ) where
88

99
> import Happy.Tabular.NameSet ( NameSet )
1010
> import qualified Happy.Tabular.NameSet as Set
11-
> import Happy.Grammar.GenUtils
1211
> import Happy.Grammar.Grammar
1312
> import Data.IntSet (IntSet)
1413

@@ -21,6 +20,17 @@ Implementation of FIRST
2120
> | Set.member epsilonTok h = Set.delete epsilonTok h `Set.union` b
2221
> | otherwise = h
2322

23+
@mkClosure@ makes a closure, when given a comparison and iteration loop.
24+
Be careful, because if the functional always makes the object different,
25+
This will never terminate.
26+
27+
> mkClosure :: (a -> a -> Bool) -> (a -> a) -> a -> a
28+
> mkClosure eq f = match . iterate f
29+
> where
30+
> match (a:b:_) | a `eq` b = a
31+
> match (_:c) = match c
32+
> match [] = error "Can't happen: match []"
33+
2434
\subsection{Implementation of FIRST}
2535

2636
> mkFirst :: Grammar -> [Name] -> NameSet

packages/tabular/src/Happy/Tabular/Info.lhs

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ Generating info files.
77
> module Happy.Tabular.Info (genInfoFile) where
88

99
> import Happy.Grammar.Grammar
10-
> import Happy.Grammar.GenUtils ( str, interleave, interleave' )
1110
> import Happy.Tabular.Tables
1211
> import Happy.Tabular.LALR ( Lr0Item(..) )
1312
> import Paths_happy_tabular ( version )
@@ -224,3 +223,10 @@ Produce a file of parser information, useful for debugging the parser.
224223
> = str "-----------------------------------------------------------------------------\n"
225224
> . str s
226225
> . str "\n-----------------------------------------------------------------------------\n"
226+
227+
> str :: String -> String -> String
228+
> str = showString
229+
> interleave :: String -> [String -> String] -> String -> String
230+
> interleave s = foldr (\a b -> a . str s . b) id
231+
> interleave' :: String -> [String -> String] -> String -> String
232+
> interleave' s = foldr1 (\a b -> a . str s . b)

packages/tabular/src/Happy/Tabular/LALR.lhs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ Generation of LALR parsing tables.
1111
> Lr0Item(..), Lr1Item(..))
1212
> where
1313

14+
> import Happy.Tabular.First ( mkClosure )
1415
> import Happy.Tabular.NameSet ( NameSet )
1516
> import qualified Happy.Tabular.NameSet as NameSet
16-
> import Happy.Grammar.GenUtils
1717
> import Happy.Grammar.Grammar
1818
> import Happy.Tabular.Tables
1919
> import qualified Data.Set as Set hiding ( Set )

packages/grammar/src/Happy/Grammar/GenUtils.lhs renamed to src/GenUtils.lhs

+1-39
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@ This is realy just an extended prelude.
44
All the code below is understood to be in the public domain.
55
-----------------------------------------------------------------------------
66

7-
> module Happy.Grammar.GenUtils (
8-
> mkClosure,
7+
> module GenUtils (
98
> combinePairs,
10-
> mapDollarDollar,
119
> str, char, nl, brack, brack',
1210
> interleave, interleave',
1311
> strspace, maybestr,
@@ -16,28 +14,13 @@ All the code below is understood to be in the public domain.
1614
> getProgramName
1715
> ) where
1816

19-
> import Data.Char (isAlphaNum)
2017
> import Data.Ord (comparing)
2118
> import Data.List (sortBy, isSuffixOf)
2219
> import Control.Monad
2320
> import System.IO (stderr, hPutStr)
2421
> import System.Environment
2522
> import System.Exit (exitWith, ExitCode(..))
2623

27-
%------------------------------------------------------------------------------
28-
29-
@mkClosure@ makes a closure, when given a comparison and iteration loop.
30-
Be careful, because if the functional always makes the object different,
31-
This will never terminate.
32-
33-
> mkClosure :: (a -> a -> Bool) -> (a -> a) -> a -> a
34-
> mkClosure eq f = match . iterate f
35-
> where
36-
> match (a:b:_) | a `eq` b = a
37-
> match (_:c) = match c
38-
> match [] = error "Can't happen: match []"
39-
40-
4124
Gofer-like stuff:
4225

4326
> combinePairs :: (Ord a) => [(a,b)] -> [(a,[b])]
@@ -49,27 +32,6 @@ Gofer-like stuff:
4932
> combine (a:r) = a : combine r
5033
>
5134

52-
53-
Replace $$ with an arbitrary string, being careful to avoid ".." and '.'.
54-
55-
> mapDollarDollar :: String -> Maybe (String -> String)
56-
> mapDollarDollar code0 = go code0 ""
57-
> where go code acc =
58-
> case code of
59-
> [] -> Nothing
60-
>
61-
> '"' :r -> case reads code :: [(String,String)] of
62-
> [] -> go r ('"':acc)
63-
> (s,r'):_ -> go r' (reverse (show s) ++ acc)
64-
> a:'\'' :r | isAlphaNum a -> go r ('\'':a:acc)
65-
> '\'' :r -> case reads code :: [(Char,String)] of
66-
> [] -> go r ('\'':acc)
67-
> (c,r'):_ -> go r' (reverse (show c) ++ acc)
68-
> '\\':'$':r -> go r ('$':acc)
69-
> '$':'$':r -> Just (\repl -> reverse acc ++ repl ++ r)
70-
> c:r -> go r (c:acc)
71-
72-
7335
%-------------------------------------------------------------------------------
7436
Fast string-building functions.
7537

src/Main.lhs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Path settings auto-generated by Cabal:
1212
> import Paths_happy
1313

1414
> import ParseMonad.Class
15-
> import Happy.Grammar.GenUtils
15+
> import GenUtils
1616
> import Happy.Grammar.Grammar
1717
> import PrettyGrammar
1818
> import Parser

src/Mangler.lhs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Mangler converts AbsSyn to Grammar
99
> module Mangler (mangler) where
1010

1111
> import Happy.Grammar.Grammar
12-
> import Happy.Grammar.GenUtils
12+
> import GenUtils
1313
> import AbsSyn
1414
#ifdef HAPPY_BOOTSTRAP
1515
> import ParseMonad.Class

src/ProduceCode.lhs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The code generator.
1010
> import Data.Version ( showVersion )
1111
> import Happy.Grammar.Grammar
1212
> import Target ( Target(..) )
13-
> import Happy.Grammar.GenUtils ( mapDollarDollar, str, char, nl, strspace,
13+
> import GenUtils ( str, char, nl, strspace,
1414
> interleave, interleave', maybestr,
1515
> brack, brack' )
1616
> import Happy.Tabular.Tables

src/ProduceGLRCode.lhs

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ This module is designed as an extension to the Haskell parser generator Happy.
1515
> ) where
1616

1717
> import Paths_happy ( version )
18-
> import Happy.Grammar.GenUtils ( mapDollarDollar )
19-
> import Happy.Grammar.GenUtils ( str, char, nl, brack, brack', interleave, maybestr )
18+
> import GenUtils ( str, char, nl, brack, brack', interleave, maybestr )
2019
> import Happy.Grammar.Grammar
2120
> import Data.Array ( Array, (!), array, assocs )
2221
> import Data.Char ( isSpace, isAlphaNum )

0 commit comments

Comments
 (0)