From 67111e676f2e2f7ed969299038a9b95394c7d75d Mon Sep 17 00:00:00 2001 From: hangedman Date: Sun, 13 Mar 2022 17:35:51 +0900 Subject: [PATCH] Fixing review items and other compile error (#4) Fix following: * Dont' generate `override` keyword on `--ansi` mode * Remove doubly defined YY_BUFFER_STATE in `--ansi` mode * Switch `--ansi` and `-std=c++14` mode in `source/src/BNFC/Backend/CPP/PrettyPrinter.hs` * Fix Parser.h, switch entry points interfaces * Use C++ location/position interface --- source/src/BNFC/Backend/C/CFtoBisonC.hs | 3 +- source/src/BNFC/Backend/CPP/PrettyPrinter.hs | 76 +++++++++++++------ source/src/BNFC/Backend/CPP/STL.hs | 21 +++-- source/src/BNFC/Backend/CPP/STL/CFtoSTLAbs.hs | 2 +- 4 files changed, 70 insertions(+), 32 deletions(-) diff --git a/source/src/BNFC/Backend/C/CFtoBisonC.hs b/source/src/BNFC/Backend/C/CFtoBisonC.hs index 5da087aa..54e0b3a7 100644 --- a/source/src/BNFC/Backend/C/CFtoBisonC.hs +++ b/source/src/BNFC/Backend/C/CFtoBisonC.hs @@ -236,7 +236,6 @@ header mode cf = unlines $ concat [ , "typedef void* yyscan_t;" , "#endif" , "" - , "typedef struct " ++ name ++ "_buffer_state *YY_BUFFER_STATE;" , "typedef struct yy_buffer_state *YY_BUFFER_STATE;" , "extern YY_BUFFER_STATE " ++ name ++ "_scan_string(const char *str, yyscan_t scanner);" , "extern void " ++ name ++ "_delete_buffer(YY_BUFFER_STATE buf, yyscan_t scanner);" @@ -605,7 +604,7 @@ generateActionSTLBeyondAnsi rp inPackage nt f b mbs = reverses ++ -- The following match only happens in the cons case: [el, lst] = applyWhen b reverse ms -- b: left-recursion transformed? loc | RecordPositions <- rp - = " $$->line_number = @$.first_line; $$->char_number = @$.first_column;" + = " $$->line_number = @$.begin.line; $$->char_number = @$.begin.column;" | otherwise = "" reverses = unwords [m ++"->reverse();" | (m, True) <- mbs] diff --git a/source/src/BNFC/Backend/CPP/PrettyPrinter.hs b/source/src/BNFC/Backend/CPP/PrettyPrinter.hs index 297867b5..b6bc0bc9 100644 --- a/source/src/BNFC/Backend/CPP/PrettyPrinter.hs +++ b/source/src/BNFC/Backend/CPP/PrettyPrinter.hs @@ -34,6 +34,7 @@ import BNFC.Backend.Common.StrUtils (renderCharOrString) import BNFC.Backend.CPP.Common (CppStdMode(..)) import BNFC.Backend.CPP.STL.STLUtils import BNFC.PrettyPrint +import BNFC.Options (Ansi(..)) --Produces (.H file, .C file) cf2CPPPrinter :: CppStdMode -> Bool -> Maybe String -> CF -> String -> (String, String) @@ -395,11 +396,8 @@ prPrintData False mode _ _ (cat@(ListCat _), rules) = prPrintData _ _ _inPackage cf (TokenCat cat, _rules) | isPositionCat cf cat = genPositionToken cat prPrintData _ mode inPackage _cf (cat, rules) = - abstract ++ concatMap (prPrintRule beyondAnsi inPackage) rules + abstract ++ concatMap (prPrintRule mode inPackage) rules where - beyondAnsi = case mode of - CppStdBeyondAnsi _ -> True - CppStdAnsi _ -> False cl = identCat (normCat cat) abstract = case lookupRule (noPosition $ catToStr cat) rules of Just _ -> "" @@ -408,7 +406,7 @@ prPrintData _ mode inPackage _cf (cat, rules) = -- | Generate pretty printer visitor for a list category (STL version). -- genPrintVisitorList :: (CppStdMode, Cat, [Rule]) -> Doc -genPrintVisitorList (_, cat@(ListCat _), rules) = vcat +genPrintVisitorList (mode, cat@(ListCat _), rules) = vcat [ "void PrintAbsyn::visit" <> lty <> parens (ltyarg <> "*" <+> varg) , codeblock 2 [ "iter" <> lty <> parens (vname <> "->begin()" <> comma <+> vname <> "->end()") <> semi ] @@ -425,7 +423,7 @@ genPrintVisitorList (_, cat@(ListCat _), rules) = vcat , "else" ] , unless (null docs1) - [ "if (i == std::prev(j, 1))" + [ "if (i == " <> prevJ <> ")" , "{ /* last */" , nest 2 $ vcat docs1 , "}" @@ -448,12 +446,18 @@ genPrintVisitorList (_, cat@(ListCat _), rules) = vcat varg = text $ (map toLower cl) prules = sortRulesByPrecedence rules swRules f = switchByPrecedence "_i_" $ - map (second $ sep . prListRule_) $ + map (second $ sep . prListRuleFn) $ uniqOn fst $ filter f prules -- Discard duplicates, can only handle one rule per precedence. docs0 = swRules isNilFun docs1 = swRules isOneFun docs2 = swRules isConsFun + prevJ = case mode of + CppStdBeyondAnsi _ -> "std::prev(j, 1)" + CppStdAnsi _ -> "j-1" + prListRuleFn = case mode of + CppStdBeyondAnsi _ -> prListRuleBeyondAnsi + CppStdAnsi _ -> prListRuleAnsi genPrintVisitorList _ = error "genPrintVisitorList expects a ListCat" @@ -469,8 +473,8 @@ genPositionToken cat = unlines $ -- | Only render the rhs (items) of a list rule. -prListRule_ :: IsFun a => Rul a -> [Doc] -prListRule_ (Rule _ _ items _) = for items $ \case +prListRuleBeyondAnsi :: IsFun a => Rul a -> [Doc] +prListRuleBeyondAnsi (Rule _ _ items _) = for items $ \case Right t -> "render(" <> text (snd (renderCharOrString t)) <> ");" Left c | Just{} <- maybeTokenCat c @@ -480,11 +484,22 @@ prListRule_ (Rule _ _ items _) = for items $ \case where dat = text $ identCat $ normCat c +prListRuleAnsi :: IsFun a => Rul a -> [Doc] +prListRuleAnsi (Rule _ _ items _) = for items $ \case + Right t -> "render(" <> text (snd (renderCharOrString t)) <> ");" + Left c + | Just{} <- maybeTokenCat c + -> "visit" <> dat <> "(*i);" + | isList c -> "iter" <> dat <> "(i+1, j);" + | otherwise -> "(*i)->accept(this);" + where + dat = text $ identCat $ normCat c + -- This is the only part of the pretty printer that differs significantly -- between the versions with and without STL. -- The present version has been adapted from CFtoCPrinter. genPrintVisitorListNoStl :: (CppStdMode, Cat, [Rule]) -> String -genPrintVisitorListNoStl (_, cat@(ListCat _), rules) = unlines $ concat +genPrintVisitorListNoStl (mode, cat@(ListCat _), rules) = unlines $ concat [ [ "void PrintAbsyn::visit" ++ cl ++ "("++ cl ++ " *" ++ vname ++ ")" , "{" , " if (" ++ vname +++ "== 0)" @@ -514,22 +529,27 @@ genPrintVisitorListNoStl (_, cat@(ListCat _), rules) = unlines $ concat vname = map toLower cl pre = vname ++ "->" prules = sortRulesByPrecedence rules + prPrintRuleFn = case mode of + CppStdBeyondAnsi _ -> prPrintRuleBeyondAnsi + CppStdAnsi _ -> prPrintRuleAnsi swRules f = switchByPrecedence "_i_" $ - map (second $ sep . map text . prPrintRule_ pre) $ + map (second $ sep . map text . prPrintRuleFn pre) $ uniqOn fst $ filter f prules -- Discard duplicates, can only handle one rule per precedence. + + genPrintVisitorListNoStl _ = error "genPrintVisitorListNoStl expects a ListCat" --Pretty Printer methods for a rule. -prPrintRule :: Bool -> Maybe String -> Rule -> String -prPrintRule _ inPackage r@(Rule fun _ _ _) | isProperLabel fun = unlines $ concat +prPrintRule :: CppStdMode -> Maybe String -> Rule -> String +prPrintRule mode inPackage r@(Rule fun _ _ _) | isProperLabel fun = unlines $ concat [ [ "void PrintAbsyn::visit" ++ visitFunName ++ "(" ++ vararg +++ fnm ++ ")" , "{" , " int oldi = _i_;" , parenCode "_L_PAREN" , "" ] - , prPrintRule_ (fnm ++ "->") r + , prPrintRuleFn (fnm ++ "->") r , [ "" , parenCode "_R_PAREN" , " _i_ = oldi;" @@ -543,28 +563,38 @@ prPrintRule _ inPackage r@(Rule fun _ _ _) | isProperLabel fun = unlines $ conca p = precRule r parenCode x = " if (oldi > " ++ show p ++ ") render(" ++ nsDefine inPackage x ++ ");" fnm = "p" --old names could cause conflicts + prPrintRuleFn = case mode of + CppStdBeyondAnsi _ -> prPrintRuleBeyondAnsi + CppStdAnsi _ -> prPrintRuleAnsi prPrintRule _ _ _ = "" -prPrintRule_ :: IsFun a => String -> Rul a -> [String] -prPrintRule_ pre (Rule _ _ items _) = map (prPrintItem pre) $ numVars items +prPrintRuleAnsi :: IsFun a => String -> Rul a -> [String] +prPrintRuleAnsi pre (Rule _ _ items _) = map (prPrintItem (CppStdAnsi Ansi) pre) $ numVars items + +prPrintRuleBeyondAnsi :: IsFun a => String -> Rul a -> [String] +prPrintRuleBeyondAnsi pre (Rule _ _ items _) = map (prPrintItem (CppStdBeyondAnsi Ansi) pre) $ numVars items --This goes on to recurse to the instance variables. -prPrintItem :: String -> Either (Cat, Doc) String -> String -prPrintItem _ (Right t) = " render(" ++ snd (renderCharOrString t) ++ ");" -prPrintItem pre (Left (c, nt)) +prPrintItem :: CppStdMode -> String -> Either (Cat, Doc) String -> String +prPrintItem _ _ (Right t) = " render(" ++ snd (renderCharOrString t) ++ ");" +prPrintItem mode pre (Left (c, nt)) | Just t <- maybeTokenCat c = " visit" ++ t ++ "(" ++ pre ++ s ++ ");" - | isList c = " " ++ setI (precCat c) ++ "visit" ++ elt ++ "(" ++ pre ++ s ++ ".get());" -- TODO: shared_ptr.get is only beyondAnsi + | isList c = " " ++ setI (precCat c) ++ "visit" ++ elt ++ "(" ++ pre ++ s ++ toRawPtr ++ ");" | otherwise = " " ++ setI (precCat c) ++ pre ++ s ++ "->accept(this);" where s = render nt elt = identCat $ normCat c + toRawPtr = case mode of + CppStdBeyondAnsi _ -> ".get()" + CppStdAnsi _ -> "" + {- **** Abstract Syntax Tree Printer **** -} --This prints the functions for Abstract Syntax tree printing. prShowData :: Bool -> CppStdMode -> (Cat, [Rule]) -> String -prShowData True _ (cat@(ListCat c), _) = unlines +prShowData True mode (cat@(ListCat c), _) = unlines [ "void ShowAbsyn::visit" ++ cl ++ "("++ cl ++ " *" ++ vname ++ ")", "{", @@ -574,7 +604,9 @@ prShowData True _ (cat@(ListCat c), _) = unlines if isTokenCat c then " visit" ++ baseName cl ++ "(*i) ;" else " (*i)->accept(this);", - " if (i != std::prev(" ++ vname ++ "->end(), 1)) bufAppend(\", \");", + case mode of + CppStdBeyondAnsi _ -> " if (i != std::prev(" ++ vname ++ "->end(), 1)) bufAppend(\", \");" + CppStdAnsi _ -> " if (i != " ++ vname ++ "->end() - 1) bufAppend(\", \");", " }", "}", "" diff --git a/source/src/BNFC/Backend/CPP/STL.hs b/source/src/BNFC/Backend/CPP/STL.hs index 19fbe72f..e6703b42 100644 --- a/source/src/BNFC/Backend/CPP/STL.hs +++ b/source/src/BNFC/Backend/CPP/STL.hs @@ -43,7 +43,7 @@ makeCppStl opts cf = do -- Generate xxx.yy file mkCppFileWithHint (name ++ parserExt) $ cf2Bison (linenumbers opts) parserMode cf env mkCppFile ("Parser" ++ hExt) $ - mkHeaderFile hExt (inPackage opts) cf (allParserCats cf) (toList $ allEntryPoints cf) (Map.elems env) + mkHeaderFile parserMode hExt (inPackage opts) cf (allParserCats cf) (toList $ allEntryPoints cf) (Map.elems env) mkCppFile ("ParserError" ++ hExt) $ printParseErrHeader (inPackage opts) let (skelH, skelC) = cf2CVisitSkel opts True (inPackage opts) cf mkCppFile ("Skeleton" ++ hExt) skelH @@ -249,17 +249,19 @@ cpptest mode inPackage cf hExt = unlines $ concat camelCaseName = camelCase_ name ns = fromMaybe camelCaseName (parserPackage mode) -mkHeaderFile :: String -> Maybe String -> CF -> [Cat] -> [Cat] -> [String] -> String -mkHeaderFile hExt inPackage _cf _cats eps _env = unlines $ concat +mkHeaderFile :: ParserMode -> String -> Maybe String -> CF -> [Cat] -> [Cat] -> [String] -> String +mkHeaderFile mode hExt inPackage _cf _cats eps _env = unlines $ concat [ [ "#ifndef " ++ hdef , "#define " ++ hdef , "" , "#include " , "#include " , "#include " - , "#include \"Bison" ++ hExt ++ "\"" , "#include \"Absyn" ++ hExt ++ "\"" - , "" + , if beyondAnsi mode then + "#include \"Bison" ++ hExt ++ "\"" + else + "" , nsStart inPackage ] , concatMap mkFuncs eps @@ -270,8 +272,13 @@ mkHeaderFile hExt inPackage _cf _cats eps _env = unlines $ concat ] where hdef = nsDefine inPackage "PARSER_HEADER_FILE" - mkFuncs s = - [ identCat (normCat s) ++ "*" +++ "p" ++ identCat s ++ "(std::istream &stream);" ] + mkFuncs s = if beyondAnsi mode then + [ identCat (normCat s) ++ "*" +++ "p" ++ identCat s ++ "(std::istream &stream);" ] + else + [ identCat (normCat s) ++ "*" +++ "p" ++ identCat s ++ "(FILE *inp);" + , identCat (normCat s) ++ "*" +++ "p" ++ identCat s ++ "(const char *str);" + ] + -- | C++ lexer/parser driver diff --git a/source/src/BNFC/Backend/CPP/STL/CFtoSTLAbs.hs b/source/src/BNFC/Backend/CPP/STL/CFtoSTLAbs.hs index c4385f75..de73d244 100644 --- a/source/src/BNFC/Backend/CPP/STL/CFtoSTLAbs.hs +++ b/source/src/BNFC/Backend/CPP/STL/CFtoSTLAbs.hs @@ -175,7 +175,7 @@ prCon mode (c,(f,cs)) = " " ++ f ++ "(" ++ conargs ++ ");", -- Typ *p1, PIdent *p2, ListStm *p3); " ~" ++f ++ "();", - " virtual void accept(Visitor *v) override;", + " virtual void accept(Visitor *v);", " virtual " ++f++ " *clone() const;", " void swap(" ++f++ " &);", "};"