{-
    BNF Converter: Latex Generator
    Copyright (C) 2004  Author:  Markus Forsberg, Aarne Ranta

-}

module BNFC.Backend.Txt2Tag (cfToTxt)where

import BNFC.CF
import BNFC.Abs (Reg (..))
import BNFC.Utils
import Data.List

cfToTxt :: String -> CF -> String
cfToTxt :: [Char] -> CF -> [Char]
cfToTxt [Char]
name CF
cf = [[Char]] -> [Char]
unlines [
                            [Char] -> [Char]
beginDocument [Char]
name,
                            [Char]
introduction,
                            [Char] -> CF -> [Char]
prtTerminals [Char]
name CF
cf,
                            [Char] -> CF -> [Char]
prtBNF [Char]
name CF
cf
                            ]

introduction :: String
introduction :: [Char]
introduction = [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
               [
               [Char]
"\nThis document was automatically generated by ",
               [Char]
"the //BNF-Converter//.",
               [Char]
" It was generated together with the lexer, the parser, and the",
               [Char]
" abstract syntax module, which guarantees that the document",
               [Char]
" matches with the implementation of the language (provided no",
               [Char]
" hand-hacking has taken place).\n"
               ]

prtTerminals :: String -> CF -> String
prtTerminals :: [Char] -> CF -> [Char]
prtTerminals [Char]
name CF
cf = [[Char]] -> [Char]
unlines ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$
  [ [Char]
"==The lexical structure of " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"=="
  , CF -> [Char]
forall {f}. CFG f -> [Char]
identSection CF
cf
  , [Char]
"===Literals==="
  , CF -> [Char]
prtLiterals CF
cf
  , [[Char]] -> [Char]
unlines ((([Char], Reg) -> [Char]) -> [([Char], Reg)] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char], Reg) -> [Char]
prtOwnToken (CF -> [([Char], Reg)]
forall f. CFG f -> [([Char], Reg)]
tokenPragmas CF
cf))
  , [Char]
"===Reserved words and symbols==="
  , [Char] -> CF -> [Char]
prtReserved [Char]
name CF
cf
  , [Char] -> CF -> [Char]
prtSymb [Char]
name CF
cf
  , [Char]
"===Comments==="
  , ([([Char], [Char])], [[Char]]) -> [Char]
prtComments (([([Char], [Char])], [[Char]]) -> [Char])
-> ([([Char], [Char])], [[Char]]) -> [Char]
forall a b. (a -> b) -> a -> b
$ CF -> ([([Char], [Char])], [[Char]])
comments CF
cf
  ]

identSection :: CFG f -> [Char]
identSection CFG f
cf = if Bool -> Bool
not (CFG f -> Bool
forall f. CFG f -> Bool
hasIdent CFG f
cf) then [] else
                    [[Char]] -> [Char]
unlines [
                               [Char]
"===Identifiers===",
                               [Char]
prtIdentifiers
                          ]

prtIdentifiers :: String
prtIdentifiers :: [Char]
prtIdentifiers = [[Char]] -> [Char]
unlines
  [
   [Char]
"Identifiers //Ident// are unquoted strings beginning with a letter,",
   [Char]
"followed by any combination of letters, digits, and the characters ``_ '``",
   [Char]
"reserved words excluded."
  ]

prtLiterals :: CF -> String
prtLiterals :: CF -> [Char]
prtLiterals CF
cf =
  [[Char]] -> [Char]
unlines ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ ([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> [Char]
stringLit ([[Char]] -> [[Char]]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> a -> b
$
    ([Char] -> Bool) -> [[Char]] -> [[Char]]
forall a. (a -> Bool) -> [a] -> [a]
filter ([Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
/= [Char]
catIdent) ([[Char]] -> [[Char]]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> a -> b
$ CF -> [[Char]]
forall f. CFG f -> [[Char]]
literals CF
cf

stringLit :: TokenCat -> String
stringLit :: [Char] -> [Char]
stringLit = [[Char]] -> [Char]
unlines ([[Char]] -> [Char]) -> ([Char] -> [[Char]]) -> [Char] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
  [Char]
"Char" -> [[Char]
"Character literals //Char// have the form",
             [Char]
"``'``//c//``'``, where //c// is any single character.",
             [Char]
""
            ]
  [Char]
"String" -> [[Char]
"String literals //String// have the form",
             [Char]
"``\"``//x//``\"``}, where //x// is any sequence of any characters",
             [Char]
"except ``\"`` unless preceded by ``\\``.",
             [Char]
""]
  [Char]
"Integer" -> [[Char]
"Integer literals //Integer// are nonempty sequences of digits.",
             [Char]
""]
  [Char]
"Double" -> [[Char]
"Double-precision float literals //Double// have the structure",
               [Char]
"indicated by the regular expression" [Char] -> [Char] -> [Char]
+++
               [Char]
"``digit+ '.' digit+ ('e' ('-')? digit+)?`` i.e.\\",
               [Char]
"two sequences of digits separated by a decimal point, optionally",
               [Char]
"followed by an unsigned or negative exponent.",
               [Char]
""]
  [Char]
_ -> []

prtOwnToken :: ([Char], Reg) -> [Char]
prtOwnToken ([Char]
name,Reg
reg) = [[Char]] -> [Char]
unlines
  [[Char]
name [Char] -> [Char] -> [Char]
+++ [Char]
"literals are recognized by the regular expression",
   [Char]
"```" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
   Reg -> [Char]
latexRegExp Reg
reg [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
   [Char]
"```"
  ]

prtComments :: ([(String,String)],[String]) -> String
prtComments :: ([([Char], [Char])], [[Char]]) -> [Char]
prtComments ([([Char], [Char])]
xs,[[Char]]
ys) = [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
                   [
                   if [[Char]] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Char]]
ys then
                    [Char]
"There are no single-line comments in the grammar."
                   else
                    [Char]
"Single-line comments begin with " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
sing [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
".",
                   if [([Char], [Char])] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [([Char], [Char])]
xs then
                    [Char]
"There are no multiple-line comments in the grammar."
                   else
                   [Char]
"Multiple-line comments are  enclosed with " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
mult [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"."
                   ]
 where
 sing :: [Char]
sing = [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
", " ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ ([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> [Char]
symbol([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.[Char] -> [Char]
prt) [[Char]]
ys
 mult :: [Char]
mult = [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
", " ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$
         (([Char], [Char]) -> [Char]) -> [([Char], [Char])] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map (\([Char]
x,[Char]
y) -> [Char] -> [Char]
symbol ([Char] -> [Char]
prt [Char]
x) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" and " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
symbol ([Char] -> [Char]
prt [Char]
y)) [([Char], [Char])]
xs

prtSymb :: String -> CF -> String
prtSymb :: [Char] -> CF -> [Char]
prtSymb [Char]
name CF
cf = case CF -> [[Char]]
forall f. CFG f -> [[Char]]
cfgSymbols CF
cf of
                   [] -> [Char]
"\nThere are no symbols in " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
".\n"
                   [[Char]]
xs -> [Char]
"The symbols used in " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" are the following:\n"
                         [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
                         Int -> [[[Char]]] -> [Char]
tabular Int
4 ([[Char]] -> [[[Char]]]
three ([[Char]] -> [[[Char]]]) -> [[Char]] -> [[[Char]]]
forall a b. (a -> b) -> a -> b
$ ([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> [Char]
symbol([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.[Char] -> [Char]
prt) [[Char]]
xs)

prtReserved :: String -> CF -> String
prtReserved :: [Char] -> CF -> [Char]
prtReserved [Char]
name CF
cf = case CF -> [[Char]]
forall f. CFG f -> [[Char]]
reservedWords CF
cf of
                       [] -> [Char] -> [Char]
stringRes [Char]
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
                             [Char]
"\nThere are no reserved words in " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
".\n"
                       [[Char]]
xs -> [Char] -> [Char]
stringRes [Char]
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
                             Int -> [[[Char]]] -> [Char]
tabular Int
4 ([[Char]] -> [[[Char]]]
three ([[Char]] -> [[[Char]]]) -> [[Char]] -> [[[Char]]]
forall a b. (a -> b) -> a -> b
$ ([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> [Char]
quote [[Char]]
xs)

stringRes :: String -> String
stringRes :: [Char] -> [Char]
stringRes [Char]
name = [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
                 [[Char]
"The set of reserved words is the set of terminals ",
                  [Char]
"appearing in the grammar. Those reserved words ",
                  [Char]
"that consist of non-letter characters are called symbols, and ",
                  [Char]
"they are treated in a different way from those that ",
                  [Char]
"are similar to identifiers. The lexer ",
                  [Char]
"follows rules familiar from languages ",
                  [Char]
"like Haskell, C, and Java, including longest match ",
                  [Char]
"and spacing conventions.",
                  [Char]
"\n\n",
                  [Char]
"The reserved words used in " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" are the following:\n"]

three :: [String] -> [[String]]
three :: [[Char]] -> [[[Char]]]
three []         = []
three [[Char]
x]        = [[[Char]
x,[],[],[]]]
three [[Char]
x,[Char]
y]      = [[[Char]
x,[Char]
y,[],[]]]
three [[Char]
x,[Char]
y,[Char]
z]      = [[[Char]
x,[Char]
y,[Char]
z,[]]]
three ([Char]
x:[Char]
y:[Char]
z:[Char]
u:[[Char]]
xs) = [[Char]
x,[Char]
y,[Char]
z,[Char]
u] [[Char]] -> [[[Char]]] -> [[[Char]]]
forall a. a -> [a] -> [a]
: [[Char]] -> [[[Char]]]
three [[Char]]
xs

prtBNF :: String -> CF -> String
prtBNF :: [Char] -> CF -> [Char]
prtBNF [Char]
name CF
cf = [[Char]] -> [Char]
unlines [
                     [Char]
"==The syntactic structure of " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"==",
                     [Char]
"Non-terminals are enclosed between < and >. ",
                     [Char]
"The symbols " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
arrow [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" (production), " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
                      [Char]
delimiter [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
" (union) ",
                     [Char]
"and " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
empty [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" (empty rule) belong to the BNF notation. ",
                     [Char]
"All other symbols are terminals.",
                     [Char]
"",
                     [(Cat, [Rule])] -> [Char]
prtRules (CF -> [(Cat, [Rule])]
ruleGroups CF
cf)
                     ]

prtRules :: [(Cat,[Rule])] -> String
prtRules :: [(Cat, [Rule])] -> [Char]
prtRules          [] = []
prtRules ((Cat
c,[]):[(Cat, [Rule])]
xs)
    = Int -> [[[Char]]] -> [Char]
tabular Int
3 [[Cat -> [Char]
nonterminal Cat
c,[Char]
arrow,[]]] [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [(Cat, [Rule])] -> [Char]
prtRules [(Cat, [Rule])]
xs
prtRules ((Cat
c, Rule
r : [Rule]
rs) : [(Cat, [Rule])]
xs)
    = Int -> [[[Char]]] -> [Char]
tabular Int
3 ([[Cat -> [Char]
nonterminal Cat
c,[Char]
arrow,[Either Cat [Char]] -> [Char]
prtSymbols ([Either Cat [Char]] -> [Char]) -> [Either Cat [Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ Rule -> [Either Cat [Char]]
forall function. Rul function -> [Either Cat [Char]]
rhsRule Rule
r]] [[[Char]]] -> [[[Char]]] -> [[[Char]]]
forall a. [a] -> [a] -> [a]
++
                 [[[],[Char]
delimiter,[Either Cat [Char]] -> [Char]
prtSymbols (Rule -> [Either Cat [Char]]
forall function. Rul function -> [Either Cat [Char]]
rhsRule Rule
y)] | Rule
y <-  [Rule]
rs]) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
    ---  "\n\n" ++ --- with empty lines good for latex, bad for html
      [(Cat, [Rule])] -> [Char]
prtRules [(Cat, [Rule])]
xs

prtSymbols :: [Either Cat String] -> String
prtSymbols :: [Either Cat [Char]] -> [Char]
prtSymbols [] = [Char]
empty
prtSymbols [Either Cat [Char]]
xs = (Either Cat [Char] -> [Char] -> [Char])
-> [Char] -> [Either Cat [Char]] -> [Char]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ([Char] -> [Char] -> [Char]
(+++) ([Char] -> [Char] -> [Char])
-> (Either Cat [Char] -> [Char])
-> Either Cat [Char]
-> [Char]
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either Cat [Char] -> [Char]
p) [] [Either Cat [Char]]
xs
 where p :: Either Cat [Char] -> [Char]
p (Left  Cat
r) = Cat -> [Char]
nonterminal Cat
r
       p (Right [Char]
r) = [Char] -> [Char]
terminal [Char]
r

prt :: String -> String
prt :: [Char] -> [Char]
prt [Char]
s = [Char]
s

empty :: String
empty :: [Char]
empty = [Char]
"**eps**"

symbol :: String -> String
symbol :: [Char] -> [Char]
symbol [Char]
s = [Char]
s

tabular :: Int -> [[String]] -> String
tabular :: Int -> [[[Char]]] -> [Char]
tabular Int
_ [[[Char]]]
xs = [[Char]] -> [Char]
unlines [[[Char]] -> [Char]
unwords ([Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
intersperse [Char]
"|" ([Char]
" " [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: [[Char]]
x)) | [[Char]]
x <- [[[Char]]]
xs]

terminal :: String -> String
terminal :: [Char] -> [Char]
terminal [Char]
s = [Char]
"``" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"``"

nonterminal :: Cat -> String
nonterminal :: Cat -> [Char]
nonterminal Cat
s = [Char]
"//" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Cat -> [Char]
forall a. Show a => a -> [Char]
show Cat
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"//"

arrow :: String
arrow :: [Char]
arrow = [Char]
"->"

delimiter :: String
delimiter :: [Char]
delimiter = [Char]
" **|** "

beginDocument :: String -> String
beginDocument :: [Char] -> [Char]
beginDocument [Char]
name = [[Char]] -> [Char]
unlines [
 [Char]
"The Language " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
name,
 [Char]
"BNF Converter",
 [Char]
"",
 [Char]
"",
 [Char]
"%This txt2tags file is machine-generated by the BNF-converter",
 [Char]
"%Process by txt2tags to generate html or latex",
 [Char]
""
 ]

latexRegExp :: Reg -> String
latexRegExp :: Reg -> [Char]
latexRegExp = [Char] -> [Char]
quote ([Char] -> [Char]) -> (Reg -> [Char]) -> Reg -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Reg -> [Char]
forall {t}. (Ord t, Num t) => t -> Reg -> [Char]
rex (Int
0 :: Int) where
  rex :: t -> Reg -> [Char]
rex t
i Reg
e = case Reg
e of
    RSeq Reg
reg0 Reg
reg  -> t -> t -> [Char] -> [Char]
forall {a}. Ord a => a -> a -> [Char] -> [Char]
ifPar t
i t
2 ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ t -> Reg -> [Char]
rex t
2 Reg
reg0 [Char] -> [Char] -> [Char]
+++ t -> Reg -> [Char]
rex t
2 Reg
reg
    RAlt Reg
reg0 Reg
reg  -> t -> t -> [Char] -> [Char]
forall {a}. Ord a => a -> a -> [Char] -> [Char]
ifPar t
i t
1 ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ t -> Reg -> [Char]
rex t
1 Reg
reg0 [Char] -> [Char] -> [Char]
+++ [Char]
"|" [Char] -> [Char] -> [Char]
+++ t -> Reg -> [Char]
rex t
1 Reg
reg
    RMinus Reg
reg0 Reg
reg  -> t -> t -> [Char] -> [Char]
forall {a}. Ord a => a -> a -> [Char] -> [Char]
ifPar t
i t
1 ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ t -> Reg -> [Char]
rex t
2 Reg
reg0 [Char] -> [Char] -> [Char]
+++ [Char]
"-" [Char] -> [Char] -> [Char]
+++ t -> Reg -> [Char]
rex t
2 Reg
reg
    RStar Reg
reg  -> t -> Reg -> [Char]
rex t
3 Reg
reg [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"*"
    RPlus Reg
reg  -> t -> Reg -> [Char]
rex t
3 Reg
reg [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"+"
    ROpt Reg
reg  -> t -> Reg -> [Char]
rex t
3 Reg
reg [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"?"
    Reg
REps  -> [Char]
"eps"
    RChar Char
c  -> [Char]
"'" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char
c] [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"'"
    RAlts [Char]
str  -> [Char]
"[\"" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
str [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\"]"
    RSeqs [Char]
str  -> [Char]
"{\"" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
str [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\"}"
    Reg
RDigit  -> [Char]
"digit"
    Reg
RLetter  -> [Char]
"letter"
    Reg
RUpper  -> [Char]
"upper"
    Reg
RLower  -> [Char]
"lower"
    Reg
RAny  -> [Char]
"char"
  ifPar :: a -> a -> [Char] -> [Char]
ifPar a
i a
j [Char]
s = if a
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
j then [Char]
"(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
")" else [Char]
s

quote :: [Char] -> [Char]
quote [Char]
s = [Char]
"``" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"``"