From 8807a16fe3115e19ce4d65f1c8beb476494ccaec Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 14 Oct 2014 21:24:31 -0700 Subject: More type safety, with help from C++ compiler. * parser.h (scanner_t): New typedef. Cleverly, we use yyguts_t as the basis for this, which pays off in a few places, getting rid of conversions. (parser_t): scanner member redeclared to scanner_t *. (yyerror, yyerr, yyerrof, end_of_regex, end_of_char): Declarations updated. * parser.l (yyerror, yyerrorf, num_esc): scanner argument becomes scanner_t * instead of void *. (yyscanner): Occurrences replaced by yyg: why should we refer to the type-unsafe void *yyscanner, when we know that in the middle of the yylex function we have the properly typed yyguts_t *yyg. (end_of_regex, end_of_char): Argument changes to scanner_t * and name strategically changes to yyg, eliminating the local variable and cast. * parser.y (sym_helper): scanner argument becomes scanner_t * instead of void *. (%parse-param}: void *scnr becomes scanner_t *scnr. (define-transform, yybadtoken): Use scanner_t * instead of void *. (parse): Since yylex_init takes a void **, we use it to initialize a local void *, and then assign it to the structure member. --- ChangeLog | 27 +++++++++++++++++++++++++++ parser.h | 14 ++++++++------ parser.l | 40 ++++++++++++++++++---------------------- parser.y | 14 ++++++++------ 4 files changed, 61 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index fb23e8e8..fd8d0bfb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2014-10-14 Kaz Kylheku + + More type safety, with help from C++ compiler. + + * parser.h (scanner_t): New typedef. Cleverly, we use + yyguts_t as the basis for this, which pays off in + a few places, getting rid of conversions. + (parser_t): scanner member redeclared to scanner_t *. + (yyerror, yyerr, yyerrof, end_of_regex, end_of_char): + Declarations updated. + + * parser.l (yyerror, yyerrorf, num_esc): scanner argument becomes + scanner_t * instead of void *. + (yyscanner): Occurrences replaced by yyg: why should we + refer to the type-unsafe void *yyscanner, when we know that + in the middle of the yylex function we have the properly + typed yyguts_t *yyg. + (end_of_regex, end_of_char): Argument changes to scanner_t * and name + strategically changes to yyg, eliminating the local variable and cast. + + * parser.y (sym_helper): scanner argument becomes + scanner_t * instead of void *. + (%parse-param}: void *scnr becomes scanner_t *scnr. + (define-transform, yybadtoken): Use scanner_t * instead of void *. + (parse): Since yylex_init takes a void **, we use it to initialize + a local void *, and then assign it to the structure member. + 2014-10-14 Kaz Kylheku C++ upkeep. diff --git a/parser.h b/parser.h index bb85d01c..532fbfb1 100644 --- a/parser.h +++ b/parser.h @@ -24,6 +24,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +typedef struct yyguts_t scanner_t; + typedef struct { cnum lineno; int errors; @@ -31,17 +33,17 @@ typedef struct { val name; val prepared_msg; val syntax_tree; - void *scanner; + scanner_t *scanner; } parser_t; extern const wchar_t *spec_file; extern val form_to_ln_hash; -void yyerror(void *scanner, parser_t *, const char *s); -void yyerr(void *scanner, const char *s); -void yyerrorf(void *scanner, val s, ...); +void yyerror(scanner_t *scanner, parser_t *, const char *s); +void yyerr(scanner_t *scanner, const char *s); +void yyerrorf(scanner_t *scanner, val s, ...); void yybadtoken(parser_t *, int tok, val context); -void end_of_regex(void *scanner); -void end_of_char(void *scanner); +void end_of_regex(scanner_t *scanner); +void end_of_char(scanner_t *scanner); int yylex_init(void **pscanner); int yylex_destroy(void *scanner); parser_t *yyget_extra(void *scanner); diff --git a/parser.l b/parser.l index d59955b7..d17b0c01 100644 --- a/parser.l +++ b/parser.l @@ -78,7 +78,7 @@ int yylex_destroy(void) int yyget_column(void *); void yyset_column (int column_no , yyscan_t yyscanner); -void yyerror(void *scanner, parser_t *parser, const char *s) +void yyerror(scanner_t *scanner, parser_t *parser, const char *s) { yyerrorf(scanner, lit("~a"), string_utf8(s), nao); if (parser->prepared_msg) { @@ -87,7 +87,7 @@ void yyerror(void *scanner, parser_t *parser, const char *s) } } -void yyerrorf(void *scanner, val fmt, ...) +void yyerrorf(scanner_t *scanner, val fmt, ...) { parser_t *parser = yyget_extra(scanner); @@ -137,7 +137,7 @@ static wchar_t char_esc(int letter) internal_error("unhandled escape character"); } -static wchar_t num_esc(void *scn, char *num) +static wchar_t num_esc(scanner_t *scn, char *num) { if (num[0] == 'x') { if (strlen(num) > 7) @@ -280,7 +280,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} ({FLO}|{FLODOT}){NTOK} { val str = string_utf8(yytext); - yyerrorf(yyscanner, lit("trailing junk in floating-point literal: ~a"), str, nao); + yyerrorf(yyg, lit("trailing junk in floating-point literal: ~a"), str, nao); if (yy_top_state(yyscanner) == INITIAL || yy_top_state(yyscanner) == QSILIT @@ -673,7 +673,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} [\\](x{HEX}+|{OCT}+) { wchar_t lexeme[2]; - lexeme[0] = num_esc(yyscanner, yytext + 1); + lexeme[0] = num_esc(yyg, yytext + 1); lexeme[1] = 0; yylval->lexeme = chk_strdup(lexeme); yy_pop_state(yyscanner); @@ -681,7 +681,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} } [\\]. { - yyerrorf(yyscanner, lit("unrecognized escape: \\~a"), chr(yytext[1]), nao); + yyerrorf(yyg, lit("unrecognized escape: \\~a"), chr(yytext[1]), nao); } [;].* { @@ -712,7 +712,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} } [\\](x{HEX}+|{OCT}+);? { - yylval->chr = num_esc(yyscanner, yytext + 1); + yylval->chr = num_esc(yyg, yytext + 1); return REGCHAR; } @@ -833,16 +833,16 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} } [\\](x{HEX}+|{OCT}+);? { - yylval->chr = num_esc(yyscanner, yytext+1); + yylval->chr = num_esc(yyg, yytext+1); return LITCHAR; } [\\]. { - yyerrorf(yyscanner, lit("unrecognized escape: \\~a"), chr(yytext[1]), nao); + yyerrorf(yyg, lit("unrecognized escape: \\~a"), chr(yytext[1]), nao); } (x{HEX}+|o{OCT}+) { - yylval->chr = num_esc(yyscanner, yytext); + yylval->chr = num_esc(yyg, yytext); return LITCHAR; } @@ -905,31 +905,27 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} %% -void end_of_regex(yyscan_t yyscanner) +void end_of_regex(scanner_t *yyg) { - struct yyguts_t *yyg = (struct yyguts_t *) yyscanner; - if (YYSTATE != REGEX) internal_error("end_of_regex called in wrong scanner state"); - yy_pop_state(yyscanner); + yy_pop_state(yyg); if (YYSTATE != INITIAL) { - if (yy_top_state(yyscanner) == INITIAL - || yy_top_state(yyscanner) == QSILIT - || yy_top_state(yyscanner) == QWLIT) - yy_pop_state(yyscanner); + if (yy_top_state(yyg) == INITIAL + || yy_top_state(yyg) == QSILIT + || yy_top_state(yyg) == QWLIT) + yy_pop_state(yyg); } } -void end_of_char(yyscan_t yyscanner) +void end_of_char(scanner_t *yyg) { - struct yyguts_t *yyg = (struct yyguts_t *) yyscanner; - if (YYSTATE != CHRLIT) internal_error("end_of_char called in wrong scanner state"); - yy_pop_state(yyscanner); + yy_pop_state(yyg); } val source_loc(val form) diff --git a/parser.y b/parser.y index 00bb15cf..fb2ff6ea 100644 --- a/parser.y +++ b/parser.y @@ -47,7 +47,7 @@ #include "stream.h" #include "parser.h" -static val sym_helper(void *scnr, wchar_t *lexeme, val meta_allowed); +static val sym_helper(scanner_t *scnr, wchar_t *lexeme, val meta_allowed); static val repeat_rep_helper(val sym, val args, val main, val parts); static val define_transform(parser_t *parser, val define_form); static val lit_char_helper(val litchars); @@ -72,7 +72,7 @@ int yylex(union YYSTYPE *, void *scanner); %} %pure-parser -%parse-param{void *scnr} +%parse-param{scanner_t *scnr} %parse-param{parser_t *parser} %lex-param{void *scnr} @@ -986,7 +986,7 @@ int yylex(YYSTYPE *, void *scanner); val rlcp(val to, val from); #endif -static val sym_helper(void *scnr, wchar_t *lexeme, val meta_allowed) +static val sym_helper(scanner_t *scnr, wchar_t *lexeme, val meta_allowed) { int leading_at = *lexeme == L'@'; wchar_t *tokfree = lexeme; @@ -1081,7 +1081,7 @@ static val repeat_rep_helper(val sym, val args, val main, val parts) static val define_transform(parser_t *parser, val define_form) { - void *scnr = parser->scanner; + scanner_t *scnr = parser->scanner; val sym = first(define_form); val args = second(define_form); @@ -1280,7 +1280,7 @@ static val make_expr(parser_t *parser, val sym, val rest, val lineno) void yybadtoken(parser_t *parser, int tok, val context) { val problem = nil; - void *scnr = parser->scanner; + scanner_t *scnr = parser->scanner; switch (tok) { case ERRTOK: @@ -1354,6 +1354,7 @@ void yybadtoken(parser_t *parser, int tok, val context) int parse(val stream, val name, parser_t *parser) { int res; + void *scanner; parser->lineno = 1; parser->errors = 0; @@ -1361,7 +1362,8 @@ int parse(val stream, val name, parser_t *parser) parser->name = name; parser->prepared_msg = nil; parser->syntax_tree = nil; - yylex_init(&parser->scanner); + yylex_init(&scanner); + parser->scanner = (scanner_t *) scanner; yyset_extra(parser, parser->scanner); -- cgit v1.2.3