@@ -12,11 +12,13 @@ The Grammar data type.
12
12
> Assoc (.. ),
13
13
>
14
14
> errorName , errorTok , startName , dummyName , firstStartTok , dummyTok ,
15
- > eofName , epsilonTok
15
+ > eofName , epsilonTok ,
16
+ >
17
+ > mapDollarDollar
16
18
> ) where
17
19
18
20
> import Data.Array
19
-
21
+ > import Data.Char ( isAlphaNum )
20
22
> type Name = Int
21
23
22
24
> data ErrorHandlerType
@@ -103,6 +105,9 @@ non-terminals = s..n
103
105
terminals = n..m
104
106
% eof = m
105
107
108
+ where n_nonterminals = n - 3 (including % starts)
109
+ n_terminals = 1{-error-} + (m-n) + 1{-eof-} (including error and % eof)
110
+
106
111
These numbers are deeply magical, change at your own risk. Several
107
112
other places rely on these being arranged as they are, including
108
113
ProduceCode.lhs and the various HappyTemplates.
@@ -113,6 +118,10 @@ namespace, which are kept in the Grammar structure.
113
118
114
119
In hindsight, this was probably a bad idea.
115
120
121
+ In normal and GHC-based parsers, these numbers are also used in the
122
+ generated grammar itself, except that the error token is mapped to -1.
123
+ For array-based parsers, see the note in Tabular/LALR.lhs.
124
+
116
125
> startName , eofName , errorName , dummyName :: String
117
126
> startName = " %start" -- with a suffix, like %start_1, %start_2 etc.
118
127
> eofName = " %eof"
@@ -123,4 +132,24 @@ In hindsight, this was probably a bad idea.
123
132
> firstStartTok = 3
124
133
> dummyTok = 2
125
134
> errorTok = 1
126
- > epsilonTok = 0
135
+ > epsilonTok = 0
136
+
137
+ -----------------------------------------------------------------------------
138
+ Replace $$ with an arbitrary string, being careful to avoid ".." and '.'.
139
+
140
+ > mapDollarDollar :: String -> Maybe (String -> String)
141
+ > mapDollarDollar code0 = go code0 ""
142
+ > where go code acc =
143
+ > case code of
144
+ > [] -> Nothing
145
+ >
146
+ > '"' :r -> case reads code :: [(String,String)] of
147
+ > [] -> go r ('"':acc)
148
+ > (s,r'):_ -> go r' (reverse (show s) ++ acc)
149
+ > a:'\' ' :r | isAlphaNum a -> go r ('\' ':a:acc)
150
+ > '\' ' :r -> case reads code :: [(Char,String)] of
151
+ > [] -> go r ('\' ':acc)
152
+ > (c,r'):_ -> go r' (reverse (show c) ++ acc)
153
+ > '\\ ':'$ ':r -> go r ('$ ':acc)
154
+ > '$ ':'$ ':r -> Just (\repl -> reverse acc ++ repl ++ r)
155
+ > c:r -> go r (c:acc)
0 commit comments