From: Dale Weiler Date: Fri, 4 Jan 2013 11:56:07 +0000 (+0000) Subject: Merge branch 'correct' X-Git-Tag: before-library~373 X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=commitdiff_plain;h=2d96b2a3ecb3610493c261c297da8a0ed429cd15;hp=-c Merge branch 'correct' --- 2d96b2a3ecb3610493c261c297da8a0ed429cd15 diff --combined parser.c index 229d2ec,b7831d4..2d7ebe3 --- a/parser.c +++ b/parser.c @@@ -74,6 -74,10 +74,10 @@@ typedef struct ht htglobals; ht *typedefs; + /* same as above but for the spelling corrector */ + ht *correct_variables; + size_t ***correct_variables_score; /* vector of vector of size_t* */ + /* not to be used directly, we use the hash table */ ast_expression **_locals; size_t *_blocklocals; @@@ -1614,13 -1618,15 +1618,15 @@@ static ast_expression* parse_expression } else { + size_t i; + char *correct = NULL; + /* * sometimes people use preprocessing predefs without enabling them * i've done this thousands of times already myself. Lets check for * it in the predef table. And diagnose it better :) */ if (!OPTS_FLAG(FTEPP_PREDEFS)) { - size_t i; for (i = 0; i < sizeof(ftepp_predefs)/sizeof(*ftepp_predefs); i++) { if (!strcmp(ftepp_predefs[i].name, parser_tokval(parser))) { parseerror(parser, "unexpected ident: %s (use -fftepp-predef to enable pre-defined macros)", parser_tokval(parser)); @@@ -1629,7 -1635,29 +1635,29 @@@ } } - parseerror(parser, "unexpected ident: %s", parser_tokval(parser)); + /* + * TODO: determine the best score for the identifier: be it + * a variable, a field. + * + * We should also consider adding correction tables for + * other things as well. + */ + for (i = 0; i < vec_size(parser->correct_variables); i++) { + correct = correct_str(parser->correct_variables[i], "ello"); + if (strcmp(correct, parser_tokval(parser))) { + break; + } else if (correct) { + mem_d(correct); + } + } + + if (correct) { + parseerror(parser, "unexpected ident: %s (did you mean %s?)", parser_tokval(parser), correct); + mem_d(correct); + } else { + parseerror(parser, "unexpected ident: %s", parser_tokval(parser)); + } + goto onerr; } } @@@ -1968,6 -1996,10 +1996,10 @@@ static void parser_enterblock(parser_t vec_push(parser->typedefs, util_htnew(TYPEDEF_HT_SIZE)); vec_push(parser->_blocktypedefs, vec_size(parser->_typedefs)); vec_push(parser->_block_ctx, parser_ctx(parser)); + + /* corrector */ + vec_push(parser->correct_variables, util_htnew(PARSER_HT_SIZE)); + vec_push(parser->correct_variables_score, NULL); } static bool parser_leaveblock(parser_t *parser) @@@ -1981,7 -2013,11 +2013,11 @@@ } util_htdel(vec_last(parser->variables)); + correct_del(vec_last(parser->correct_variables), vec_last(parser->correct_variables_score)); + vec_pop(parser->variables); + vec_pop(parser->correct_variables); + vec_pop(parser->correct_variables_score); if (!vec_size(parser->_blocklocals)) { parseerror(parser, "internal error: parser_leaveblock with no block (2)"); return false; @@@ -2008,6 -2044,7 +2044,7 @@@ vec_pop(parser->typedefs); vec_pop(parser->_block_ctx); + return rv; } @@@ -2015,6 -2052,13 +2052,13 @@@ static void parser_addlocal(parser_t *p { vec_push(parser->_locals, e); util_htset(vec_last(parser->variables), name, (void*)e); + + /* corrector */ + correct_add ( + vec_last(parser->correct_variables), + &vec_last(parser->correct_variables_score), + name + ); } static ast_expression* process_condition(parser_t *parser, ast_expression *cond, bool *_ifnot) @@@ -2999,35 -3043,28 +3043,35 @@@ static bool parse_switch_go(parser_t *p } /* parse computed goto sides */ -static ast_expression *parse_goto_computed(parser_t *parser, ast_expression *side) { +static ast_expression *parse_goto_computed(parser_t *parser, ast_expression **side) { ast_expression *on_true; ast_expression *on_false; + ast_expression *cond; - if (!side) + if (!*side) return NULL; - if (ast_istype(side, ast_ternary)) { - on_true = parse_goto_computed(parser, ((ast_ternary*)side)->on_true); - on_false = parse_goto_computed(parser, ((ast_ternary*)side)->on_false); + if (ast_istype(*side, ast_ternary)) { + ast_ternary *tern = (ast_ternary*)*side; + on_true = parse_goto_computed(parser, &tern->on_true); + on_false = parse_goto_computed(parser, &tern->on_false); if (!on_true || !on_false) { parseerror(parser, "expected label or expression in ternary"); - if (((ast_ternary*)side)->on_false) ast_unref(((ast_ternary*)side)->on_false); - if (((ast_ternary*)side)->on_true) ast_unref(((ast_ternary*)side)->on_true); + if (on_true) ast_unref(on_true); + if (on_false) ast_unref(on_false); return NULL; } - return (ast_expression*)ast_ifthen_new(parser_ctx(parser), ((ast_ternary*)side)->cond, on_true, on_false); - } else if (ast_istype(side, ast_label)) { - ast_goto *gt = ast_goto_new(parser_ctx(parser), ((ast_label*)side)->name); - ast_goto_set_label(gt, ((ast_label*)side)); + cond = tern->cond; + tern->cond = NULL; + ast_delete(tern); + *side = NULL; + return (ast_expression*)ast_ifthen_new(parser_ctx(parser), cond, on_true, on_false); + } else if (ast_istype(*side, ast_label)) { + ast_goto *gt = ast_goto_new(parser_ctx(parser), ((ast_label*)*side)->name); + ast_goto_set_label(gt, ((ast_label*)*side)); + *side = NULL; return (ast_expression*)gt; } return NULL; @@@ -3052,7 -3089,7 +3096,7 @@@ static bool parse_goto(parser_t *parser /* failed to parse expression for goto */ if (!(expression = parse_expression(parser, false, true)) || - !(*out = parse_goto_computed(parser, expression))) { + !(*out = parse_goto_computed(parser, &expression))) { parseerror(parser, "invalid goto expression"); ast_unref(expression); return false; @@@ -3549,6 -3586,7 +3593,7 @@@ static bool parse_function_body(parser_ vec_push(parser->globals, (ast_expression*)thinkfunc); util_htset(parser->htglobals, thinkfunc->name, thinkfunc); + nextthink = (ast_expression*)thinkfunc; } else { @@@ -4790,6 -4828,14 +4835,14 @@@ static bool parse_variable(parser_t *pa /* Add it to the local scope */ util_htset(vec_last(parser->variables), var->name, (void*)var); + + /* corrector */ + correct_add ( + vec_last(parser->correct_variables), + &vec_last(parser->correct_variables_score), + var->name + ); + /* now rename the global */ ln = strlen(var->name); vec_append(defname, ln, var->name); @@@ -4803,6 -4849,13 +4856,13 @@@ for (i = 0; i < 3; ++i) { util_htset(vec_last(parser->variables), me[i]->name, (void*)(me[i])); + /* corrector */ + correct_add( + vec_last(parser->correct_variables), + &vec_last(parser->correct_variables_score), + me[i]->name + ); + vec_shrinkto(defname, prefix_len); ln = strlen(me[i]->name); vec_append(defname, ln, me[i]->name); @@@ -5349,6 -5402,17 +5409,17 @@@ void parser_cleanup( vec_free(parser->_blocklocals); vec_free(parser->_locals); + /* corrector */ + for (i = 0; i < vec_size(parser->correct_variables); ++i) { + correct_del(parser->correct_variables[i], parser->correct_variables_score[i]); + } + for (i = 0; i < vec_size(parser->correct_variables_score); ++i) { + vec_free(parser->correct_variables_score[i]); + } + vec_free(parser->correct_variables); + vec_free(parser->correct_variables_score); + + for (i = 0; i < vec_size(parser->_typedefs); ++i) ast_delete(parser->_typedefs[i]); vec_free(parser->_typedefs);