@@ -34,6 +34,7 @@ import BNFC.Backend.Common.StrUtils (renderCharOrString)
3434import BNFC.Backend.CPP.Common (CppStdMode (.. ))
3535import BNFC.Backend.CPP.STL.STLUtils
3636import BNFC.PrettyPrint
37+ import BNFC.Options (Ansi (.. ))
3738
3839-- Produces (.H file, .C file)
3940cf2CPPPrinter :: CppStdMode -> Bool -> Maybe String -> CF -> String -> (String , String )
@@ -395,11 +396,8 @@ prPrintData False mode _ _ (cat@(ListCat _), rules) =
395396prPrintData _ _ _inPackage cf (TokenCat cat, _rules) |
396397 isPositionCat cf cat = genPositionToken cat
397398prPrintData _ mode inPackage _cf (cat, rules) =
398- abstract ++ concatMap (prPrintRule beyondAnsi inPackage) rules
399+ abstract ++ concatMap (prPrintRule mode inPackage) rules
399400 where
400- beyondAnsi = case mode of
401- CppStdBeyondAnsi _ -> True
402- CppStdAnsi _ -> False
403401 cl = identCat (normCat cat)
404402 abstract = case lookupRule (noPosition $ catToStr cat) rules of
405403 Just _ -> " "
@@ -408,7 +406,7 @@ prPrintData _ mode inPackage _cf (cat, rules) =
408406-- | Generate pretty printer visitor for a list category (STL version).
409407--
410408genPrintVisitorList :: (CppStdMode , Cat , [Rule ]) -> Doc
411- genPrintVisitorList (_ , cat@ (ListCat _), rules) = vcat
409+ genPrintVisitorList (mode , cat@ (ListCat _), rules) = vcat
412410 [ " void PrintAbsyn::visit" <> lty <> parens (ltyarg <> " *" <+> varg)
413411 , codeblock 2
414412 [ " iter" <> lty <> parens (vname <> " ->begin()" <> comma <+> vname <> " ->end()" ) <> semi ]
@@ -425,7 +423,7 @@ genPrintVisitorList (_, cat@(ListCat _), rules) = vcat
425423 , " else"
426424 ]
427425 , unless (null docs1)
428- [ " if (i == std::prev(j, 1) )"
426+ [ " if (i == " <> prevJ <> " )"
429427 , " { /* last */"
430428 , nest 2 $ vcat docs1
431429 , " }"
@@ -448,12 +446,18 @@ genPrintVisitorList (_, cat@(ListCat _), rules) = vcat
448446 varg = text $ (map toLower cl)
449447 prules = sortRulesByPrecedence rules
450448 swRules f = switchByPrecedence " _i_" $
451- map (second $ sep . prListRule_ ) $
449+ map (second $ sep . prListRuleFn ) $
452450 uniqOn fst $ filter f prules
453451 -- Discard duplicates, can only handle one rule per precedence.
454452 docs0 = swRules isNilFun
455453 docs1 = swRules isOneFun
456454 docs2 = swRules isConsFun
455+ prevJ = case mode of
456+ CppStdBeyondAnsi _ -> " std::prev(j, 1)"
457+ CppStdAnsi _ -> " j-1"
458+ prListRuleFn = case mode of
459+ CppStdBeyondAnsi _ -> prListRuleBeyondAnsi
460+ CppStdAnsi _ -> prListRuleAnsi
457461
458462genPrintVisitorList _ = error " genPrintVisitorList expects a ListCat"
459463
@@ -469,8 +473,8 @@ genPositionToken cat = unlines $
469473
470474-- | Only render the rhs (items) of a list rule.
471475
472- prListRule_ :: IsFun a => Rul a -> [Doc ]
473- prListRule_ (Rule _ _ items _) = for items $ \ case
476+ prListRuleBeyondAnsi :: IsFun a => Rul a -> [Doc ]
477+ prListRuleBeyondAnsi (Rule _ _ items _) = for items $ \ case
474478 Right t -> " render(" <> text (snd (renderCharOrString t)) <> " );"
475479 Left c
476480 | Just {} <- maybeTokenCat c
@@ -480,11 +484,22 @@ prListRule_ (Rule _ _ items _) = for items $ \case
480484 where
481485 dat = text $ identCat $ normCat c
482486
487+ prListRuleAnsi :: IsFun a => Rul a -> [Doc ]
488+ prListRuleAnsi (Rule _ _ items _) = for items $ \ case
489+ Right t -> " render(" <> text (snd (renderCharOrString t)) <> " );"
490+ Left c
491+ | Just {} <- maybeTokenCat c
492+ -> " visit" <> dat <> " (*i);"
493+ | isList c -> " iter" <> dat <> " (i+1, j);"
494+ | otherwise -> " (*i)->accept(this);"
495+ where
496+ dat = text $ identCat $ normCat c
497+
483498-- This is the only part of the pretty printer that differs significantly
484499-- between the versions with and without STL.
485500-- The present version has been adapted from CFtoCPrinter.
486501genPrintVisitorListNoStl :: (CppStdMode , Cat , [Rule ]) -> String
487- genPrintVisitorListNoStl (_ , cat@ (ListCat _), rules) = unlines $ concat
502+ genPrintVisitorListNoStl (mode , cat@ (ListCat _), rules) = unlines $ concat
488503 [ [ " void PrintAbsyn::visit" ++ cl ++ " (" ++ cl ++ " *" ++ vname ++ " )"
489504 , " {"
490505 , " if (" ++ vname +++ " == 0)"
@@ -514,22 +529,27 @@ genPrintVisitorListNoStl (_, cat@(ListCat _), rules) = unlines $ concat
514529 vname = map toLower cl
515530 pre = vname ++ " ->"
516531 prules = sortRulesByPrecedence rules
532+ prPrintRuleFn = case mode of
533+ CppStdBeyondAnsi _ -> prPrintRuleBeyondAnsi
534+ CppStdAnsi _ -> prPrintRuleAnsi
517535 swRules f = switchByPrecedence " _i_" $
518- map (second $ sep . map text . prPrintRule_ pre) $
536+ map (second $ sep . map text . prPrintRuleFn pre) $
519537 uniqOn fst $ filter f prules
520538 -- Discard duplicates, can only handle one rule per precedence.
539+
540+
521541genPrintVisitorListNoStl _ = error " genPrintVisitorListNoStl expects a ListCat"
522542
523543-- Pretty Printer methods for a rule.
524- prPrintRule :: Bool -> Maybe String -> Rule -> String
525- prPrintRule _ inPackage r@ (Rule fun _ _ _) | isProperLabel fun = unlines $ concat
544+ prPrintRule :: CppStdMode -> Maybe String -> Rule -> String
545+ prPrintRule mode inPackage r@ (Rule fun _ _ _) | isProperLabel fun = unlines $ concat
526546 [ [ " void PrintAbsyn::visit" ++ visitFunName ++ " (" ++ vararg +++ fnm ++ " )"
527547 , " {"
528548 , " int oldi = _i_;"
529549 , parenCode " _L_PAREN"
530550 , " "
531551 ]
532- , prPrintRule_ (fnm ++ " ->" ) r
552+ , prPrintRuleFn (fnm ++ " ->" ) r
533553 , [ " "
534554 , parenCode " _R_PAREN"
535555 , " _i_ = oldi;"
@@ -543,28 +563,38 @@ prPrintRule _ inPackage r@(Rule fun _ _ _) | isProperLabel fun = unlines $ conca
543563 p = precRule r
544564 parenCode x = " if (oldi > " ++ show p ++ " ) render(" ++ nsDefine inPackage x ++ " );"
545565 fnm = " p" -- old names could cause conflicts
566+ prPrintRuleFn = case mode of
567+ CppStdBeyondAnsi _ -> prPrintRuleBeyondAnsi
568+ CppStdAnsi _ -> prPrintRuleAnsi
546569
547570prPrintRule _ _ _ = " "
548571
549- prPrintRule_ :: IsFun a => String -> Rul a -> [String ]
550- prPrintRule_ pre (Rule _ _ items _) = map (prPrintItem pre) $ numVars items
572+ prPrintRuleAnsi :: IsFun a => String -> Rul a -> [String ]
573+ prPrintRuleAnsi pre (Rule _ _ items _) = map (prPrintItem (CppStdAnsi Ansi ) pre) $ numVars items
574+
575+ prPrintRuleBeyondAnsi :: IsFun a => String -> Rul a -> [String ]
576+ prPrintRuleBeyondAnsi pre (Rule _ _ items _) = map (prPrintItem (CppStdBeyondAnsi Ansi ) pre) $ numVars items
551577
552578-- This goes on to recurse to the instance variables.
553- prPrintItem :: String -> Either (Cat , Doc ) String -> String
554- prPrintItem _ (Right t) = " render(" ++ snd (renderCharOrString t) ++ " );"
555- prPrintItem pre (Left (c, nt))
579+ prPrintItem :: CppStdMode -> String -> Either (Cat , Doc ) String -> String
580+ prPrintItem _ _ (Right t) = " render(" ++ snd (renderCharOrString t) ++ " );"
581+ prPrintItem mode pre (Left (c, nt))
556582 | Just t <- maybeTokenCat c = " visit" ++ t ++ " (" ++ pre ++ s ++ " );"
557- | isList c = " " ++ setI (precCat c) ++ " visit" ++ elt ++ " (" ++ pre ++ s ++ " .get()); " -- TODO: shared_ptr.get is only beyondAnsi
583+ | isList c = " " ++ setI (precCat c) ++ " visit" ++ elt ++ " (" ++ pre ++ s ++ toRawPtr ++ " ); "
558584 | otherwise = " " ++ setI (precCat c) ++ pre ++ s ++ " ->accept(this);"
559585 where
560586 s = render nt
561587 elt = identCat $ normCat c
588+ toRawPtr = case mode of
589+ CppStdBeyondAnsi _ -> " .get()"
590+ CppStdAnsi _ -> " "
591+
562592
563593{- **** Abstract Syntax Tree Printer **** -}
564594
565595-- This prints the functions for Abstract Syntax tree printing.
566596prShowData :: Bool -> CppStdMode -> (Cat , [Rule ]) -> String
567- prShowData True _ (cat@ (ListCat c), _) = unlines
597+ prShowData True mode (cat@ (ListCat c), _) = unlines
568598 [
569599 " void ShowAbsyn::visit" ++ cl ++ " (" ++ cl ++ " *" ++ vname ++ " )" ,
570600 " {" ,
@@ -574,7 +604,9 @@ prShowData True _ (cat@(ListCat c), _) = unlines
574604 if isTokenCat c
575605 then " visit" ++ baseName cl ++ " (*i) ;"
576606 else " (*i)->accept(this);" ,
577- " if (i != std::prev(" ++ vname ++ " ->end(), 1)) bufAppend(\" , \" );" ,
607+ case mode of
608+ CppStdBeyondAnsi _ -> " if (i != std::prev(" ++ vname ++ " ->end(), 1)) bufAppend(\" , \" );"
609+ CppStdAnsi _ -> " if (i != " ++ vname ++ " ->end() - 1) bufAppend(\" , \" );" ,
578610 " }" ,
579611 " }" ,
580612 " "
0 commit comments