{-# LANGUAGE LambdaCase #-}

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

-}

module BNFC.Backend.Latex where

import qualified Data.List as List
import System.FilePath ((<.>),replaceExtension)
import Text.Printf

import BNFC.Abs (Reg (..))
import BNFC.Options hiding (Backend)
import BNFC.Backend.Base
import BNFC.Backend.Common.Makefile as Makefile
import BNFC.CF
import BNFC.Utils
import BNFC.PrettyPrint hiding (empty)

-- | Entry point: create .tex file and a Makefile to compile it.
makeLatex :: SharedOptions -> CF -> Backend
makeLatex :: SharedOptions -> CF -> Backend
makeLatex SharedOptions
opts CF
cf = do
    let texfile :: [Char]
texfile = [Char]
name [Char] -> [Char] -> [Char]
<.> [Char]
"tex"
    forall c.
FileContent c =>
[Char] -> ([Char] -> [Char]) -> c -> Backend
mkfile [Char]
texfile [Char] -> [Char]
comment ([Char] -> CF -> [Char]
cfToLatex [Char]
name CF
cf)
    Maybe [Char] -> ([Char] -> Doc) -> Backend
Makefile.mkMakefile (SharedOptions -> Maybe [Char]
optMake SharedOptions
opts) ([Char] -> [Char] -> Doc
makefile [Char]
texfile)
  where name :: [Char]
name = SharedOptions -> [Char]
lang SharedOptions
opts

-- | Create a makefile for the given tex file
--
-- >>> makefile "myFile.tex" "Makefile"
-- all : myFile.pdf
-- <BLANKLINE>
-- myFile.pdf : myFile.tex
-- 	pdflatex myFile.tex
-- <BLANKLINE>
-- clean :
-- 	-rm myFile.pdf myFile.aux myFile.log
-- <BLANKLINE>
-- cleanall : clean
-- 	-rm Makefile myFile.tex
-- <BLANKLINE>
--
makefile :: String -> String -> Doc
makefile :: [Char] -> [Char] -> Doc
makefile [Char]
texfile [Char]
basename = [Doc] -> Doc
vcat
    [ [Char] -> [[Char]] -> [[Char]] -> Doc
Makefile.mkRule [Char]
"all" [[Char]
pdffile]
        []
    , [Char] -> [[Char]] -> [[Char]] -> Doc
Makefile.mkRule [Char]
pdffile [[Char]
texfile]
        [ forall r. PrintfType r => [Char] -> r
printf [Char]
"pdflatex %s" [Char]
texfile ]
    , [Char] -> [[Char]] -> [[Char]] -> Doc
Makefile.mkRule [Char]
"clean" []
        [ [[Char]] -> [Char]
unwords [ [Char]
"-rm", [Char]
pdffile, [Char]
auxfile, [Char]
logfile ]]
    , [Char] -> [[Char]] -> [[Char]] -> Doc
Makefile.mkRule [Char]
"cleanall" [[Char]
"clean"]
        [ [[Char]] -> [Char]
unwords [ [Char]
"-rm", [Char]
basename, [Char]
texfile ]]
    ]
  where pdffile :: [Char]
pdffile = [Char] -> [Char] -> [Char]
replaceExtension [Char]
texfile [Char]
"pdf"
        auxfile :: [Char]
auxfile = [Char] -> [Char] -> [Char]
replaceExtension [Char]
texfile [Char]
"aux"
        logfile :: [Char]
logfile = [Char] -> [Char] -> [Char]
replaceExtension [Char]
texfile [Char]
"log"

comment :: String -> String
comment :: [Char] -> [Char]
comment = ([Char]
"%% " forall a. [a] -> [a] -> [a]
++)

-- | Create content of .tex file.
cfToLatex :: String -> CF -> String
cfToLatex :: [Char] -> CF -> [Char]
cfToLatex [Char]
name CF
cf = [[Char]] -> [Char]
unlines
  -- Overall structure of created LaTeX document:
  [ [Char]
"\\batchmode"
  , [Char] -> [Char]
beginDocument [Char]
name
  , [Char]
macros
  , [Char]
introduction
  , [Char] -> CF -> [Char]
prtTerminals [Char]
name CF
cf
  , [Char] -> CF -> [Char]
prtBNF [Char]
name CF
cf
  , [Char]
endDocument
  ]

introduction :: String
introduction :: [Char]
introduction = [[Char]] -> [Char]
unlines
  [ [Char]
"This document was automatically generated by the {\\em 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"
  , [Char]
"(provided no hand-hacking has taken place)."
  ]

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

identSection :: CF -> [String]
identSection :: CF -> [[Char]]
identSection CF
cf
  | forall f. CFG f -> Bool
hasIdent CF
cf = [ [Char]
"\\subsection*{Identifiers}" ] forall a. [a] -> [a] -> [a]
++ [[Char]]
prtIdentifiers
  | Bool
otherwise   = []

prtIdentifiers :: [String]
prtIdentifiers :: [[Char]]
prtIdentifiers =
  [ [Char]
"Identifiers \\nonterminal{Ident} are unquoted strings beginning with a letter,"
  , [Char]
"followed by any combination of letters, digits, and the characters {\\tt \\_ '},"
  , [Char]
"reserved words excluded."
  ]

prtLiterals :: String -> CF -> String
prtLiterals :: [Char] -> CF -> [Char]
prtLiterals [Char]
_ CF
cf =
  [[Char]] -> [Char]
unlines forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
List.intersperse [[Char]
""] forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map [Char] -> [[Char]]
stringLit forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter (forall a. Eq a => a -> a -> Bool
/= [Char]
catIdent) forall a b. (a -> b) -> a -> b
$ forall f. CFG f -> [[Char]]
literals CF
cf

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

prtOwnToken :: (String, Reg) -> String
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]
"\\(" forall a. [a] -> [a] -> [a]
++
   Reg -> [Char]
latexRegExp Reg
reg forall a. [a] -> [a] -> [a]
++
   [Char]
"\\)"
  ]

prtComments :: ([(String,String)],[String]) -> String
prtComments :: ([([Char], [Char])], [[Char]]) -> [Char]
prtComments ([([Char], [Char])]
xs,[[Char]]
ys) =
    (if 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 " forall a. [a] -> [a] -> [a]
++ [Char]
sing forall a. [a] -> [a] -> [a]
++[Char]
". \\\\")
    forall a. [a] -> [a] -> [a]
++
    (if 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 " forall a. [a] -> [a] -> [a]
++ [Char]
mult forall a. [a] -> [a] -> [a]
++[Char]
".")
 where
 sing :: [Char]
sing = forall a. [a] -> [[a]] -> [a]
List.intercalate [Char]
", " forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> [Char]
symbolforall b c a. (b -> c) -> (a -> b) -> a -> c
.[Char] -> [Char]
prt) [[Char]]
ys
 mult :: [Char]
mult = forall a. [a] -> [[a]] -> [a]
List.intercalate [Char]
", " forall a b. (a -> b) -> a -> b
$
         forall a b. (a -> b) -> [a] -> [b]
map (\([Char]
x,[Char]
y) -> [Char] -> [Char]
symbol ([Char] -> [Char]
prt [Char]
x)
                       forall a. [a] -> [a] -> [a]
++ [Char]
" and " 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 forall f. CFG f -> [[Char]]
cfgSymbols CF
cf of
                   [] -> [Char]
"\nThere are no symbols in " forall a. [a] -> [a] -> [a]
++ [Char]
name forall a. [a] -> [a] -> [a]
++ [Char]
".\\\\\n"
                   [[Char]]
xs -> [Char]
"The symbols used in " forall a. [a] -> [a] -> [a]
++ [Char]
name forall a. [a] -> [a] -> [a]
++ [Char]
" are the following: \\\\\n"
                         forall a. [a] -> [a] -> [a]
++
                         Int -> [[[Char]]] -> [Char]
tabular Int
3 (forall a. Monoid a => [a] -> [[a]]
three forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> [Char]
symbolforall 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 forall f. CFG f -> [[Char]]
reservedWords CF
cf of
                       [] -> [Char] -> [Char]
stringRes [Char]
name forall a. [a] -> [a] -> [a]
++
                             [Char]
"\nThere are no reserved words in " forall a. [a] -> [a] -> [a]
++ [Char]
name forall a. [a] -> [a] -> [a]
++ [Char]
".\\\\\n"
                       [[Char]]
xs -> [Char] -> [Char]
stringRes [Char]
name forall a. [a] -> [a] -> [a]
++
                             Int -> [[[Char]]] -> [Char]
tabular Int
3 (forall a. Monoid a => [a] -> [[a]]
three forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> [Char]
reservedforall b c a. (b -> c) -> (a -> b) -> a -> c
.[Char] -> [Char]
prt) [[Char]]
xs)

stringRes :: String -> String
stringRes :: [Char] -> [Char]
stringRes [Char]
name = 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 " forall a. [a] -> [a] -> [a]
++ [Char]
name forall a. [a] -> [a] -> [a]
++ [Char]
" are the following: \\\\\n"]

-- | Group a list into blocks of 3 elements.
three :: Monoid a => [a] -> [[a]]
three :: forall a. Monoid a => [a] -> [[a]]
three []         = []
three [a
x]        = [[a
x,forall a. Monoid a => a
mempty,forall a. Monoid a => a
mempty]]
three [a
x,a
y]      = [[a
x,a
y,forall a. Monoid a => a
mempty]]
three (a
x:a
y:a
z:[a]
xs) = [a
x,a
y,a
z] forall a. a -> [a] -> [a]
: forall a. Monoid a => [a] -> [[a]]
three [a]
xs

prtBNF :: String -> CF -> String
prtBNF :: [Char] -> CF -> [Char]
prtBNF [Char]
name CF
cf = [[Char]] -> [Char]
unlines
  [ [Char]
"\\section*{The syntactic structure of " forall a. [a] -> [a] -> [a]
++ [Char]
name forall a. [a] -> [a] -> [a]
++ [Char]
"}"
  , [Char]
""
  , [Char]
"Non-terminals are enclosed between $\\langle$ and $\\rangle$."
  , [Char]
"The symbols " forall a. [a] -> [a] -> [a]
++ [Char]
arrow forall a. [a] -> [a] -> [a]
++ [Char]
" (production), " forall a. [a] -> [a] -> [a]
++ [Char]
delimiter forall a. [a] -> [a] -> [a]
++ [Char]
" (union)"
  , [Char]
"and " forall a. [a] -> [a] -> [a]
++ [Char]
empty forall a. [a] -> [a] -> [a]
++ [Char]
" (empty rule) belong to the BNF notation."
  , [Char]
"All other symbols are terminals.\\\\"
  , [(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,[]]] 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 forall a b. (a -> b) -> a -> b
$ forall function. Rul function -> [Either Cat [Char]]
rhsRule Rule
r] forall a. a -> [a] -> [a]
:
                 [[[],[Char]
delimiter,[Either Cat [Char]] -> [Char]
prtSymbols (forall function. Rul function -> [Either Cat [Char]]
rhsRule Rule
y)] | Rule
y <-  [Rule]
rs]) forall a. [a] -> [a] -> [a]
++
      [(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 = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ([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 --- (prt r)
       p (Right [Char]
r) = [Char] -> [Char]
terminal    ([Char] -> [Char]
prt [Char]
r)


prt :: String -> String
prt :: [Char] -> [Char]
prt = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Char -> [Char]
escape
  where escape :: Char -> [Char]
escape Char
'\\'                               = [Char]
"$\\backslash$"
        escape Char
'~'                                = [Char]
"\\~{}"
        escape Char
'^'                                = [Char]
"{\\textasciicircum}"
        escape Char
c | Char
c forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ([Char]
"$&%#_{}" :: String) = [Char
'\\', Char
c]
        escape Char
c | Char
c forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ([Char]
"+=|<>-" :: String)  = [Char]
"{$"  forall a. [a] -> [a] -> [a]
++ [Char
c] forall a. [a] -> [a] -> [a]
++ [Char]
"$}"
        escape Char
c                                  = [Char
c]

macros :: String
macros :: [Char]
macros = [[Char]] -> [Char]
unlines
  [ [Char]
"\\newcommand{\\emptyP}{\\mbox{$\\epsilon$}}"
  , [Char]
"\\newcommand{\\terminal}[1]{\\mbox{{\\texttt {#1}}}}"
  , [Char]
"\\newcommand{\\nonterminal}[1]{\\mbox{$\\langle \\mbox{{\\sl #1 }} \\! \\rangle$}}"
  , [Char]
"\\newcommand{\\arrow}{\\mbox{::=}}"
  , [Char]
"\\newcommand{\\delimit}{\\mbox{$|$}}"
  , [Char]
"\\newcommand{\\reserved}[1]{\\mbox{{\\texttt {#1}}}}"
  , [Char]
"\\newcommand{\\literal}[1]{\\mbox{{\\texttt {#1}}}}"
  , [Char]
"\\newcommand{\\symb}[1]{\\mbox{{\\texttt {#1}}}}"
  ]

reserved :: String -> String
reserved :: [Char] -> [Char]
reserved [Char]
s = [Char]
"{\\reserved{" forall a. [a] -> [a] -> [a]
++ [Char]
s forall a. [a] -> [a] -> [a]
++ [Char]
"}}"

literal :: String -> String
literal :: [Char] -> [Char]
literal [Char]
s = [Char]
"{\\literal{" forall a. [a] -> [a] -> [a]
++ [Char]
s forall a. [a] -> [a] -> [a]
++ [Char]
"}}"

empty :: String
empty :: [Char]
empty = [Char]
"{\\emptyP}"

symbol :: String -> String
symbol :: [Char] -> [Char]
symbol [Char]
s = [Char]
"{\\symb{" forall a. [a] -> [a] -> [a]
++ [Char]
s forall a. [a] -> [a] -> [a]
++ [Char]
"}}"

tabular :: Int -> [[String]] -> String
tabular :: Int -> [[[Char]]] -> [Char]
tabular Int
n [[[Char]]]
xs = [Char]
"\n\\begin{tabular}{" forall a. [a] -> [a] -> [a]
++ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (forall a. Int -> a -> [a]
replicate Int
n [Char]
"l") forall a. [a] -> [a] -> [a]
++ [Char]
"}\n" forall a. [a] -> [a] -> [a]
++
               forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\([Char]
a:[[Char]]
as) -> forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr [Char] -> [Char] -> [Char]
(+++) [Char]
"\\\\\n" ([Char]
aforall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map (Char
'&'forall a. a -> [a] -> [a]
:) [[Char]]
as)) [[[Char]]]
xs forall a. [a] -> [a] -> [a]
++
               [Char]
"\\end{tabular}\\\\\n"

terminal :: String -> String
terminal :: [Char] -> [Char]
terminal [Char]
s = [Char]
"{\\terminal{" forall a. [a] -> [a] -> [a]
++ [Char]
s forall a. [a] -> [a] -> [a]
++ [Char]
"}}"

nonterminal :: Cat -> String
nonterminal :: Cat -> [Char]
nonterminal Cat
s = [Char]
"{\\nonterminal{" forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
mkId (Cat -> [Char]
identCat Cat
s) forall a. [a] -> [a] -> [a]
++ [Char]
"}}" where
 mkId :: [Char] -> [Char]
mkId = forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
mk
 mk :: Char -> Char
mk Char
c = case Char
c of
   Char
'_' -> Char
'-' ---
   Char
_ -> Char
c


arrow :: String
arrow :: [Char]
arrow = [Char]
" {\\arrow} "

delimiter :: String
delimiter :: [Char]
delimiter = [Char]
" {\\delimit} "

beginDocument :: String -> String
beginDocument :: [Char] -> [Char]
beginDocument [Char]
name = [[Char]] -> [Char]
unlines
 [ [Char]
""
 , [Char]
"\\documentclass[a4paper,11pt]{article}"
 , [Char]
"\\usepackage[T1]{fontenc}"
 , [Char]
"\\usepackage[utf8x]{inputenc}"
 , [Char]
"\\setlength{\\parindent}{0mm}"
 , [Char]
"\\setlength{\\parskip}{1mm}"
 , [Char]
""
 , [Char]
"\\title{The Language " forall a. [a] -> [a] -> [a]
++ [Char]
name forall a. [a] -> [a] -> [a]
++ [Char]
"}"
 , [Char]
"\\author{BNF-converter}"
 , [Char]
""
 , [Char]
"\\begin{document}"
 , [Char]
"\\maketitle"
 , [Char]
""
 ]

endDocument :: String
endDocument :: [Char]
endDocument = [[Char]] -> [Char]
unlines
  [ [Char]
""
  , [Char]
"\\end{document}"
  ]

latexRegExp :: Reg -> String
latexRegExp :: Reg -> [Char]
latexRegExp = Int -> Reg -> [Char]
rex Int
0
  where
  rex :: Int -> Reg -> String
  rex :: Int -> Reg -> [Char]
rex Int
i = \case
    RSeq Reg
r0 Reg
r   -> forall {a}. Ord a => a -> a -> [Char] -> [Char]
ifPar Int
i Int
2 forall a b. (a -> b) -> a -> b
$ Int -> Reg -> [Char]
rex Int
2 Reg
r0 [Char] -> [Char] -> [Char]
+++ Int -> Reg -> [Char]
rex Int
2 Reg
r
    RAlt Reg
r0 Reg
r   -> forall {a}. Ord a => a -> a -> [Char] -> [Char]
ifPar Int
i Int
1 forall a b. (a -> b) -> a -> b
$ Int -> Reg -> [Char]
rex Int
1 Reg
r0 [Char] -> [Char] -> [Char]
+++ [Char]
"\\mid" [Char] -> [Char] -> [Char]
+++ Int -> Reg -> [Char]
rex Int
1 Reg
r
    RMinus Reg
r0 Reg
r -> forall {a}. Ord a => a -> a -> [Char] -> [Char]
ifPar Int
i Int
1 forall a b. (a -> b) -> a -> b
$ Int -> Reg -> [Char]
rex Int
2 Reg
r0 [Char] -> [Char] -> [Char]
+++ [Char]
"-" [Char] -> [Char] -> [Char]
+++ Int -> Reg -> [Char]
rex Int
2 Reg
r
    RStar Reg
r     -> Int -> Reg -> [Char]
rex Int
3 Reg
r forall a. [a] -> [a] -> [a]
++ [Char]
"*"
    RPlus Reg
r     -> Int -> Reg -> [Char]
rex Int
3 Reg
r forall a. [a] -> [a] -> [a]
++ [Char]
"+"
    ROpt Reg
r      -> Int -> Reg -> [Char]
rex Int
3 Reg
r forall a. [a] -> [a] -> [a]
++ [Char]
"?"
    Reg
REps        -> [Char]
"\\epsilon"
    RChar Char
c     -> [Char]
"\\mbox{`" forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
prt [Char
c] forall a. [a] -> [a] -> [a]
++ [Char]
"'}"
    RAlts [Char]
s     -> [Char]
"[" forall a. [a] -> [a] -> [a]
++ [Char]
"\\mbox{``" forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
prt [Char]
s forall a. [a] -> [a] -> [a]
++ [Char]
"''}" forall a. [a] -> [a] -> [a]
++ [Char]
"]"
    RSeqs [Char]
s     -> [Char]
"\\{" forall a. [a] -> [a] -> [a]
++ [Char]
"\\mbox{``" forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
prt [Char]
s forall a. [a] -> [a] -> [a]
++ [Char]
"''}" forall a. [a] -> [a] -> [a]
++ [Char]
"\\}"
    Reg
RDigit      -> [Char]
"{\\nonterminal{digit}}"
    Reg
RLetter     -> [Char]
"{\\nonterminal{letter}}"
    Reg
RUpper      -> [Char]
"{\\nonterminal{upper}}"
    Reg
RLower      -> [Char]
"{\\nonterminal{lower}}"
    Reg
RAny        -> [Char]
"{\\nonterminal{anychar}}"
  ifPar :: a -> a -> [Char] -> [Char]
ifPar a
i a
j [Char]
s = if a
i forall a. Ord a => a -> a -> Bool
> a
j then [Char]
"(" forall a. [a] -> [a] -> [a]
++ [Char]
s forall a. [a] -> [a] -> [a]
++ [Char]
")" else [Char]
s