{-# LANGUAGE LambdaCase #-}
module BNFC.Backend.Txt2Tag (cfToTxt, t2tComment) where
import qualified Data.List as List
import BNFC.Abs (Reg (..))
import BNFC.CF
import BNFC.PrettyPrint
import BNFC.Utils
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 -> String
identSection :: forall f. 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 :: (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]
"```" [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) = [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[
if [[Char]] -> Bool
forall a. [a] -> 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 a. [a] -> 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
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]
eps [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]
++
[(Cat, [Rule])] -> [Char]
prtRules [(Cat, [Rule])]
xs
prtSymbols :: [Either Cat String] -> String
prtSymbols :: [Either Cat [Char]] -> [Char]
prtSymbols [] = [Char]
eps
prtSymbols [Either Cat [Char]]
xs = (Either Cat [Char] -> [Char] -> [Char])
-> [Char] -> [Either Cat [Char]] -> [Char]
forall a b. (a -> b -> b) -> b -> [a] -> b
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
eps :: String
eps :: [Char]
eps = [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]
List.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
cat = [Char]
"//" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Cat -> [Char]
forall a. Pretty a => a -> [Char]
prettyShow Cat
cat [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]
"%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 :: String -> String
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]
"``"
t2tComment :: String -> String
= ([Char]
"%% " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++)