{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module BNFC.Backend.Haskell.CFtoHappy (cf2Happy, convert) where
import Prelude hiding ((<>))
import Data.Foldable (toList)
import Data.List (intersperse)
import BNFC.CF
import BNFC.Backend.Common.StrUtils (escapeChars)
import BNFC.Backend.Haskell.Utils
import BNFC.Options (HappyMode(..), TokenText(..))
import BNFC.PrettyPrint
import BNFC.Utils
type Rules = [(NonTerminal,[(Pattern,Action)])]
type Pattern = String
type Action = String
type MetaVar = String
tokenName :: String
tokenName = String
"Token"
cf2Happy
:: ModuleName
-> ModuleName
-> ModuleName
-> HappyMode
-> TokenText
-> Bool
-> CF
-> String
cf2Happy :: String
-> String
-> String
-> HappyMode
-> TokenText
-> Bool
-> CF
-> String
cf2Happy String
name String
absName String
lexName HappyMode
mode TokenText
tokenText Bool
functor CF
cf = [String] -> String
unlines
[ String -> String -> String -> TokenText -> [Cat] -> String
header String
name String
absName String
lexName TokenText
tokenText [Cat]
eps
, Doc -> String
render (Doc -> String) -> Doc -> String
forall a b. (a -> b) -> a -> b
$ HappyMode -> Bool -> [Cat] -> Doc
declarations HappyMode
mode Bool
functor [Cat]
eps
, Doc -> String
render (Doc -> String) -> Doc -> String
forall a b. (a -> b) -> a -> b
$ CF -> Bool -> Doc
tokens CF
cf Bool
functor
, String
delimiter
, String -> Bool -> TokenText -> CF -> String
specialRules String
absName Bool
functor TokenText
tokenText CF
cf
, Doc -> String
render (Doc -> String) -> Doc -> String
forall a b. (a -> b) -> a -> b
$ String -> Bool -> Rules -> Doc
prRules String
absName Bool
functor (String -> Bool -> CF -> Rules
rulesForHappy String
absName Bool
functor CF
cf)
, String -> TokenText -> Bool -> [Cat] -> CF -> String
footer String
absName TokenText
tokenText Bool
functor [Cat]
eps CF
cf
]
where
eps :: [Cat]
eps = NonEmpty Cat -> [Cat]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (NonEmpty Cat -> [Cat]) -> NonEmpty Cat -> [Cat]
forall a b. (a -> b) -> a -> b
$ CF -> NonEmpty Cat
forall f. CFG f -> NonEmpty Cat
allEntryPoints CF
cf
header :: ModuleName -> ModuleName -> ModuleName -> TokenText -> [Cat] -> String
String
modName String
absName String
lexName TokenText
tokenText [Cat]
eps = [String] -> String
unlines ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ [[String]] -> [String]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ String
"-- This Happy file was machine-generated by the BNF converter"
, String
"{"
, String
"{-# OPTIONS_GHC -fno-warn-incomplete-patterns -fno-warn-overlapping-patterns #-}"
, String
"module " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
modName
, String
" ( happyError"
, String
" , myLexer"
]
, (Cat -> String) -> [Cat] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ((String
" , " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Cat -> String) -> Cat -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc -> String
render (Doc -> String) -> (Cat -> Doc) -> Cat -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Cat -> Doc
parserName) [Cat]
eps
, [ String
" ) where"
, String
""
, String
"import Prelude"
, String
""
, String
"import qualified " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
absName
, String
"import " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
lexName
]
, TokenText -> [String]
tokenTextImport TokenText
tokenText
, [ String
""
, String
"}"
]
]
declarations :: HappyMode -> Bool -> [Cat] -> Doc
declarations :: HappyMode -> Bool -> [Cat] -> Doc
declarations HappyMode
mode Bool
functor [Cat]
ns = [Doc] -> Doc
vcat
[ [Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ (Cat -> Doc) -> [Cat] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map Cat -> Doc
generateP [Cat]
ns
, case HappyMode
mode of
HappyMode
Standard -> Doc
"-- no lexer declaration"
HappyMode
GLR -> Doc
"%lexer { myLexer } { Err _ }",
Doc
"%monad { Err } { (>>=) } { return }",
Doc
"%tokentype" Doc -> Doc -> Doc
<+> Doc -> Doc
braces (String -> Doc
text String
tokenName)
]
where
generateP :: Cat -> Doc
generateP Cat
n = Doc
"%name" Doc -> Doc -> Doc
<+> Cat -> Doc
parserName Cat
n Doc -> Doc -> Doc
<> (if Bool
functor then Doc
"_internal" else Doc
"") Doc -> Doc -> Doc
<+> String -> Doc
text (Cat -> String
identCat Cat
n)
delimiter :: String
delimiter :: String
delimiter = String
"\n%%\n"
tokens :: CF -> Bool -> Doc
tokens :: CF -> Bool -> Doc
tokens CF
cf Bool
functor
| [Doc] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Doc]
ts = Doc
empty
| Bool
otherwise = Doc
"%token" Doc -> Doc -> Doc
$$ (Int -> Doc -> Doc
nest Int
2 (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [Doc] -> Doc
vcat [Doc]
ts)
where
ts :: [Doc]
ts = ((String, Int) -> Doc) -> [(String, Int)] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (String, Int) -> Doc
forall {a}. Show a => (String, a) -> Doc
prToken (CF -> [(String, Int)]
forall f. CFG f -> [(String, Int)]
cfTokens CF
cf) [Doc] -> [Doc] -> [Doc]
forall a. [a] -> [a] -> [a]
++ (String -> Doc) -> [String] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map String -> Doc
text (CF -> Bool -> [String]
specialToks CF
cf Bool
functor)
prToken :: (String, a) -> Doc
prToken (String
t,a
k) = [Doc] -> Doc
hsep [ String -> Doc
convert String
t, Doc
lbrace, String -> Doc
text (String
"PT _ (TS _ " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
k String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"), Doc
rbrace ]
convert :: String -> Doc
convert :: String -> Doc
convert = Doc -> Doc
quotes (Doc -> Doc) -> (String -> Doc) -> String -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Doc
text (String -> Doc) -> (String -> String) -> String -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
escapeChars
rulesForHappy :: ModuleName -> Bool -> CF -> Rules
rulesForHappy :: String -> Bool -> CF -> Rules
rulesForHappy String
absM Bool
functor CF
cf = [(Cat, [Rule])]
-> ((Cat, [Rule]) -> (Cat, [(String, String)])) -> Rules
forall a b. [a] -> (a -> b) -> [b]
for (CF -> [(Cat, [Rule])]
ruleGroups CF
cf) (((Cat, [Rule]) -> (Cat, [(String, String)])) -> Rules)
-> ((Cat, [Rule]) -> (Cat, [(String, String)])) -> Rules
forall a b. (a -> b) -> a -> b
$ \ (Cat
cat, [Rule]
rules) ->
(Cat
cat, (Rule -> (String, String)) -> [Rule] -> [(String, String)]
forall a b. (a -> b) -> [a] -> [b]
map (String -> Bool -> Rule -> (String, String)
forall f. IsFun f => String -> Bool -> Rul f -> (String, String)
constructRule String
absM Bool
functor) [Rule]
rules)
constructRule :: IsFun f => String -> Bool -> Rul f -> (Pattern, Action)
constructRule :: forall f. IsFun f => String -> Bool -> Rul f -> (String, String)
constructRule String
absName Bool
functor (Rule f
fun0 RCat
_cat SentForm
rhs InternalRule
Parsable) = (String
pat, String
action)
where
fun :: String
fun = f -> String
forall a. IsFun a => a -> String
funName f
fun0
(String
pat, [String]
metavars) = Bool -> SentForm -> (String, [String])
generatePatterns Bool
functor SentForm
rhs
action :: String
action
| Bool
functor = String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (String -> String) -> String
actionPos String -> String
forall a. a -> a
id String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
actionValue String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
| Bool
otherwise = String
actionValue
actionPos :: (String -> String) -> String
actionPos String -> String
paren = case SentForm
rhs of
[] -> String -> String
qualify String
forall a. IsString a => a
noPosConstr
(Left Cat
_:SentForm
_) -> String -> String
paren String
"fst $1"
(Right String
_:SentForm
_) -> String -> String
paren (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords [ String
"uncurry", String -> String
qualify String
forall a. IsString a => a
posConstr , String
"(tokenLineCol $1)" ]
actionValue :: String
actionValue
| String -> Bool
forall a. IsFun a => a -> Bool
isCoercion String
fun = [String] -> String
unwords [String]
metavars
| String -> Bool
forall a. IsFun a => a -> Bool
isNilCons String
fun = [String] -> String
unwords (String -> String
qualify String
fun String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
metavars)
| Bool
functor = [String] -> String
unwords (String -> String
qualify String
fun String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (String -> String) -> String
actionPos (\ String
x -> String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")") String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
metavars)
| Bool
otherwise = [String] -> String
unwords (String -> String
qualify String
fun String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
metavars)
qualify :: String -> String
qualify String
f
| String -> Bool
forall a. IsFun a => a -> Bool
isConsFun String
f Bool -> Bool -> Bool
|| String -> Bool
forall a. IsFun a => a -> Bool
isNilCons String
f = String
f
| String -> Bool
forall a. IsFun a => a -> Bool
isDefinedRule String
f = String
absName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"." String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. IsFun a => a -> String
mkDefName String
f
| Bool
otherwise = String
absName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"." String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
f
constructRule String
_ Bool
_ (Rule f
_ RCat
_ SentForm
_ InternalRule
Internal) = (String, String)
forall a. HasCallStack => a
undefined
generatePatterns :: Bool -> SentForm -> (Pattern, [MetaVar])
generatePatterns :: Bool -> SentForm -> (String, [String])
generatePatterns Bool
_ [] = (String
"{- empty -}", [])
generatePatterns Bool
functor SentForm
its =
( [String] -> String
unwords ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ SentForm -> (Either Cat String -> String) -> [String]
forall a b. [a] -> (a -> b) -> [b]
for SentForm
its ((Either Cat String -> String) -> [String])
-> (Either Cat String -> String) -> [String]
forall a b. (a -> b) -> a -> b
$ (Cat -> String)
-> (String -> String) -> Either Cat String -> String
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Cat -> String
identCat (Doc -> String
render (Doc -> String) -> (String -> Doc) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Doc
convert)
, [ if Bool
functor then String
"(snd $" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")" else (Char
'$' Char -> String -> String
forall a. a -> [a] -> [a]
: Int -> String
forall a. Show a => a -> String
show Int
i) | (Int
i, Left{}) <- [Int] -> SentForm -> [(Int, Either Cat String)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
1 :: Int ..] SentForm
its ]
)
prRules :: ModuleName -> Bool -> Rules -> Doc
prRules :: String -> Bool -> Rules -> Doc
prRules String
absM Bool
functor = [Doc] -> Doc
vsep ([Doc] -> Doc) -> (Rules -> [Doc]) -> Rules -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Cat, [(String, String)]) -> Doc) -> Rules -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (Cat, [(String, String)]) -> Doc
prOne
where
prOne :: (Cat, [(String, String)]) -> Doc
prOne (Cat
_ , [] ) = Doc
empty
prOne (Cat
nt, (String
p,String
a):[(String, String)]
ls) =
[Doc] -> Doc
hsep [ Doc
nt', Doc
"::", Doc
"{", if Bool
functor then Cat -> Doc
functorType' Cat
nt else Cat -> Doc
type' Cat
nt, Doc
"}" ]
Doc -> Doc -> Doc
$$ Doc
nt' Doc -> Doc -> Doc
<+> [Doc] -> Doc
sep (Doc -> (String, String) -> Doc
pr Doc
":" (String
p, String
a) Doc -> [Doc] -> [Doc]
forall a. a -> [a] -> [a]
: ((String, String) -> Doc) -> [(String, String)] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (Doc -> (String, String) -> Doc
pr Doc
"|") [(String, String)]
ls)
where
nt' :: Doc
nt' = String -> Doc
text (Cat -> String
identCat Cat
nt)
pr :: Doc -> (String, String) -> Doc
pr Doc
pre (String
p,String
a) = [Doc] -> Doc
hsep [Doc
pre, String -> Doc
text String
p, Doc
"{", String -> Doc
text String
a , Doc
"}"]
type' :: Cat -> Doc
type' = (Doc -> Doc) -> Doc -> Cat -> Doc
catToType Doc -> Doc
qualify Doc
empty
functorType' :: Cat -> Doc
functorType' Cat
nt = [Doc] -> Doc
hcat [Doc
"(", Doc -> Doc
qualify Doc
forall a. IsString a => a
posType, Doc
", ", Cat -> Doc
type' Cat
nt, Doc
")"]
qualify :: Doc -> Doc
qualify
| String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
absM = Doc -> Doc
forall a. a -> a
id
| Bool
otherwise = ((String -> Doc
text String
absM Doc -> Doc -> Doc
<> Doc
".") Doc -> Doc -> Doc
<>)
footer :: ModuleName -> TokenText -> Bool -> [Cat] -> CF -> String
String
absName TokenText
tokenText Bool
functor [Cat]
eps CF
cf = [String] -> String
unlines ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ [[String]] -> [String]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ String
"{"
, String
""
, String
"type Err = Either String"
, String
""
, String
"happyError :: [" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
tokenName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"] -> Err a"
, String
"happyError ts = Left $"
, String
" \"syntax error at \" ++ tokenPos ts ++ "
, String
" case ts of"
, String
" [] -> []"
, String
" [Err _] -> \" due to lexer error\""
, [String] -> String
unwords
[ String
" t:_ -> \" before `\" ++"
, String
"(prToken t)"
, String
"++ \"'\""
]
, String
""
, String
"myLexer :: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ TokenText -> String
tokenTextType TokenText
tokenText String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" -> [" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
tokenName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"]"
, String
"myLexer = tokens"
, String
""
]
, Bool -> [String] -> [String]
forall m. Monoid m => Bool -> m -> m
when Bool
functor
[ String
"-- Entrypoints"
, String
""
, Doc -> String
render (Doc -> String) -> ([Doc] -> Doc) -> [Doc] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Doc] -> Doc
vsep ([Doc] -> String) -> [Doc] -> String
forall a b. (a -> b) -> a -> b
$ (Cat -> Doc) -> [Cat] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map Cat -> Doc
mkParserFun [Cat]
eps
]
, [ String
"}" ]
]
where
mkParserFun :: Cat -> Doc
mkParserFun Cat
cat = [Doc] -> Doc
vcat
[ Cat -> Doc
parserName Cat
cat Doc -> Doc -> Doc
<+> Doc
"::" Doc -> Doc -> Doc
<+> Doc -> Doc
brackets (String -> Doc
text String
tokenName) Doc -> Doc -> Doc
<+> Doc
"-> Err" Doc -> Doc -> Doc
<+> (Doc -> Doc) -> Doc -> Cat -> Doc
catToType Doc -> Doc
qualify Doc
empty Cat
cat
, Cat -> Doc
parserName Cat
cat Doc -> Doc -> Doc
<+> Doc
"=" Doc -> Doc -> Doc
<+> Doc
"fmap snd" Doc -> Doc -> Doc
<+> Doc
"." Doc -> Doc -> Doc
<+> Cat -> Doc
parserName Cat
cat Doc -> Doc -> Doc
<> Doc
"_internal"
]
qualify :: Doc -> Doc
qualify
| String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
absName = Doc -> Doc
forall a. a -> a
id
| Bool
otherwise = ((String -> Doc
text String
absName Doc -> Doc -> Doc
<> Doc
".") Doc -> Doc -> Doc
<>)
specialToks :: CF -> Bool -> [String]
specialToks :: CF -> Bool -> [String]
specialToks CF
cf Bool
functor = ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
`map` CF -> [String]
forall f. CFG f -> [String]
literals CF
cf) ((String -> String) -> [String]) -> (String -> String) -> [String]
forall a b. (a -> b) -> a -> b
$ \String
t -> case String
t of
String
"Ident" -> String
"L_Ident { PT _ (TV " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall {p}. IsString p => String -> p
posn String
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") }"
String
"String" -> String
"L_quoted { PT _ (TL " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall {p}. IsString p => String -> p
posn String
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") }"
String
"Integer" -> String
"L_integ { PT _ (TI " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall {p}. IsString p => String -> p
posn String
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") }"
String
"Double" -> String
"L_doubl { PT _ (TD " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall {p}. IsString p => String -> p
posn String
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") }"
String
"Char" -> String
"L_charac { PT _ (TC " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall {p}. IsString p => String -> p
posn String
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") }"
String
own -> String
"L_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
own String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" { PT _ (T_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
own String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall {p}. IsString p => String -> p
posn String
own String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") }"
where
posn :: String -> p
posn String
tokenCat = if CF -> String -> Bool
forall f. CFG f -> String -> Bool
isPositionCat CF
cf String
tokenCat Bool -> Bool -> Bool
|| Bool
functor then p
"_" else p
"$$"
specialRules :: ModuleName -> Bool -> TokenText -> CF -> String
specialRules :: String -> Bool -> TokenText -> CF -> String
specialRules String
absName Bool
functor TokenText
tokenText CF
cf = [String] -> String
unlines ([String] -> String)
-> ((String -> String) -> [String]) -> (String -> String) -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> [String]
forall a. a -> [a] -> [a]
intersperse String
"" ([String] -> [String])
-> ((String -> String) -> [String])
-> (String -> String)
-> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
`map` CF -> [String]
forall f. CFG f -> [String]
literals CF
cf) ((String -> String) -> String) -> (String -> String) -> String
forall a b. (a -> b) -> a -> b
$ \String
t -> case String
t of
String
"String" -> String
"String :: { " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
mkTypePart String
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" }"
String -> String -> String
++++ String
"String : L_quoted { " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
mkBodyPart String
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" }"
String
"Integer" -> String
"Integer :: { " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
mkTypePart String
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" }"
String -> String -> String
++++ String
"Integer : L_integ { " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
mkBodyPart String
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" }"
String
"Double" -> String
"Double :: { " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
mkTypePart String
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" }"
String -> String -> String
++++ String
"Double : L_doubl { " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
mkBodyPart String
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" }"
String
"Char" -> String
"Char :: { " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
mkTypePart String
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" }"
String -> String -> String
++++ String
"Char : L_charac { " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
mkBodyPart String
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" }"
String
own -> String
own String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" :: { " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
mkTypePart (String -> String
qualify String
own) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" }"
String -> String -> String
++++ String
own String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" : L_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
own String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" { " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
mkBodyPart String
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" }"
where
mkTypePart :: String -> String
mkTypePart String
tokenCat = if Bool
functor then [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ String
"(", String -> String
qualify String
forall a. IsString a => a
posType, String
", ", String
tokenCat, String
")" ] else String
tokenCat
mkBodyPart :: String -> String
mkBodyPart String
tokenCat
| Bool
functor = String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [String] -> String
unwords [String
"uncurry", String -> String
qualify String
forall a. IsString a => a
posConstr, String
"(tokenLineCol $1)"] String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
mkValPart String
tokenCat String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
| Bool
otherwise = String -> String
mkValPart String
tokenCat
mkValPart :: String -> String
mkValPart String
tokenCat =
case String
tokenCat of
String
"String" -> if Bool
functor then String -> String
stringUnpack String
"((\\(PT _ (TL s)) -> s) $1)"
else String -> String
stringUnpack String
"$1"
String
"Integer" -> if Bool
functor then String
"(read " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
stringUnpack String
"(tokenText $1)" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") :: Integer"
else String
"(read " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
stringUnpack String
"$1" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") :: Integer"
String
"Double" -> if Bool
functor then String
"(read " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
stringUnpack String
"(tokenText $1)" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") :: Double"
else String
"(read " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
stringUnpack String
"$1" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") :: Double"
String
"Char" -> if Bool
functor then String
"(read " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
stringUnpack String
"(tokenText $1)" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") :: Char"
else String
"(read " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
stringUnpack String
"$1" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") :: Char"
String
own ->
case Bool
functor of
Bool
False ->
case CF -> String -> Bool
forall f. CFG f -> String -> Bool
isPositionCat CF
cf String
tokenCat of
Bool
False -> String -> String
qualify String
own String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" $1"
Bool
True -> String -> String
qualify String
own String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" (mkPosToken $1)"
Bool
True ->
case CF -> String -> Bool
forall f. CFG f -> String -> Bool
isPositionCat CF
cf String
tokenCat of
Bool
False -> String -> String
qualify String
own String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" (tokenText $1)"
Bool
True -> String -> String
qualify String
own String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" (mkPosToken $1)"
stringUnpack :: String -> String
stringUnpack = TokenText -> String -> String
tokenTextUnpack TokenText
tokenText
qualify :: String -> String
qualify
| String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
absName = String -> String
forall a. a -> a
id
| Bool
otherwise = ((String
absName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".") String -> String -> String
forall a. [a] -> [a] -> [a]
++)