{-# LANGUAGE LambdaCase #-}
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)
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"
[Char] -> [Char] -> Backend
forall c. FileContent c => [Char] -> c -> Backend
mkfile [Char]
texfile ([Char] -> CF -> [Char]
cfToLatex [Char]
name CF
cf)
SharedOptions -> ([Char] -> Doc) -> Backend
Makefile.mkMakefile SharedOptions
opts ([Char] -> [Char] -> Doc
makefile [Char]
texfile)
where name :: [Char]
name = SharedOptions -> [Char]
lang SharedOptions
opts
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]
[ [Char] -> [Char] -> [Char]
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"
cfToLatex :: String -> CF -> String
cfToLatex :: [Char] -> CF -> [Char]
cfToLatex [Char]
name CF
cf = [[Char]] -> [Char]
unlines
[ [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 ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$
[ [Char]
"\\section*{The lexical structure of " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"}"
, [Char]
""
] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ CF -> [[Char]]
identSection CF
cf [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++
[ [Char]
"\\subsection*{Literals}"
, [Char] -> CF -> [Char]
prtLiterals [Char]
name CF
cf
] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ (([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]] -> [[Char]] -> [[Char]]
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 (([([Char], [Char])], [[Char]]) -> [Char])
-> ([([Char], [Char])], [[Char]]) -> [Char]
forall a b. (a -> b) -> a -> b
$ CF -> ([([Char], [Char])], [[Char]])
comments CF
cf
]
identSection :: CF -> [String]
identSection :: CF -> [[Char]]
identSection CF
cf
| CF -> Bool
forall f. CFG f -> Bool
hasIdent CF
cf = [ [Char]
"\\subsection*{Identifiers}" ] [[Char]] -> [[Char]] -> [[Char]]
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 ([[Char]] -> [Char])
-> ([[Char]] -> [[Char]]) -> [[Char]] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[[Char]]] -> [[Char]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[[Char]]] -> [[Char]])
-> ([[Char]] -> [[[Char]]]) -> [[Char]] -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Char]] -> [[[Char]]] -> [[[Char]]]
forall a. a -> [a] -> [a]
List.intersperse [[Char]
""] ([[[Char]]] -> [[[Char]]])
-> ([[Char]] -> [[[Char]]]) -> [[Char]] -> [[[Char]]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> [[Char]]) -> [[Char]] -> [[[Char]]]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> [[Char]]
stringLit ([[Char]] -> [[[Char]]])
-> ([[Char]] -> [[Char]]) -> [[Char]] -> [[[Char]]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([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 = \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 :: ([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
([([Char], [Char])]
xs,[[Char]]
ys) =
(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]
". \\\\")
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
(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]
List.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]
List.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
3 ([[Char]] -> [[[Char]]]
forall a. Monoid a => [a] -> [[a]]
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
3 ([[Char]] -> [[[Char]]]
forall a. Monoid a => [a] -> [[a]]
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]
reserved([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.[Char] -> [Char]
prt) [[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 :: Monoid a => [a] -> [[a]]
three :: forall a. Monoid a => [a] -> [[a]]
three [] = []
three [a
x] = [[a
x,a
forall a. Monoid a => a
mempty,a
forall a. Monoid a => a
mempty]]
three [a
x,a
y] = [[a
x,a
y,a
forall a. Monoid a => a
mempty]]
three (a
x:a
y:a
z:[a]
xs) = [a
x,a
y,a
z] [a] -> [[a]] -> [[a]]
forall a. a -> [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 " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"}"
, [Char]
""
, [Char]
"Non-terminals are enclosed between $\\langle$ and $\\rangle$."
, [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.\\\\"
, [(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]
++
[(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] -> [Char]
prt [Char]
r)
prt :: String -> String
prt :: [Char] -> [Char]
prt = (Char -> [Char]) -> [Char] -> [Char]
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 Char -> [Char] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ([Char]
"$&%#_{}" :: String) = [Char
'\\', Char
c]
escape Char
c | Char
c Char -> [Char] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ([Char]
"+=|<>-" :: String) = [Char]
"{$" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char
c] [Char] -> [Char] -> [Char]
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{" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"}}"
literal :: String -> String
literal :: [Char] -> [Char]
literal [Char]
s = [Char]
"{\\literal{" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"}}"
empty :: String
empty :: [Char]
empty = [Char]
"{\\emptyP}"
symbol :: String -> String
symbol :: [Char] -> [Char]
symbol [Char]
s = [Char]
"{\\symb{" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"}}"
tabular :: Int -> [[String]] -> String
tabular :: Int -> [[[Char]]] -> [Char]
tabular Int
n [[[Char]]]
xs = [Char]
"\n\\begin{tabular}{" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (Int -> [Char] -> [[Char]]
forall a. Int -> a -> [a]
replicate Int
n [Char]
"l") [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"}\n" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
([[Char]] -> [Char]) -> [[[Char]]] -> [Char]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\([Char]
a:[[Char]]
as) -> ([Char] -> [Char] -> [Char]) -> [Char] -> [[Char]] -> [Char]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr [Char] -> [Char] -> [Char]
(+++) [Char]
"\\\\\n" ([Char]
a[Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: ([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map (Char
'&'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:) [[Char]]
as)) [[[Char]]]
xs [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
[Char]
"\\end{tabular}\\\\\n"
terminal :: String -> String
terminal :: [Char] -> [Char]
terminal [Char]
s = [Char]
"{\\terminal{" [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]
"{\\nonterminal{" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
mkId (Cat -> [Char]
identCat Cat
s) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"}}" where
mkId :: [Char] -> [Char]
mkId = (Char -> Char) -> [Char] -> [Char]
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]
"%This Latex file is machine-generated by the BNF-converter"
, [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 " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
name [Char] -> [Char] -> [Char]
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 -> Int -> Int -> [Char] -> [Char]
forall {a}. Ord a => a -> a -> [Char] -> [Char]
ifPar Int
i Int
2 ([Char] -> [Char]) -> [Char] -> [Char]
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 -> Int -> Int -> [Char] -> [Char]
forall {a}. Ord a => a -> a -> [Char] -> [Char]
ifPar Int
i Int
1 ([Char] -> [Char]) -> [Char] -> [Char]
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 -> Int -> Int -> [Char] -> [Char]
forall {a}. Ord a => a -> a -> [Char] -> [Char]
ifPar Int
i Int
1 ([Char] -> [Char]) -> [Char] -> [Char]
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 [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"*"
RPlus Reg
r -> Int -> Reg -> [Char]
rex Int
3 Reg
r [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"+"
ROpt Reg
r -> Int -> Reg -> [Char]
rex Int
3 Reg
r [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"?"
Reg
REps -> [Char]
"\\epsilon"
RChar Char
c -> [Char]
"\\mbox{`" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
prt [Char
c] [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"'}"
RAlts [Char]
s -> [Char]
"[" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\\mbox{``" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
prt [Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"''}" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"]"
RSeqs [Char]
s -> [Char]
"\\{" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\\mbox{``" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
prt [Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"''}" [Char] -> [Char] -> [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 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