Skip to content

Commit

Permalink
[ #493 ] C++: fixed broken parse_error exception
Browse files Browse the repository at this point in the history
  • Loading branch information
MagicWinnie committed Feb 1, 2025
1 parent c2897d0 commit 44787b1
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 11 deletions.
1 change: 1 addition & 0 deletions source/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* C: preserve case in constructors (union): e.g. label `EInt` now is union member `eInt_` rather than `eint_`
[[#479](https://github.com/BNFC/bnfc/issues/479)]
* C++: repair broken `parse_error` exception throw [[#493](https://github.com/BNFC/bnfc/issues/493)]

# 2.9.5

Expand Down
42 changes: 31 additions & 11 deletions source/src/BNFC/Backend/C/CFtoBisonC.hs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ header mode cf = unlines $ concat
-- Fixing regression introduced in 2.9.2.
, when (stlParser mode)
[ "#include <algorithm> /* for std::reverse */" -- mandatory e.g. with GNU C++ 11
, "#include \"" ++ ("ParserError" <.> h) ++ "\"" -- for throwing parser_error in C++
]
, [ "#include <stdio.h>"
, "#include <stdlib.h>"
Expand Down Expand Up @@ -160,23 +161,42 @@ header mode cf = unlines $ concat
unionDependentCode :: ParserMode -> String
unionDependentCode mode = unlines
[ "%{"
, errorHandler name
, errorHandler mode
, "int yyparse(yyscan_t scanner, YYSTYPE *result);"
, ""
, "extern int yylex(YYSTYPE *lvalp, YYLTYPE *llocp, yyscan_t scanner);"
, "%}"
]
where
name = parserName mode

errorHandler :: String -> String
errorHandler name = unlines
[ "void yyerror(YYLTYPE *loc, yyscan_t scanner, YYSTYPE *result, const char *msg)"
, "{"
, " fprintf(stderr, \"error: %d,%d: %s at %s\\n\","
, " loc->first_line, loc->first_column, msg, " ++ name ++ "get_text(scanner));"
, "}"
]
errorHandler :: ParserMode -> String
errorHandler mode = case mode of
CParser _ _ ->
-- This generates error handler for C with fprintf
unlines
[ "void yyerror(YYLTYPE *loc, yyscan_t scanner, YYSTYPE *result, const char *msg)"
, "{"
, " fprintf(stderr, \"error: %d,%d: %s at %s\\n\","
, " loc->first_line, loc->first_column, msg, " ++ name ++ "get_text(scanner));"
, "}"
]
CppParser _ _ ->
-- This generates error handler for C++ with throw parse_error
unlines
[ "void yyerror(YYLTYPE *loc, yyscan_t scanner, YYSTYPE *result, const char *msg)"
, "{"
, " std::string error_msg = msg;"
, " if (loc) {"
, " error_msg += \" at line \" + std::to_string(loc->first_line) +"
, " \", column \" + std::to_string(loc->first_column);"
, " }"
, " if (scanner) {"
, " error_msg += \": '\" + std::string(" ++ name ++ "get_text(scanner)) + \"'\";"
, " }"
, " throw " ++ name ++ "::parse_error(loc ? loc->first_line : -1, error_msg);"
, "}"
]
where
name = parserName mode

-- | Parser entry point code.
--
Expand Down

0 comments on commit 44787b1

Please sign in to comment.