From 90bd3158e17089709e5a7cfff93b1c34b1b710f5 Mon Sep 17 00:00:00 2001 From: Ulya Trofimovich Date: Sat, 28 Dec 2024 10:25:49 +0000 Subject: [PATCH] Don't fail when zero condition `<>` has no end-of-inpt rule `$`. Previously re2c failed with an error in the case when end-of-input rule `$` was enabled and the special zero condition `<>` was used. Now it no longer fails and generates code withot end-of-input check for the zero condition (which is handled in a special way by the code, bypassing some of the transformations that rely on the presence of end-of-input rule). --- src/adfa/adfa.cc | 2 +- src/main.cc | 6 ++-- src/parse/ast.cc | 3 +- test/conditions/condition_16.c | 58 +++++++++++++++++++++++++++++++++- 4 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/adfa/adfa.cc b/src/adfa/adfa.cc index bbe85eb98..c2cebefe0 100644 --- a/src/adfa/adfa.cc +++ b/src/adfa/adfa.cc @@ -320,7 +320,7 @@ void Adfa::prepare(const opt_t* opts) { } // last state, add end-of-input rule $ if needed (see note [end-of-input rule]) - if (!s->next && opts->fill_eof != NOEOF) { + if (!s->next && opts->fill_eof != NOEOF && cond != "0") { eof_state = new State; eof_state->action.set_rule(eof_rule); finstates[eof_rule] = eof_state; diff --git a/src/main.cc b/src/main.cc index dd5fa3513..5b93bc93e 100644 --- a/src/main.cc +++ b/src/main.cc @@ -55,7 +55,7 @@ LOCAL_NODISCARD(Ret ast_to_dfa( const loc_t& loc = block.loc; Msg& msg = output.msg; const std::vector& ast = gram.rules; - const std::string&cond = gram.name; + const std::string& cond = gram.name; const std::string name = make_name(output, cond, loc); const std::string& setup = gram.setup.empty() ? "" : gram.setup[0]->text; @@ -87,7 +87,9 @@ LOCAL_NODISCARD(Ret ast_to_dfa( output.skeletons.insert(name); } - cutoff_dead_rules(dfa, opts, cond, msg); + if (cond != "0") { + cutoff_dead_rules(dfa, opts, cond, msg); + } insert_fallback_tags(dfa); diff --git a/src/parse/ast.cc b/src/parse/ast.cc index b71d6d81a..e325564d0 100644 --- a/src/parse/ast.cc +++ b/src/parse/ast.cc @@ -391,12 +391,13 @@ Ret check_and_merge_special_rules(AstGrams& grams, const opt_t* opts, Msg& msg, // Check that `re2c:eof` configuration and the $ rule are used together. This must be done after // merging rules inherited from other blocks and <*> condition (because they might add $ rule). + // Skip "0" condition, as it's a special one that has no rules and always matches empty string. for (const AstGram& g : grams) { if (!g.eofs.empty() && opts->fill_eof == NOEOF) { RET_FAIL(msg.error(g.eofs[0]->loc, "%s$ rule found, but `re2c:eof` configuration is not set", incond(g.name).c_str())); - } else if (g.eofs.empty() && opts->fill_eof != NOEOF) { + } else if (g.eofs.empty() && opts->fill_eof != NOEOF && g.name != "0") { RET_FAIL(error("%s`re2c:eof` configuration is set, but no $ rule found", incond(g.name).c_str())); } diff --git a/test/conditions/condition_16.c b/test/conditions/condition_16.c index 91fee2219..972b59210 100644 --- a/test/conditions/condition_16.c +++ b/test/conditions/condition_16.c @@ -1 +1,57 @@ -re2c: error: in condition '0' `re2c:eof` configuration is set, but no $ rule found +/* Generated by re2c */ +// re2c $INPUT -o $OUTPUT -ci + +{ + YYCTYPE yych; + switch (YYGETCONDITION()) { + case yyc0: goto yyc_0; + case yycx: goto yyc_x; + case yycy: goto yyc_y; + } +/* *********************************** */ +yyc_0: + { return NULL; } +/* *********************************** */ +yyc_x: +yyFillLabel0: + yych = *YYCURSOR; + switch (yych) { + case 'a': goto yy3; + default: + if (YYLIMIT <= YYCURSOR) { + if (YYFILL() == 0) goto yyFillLabel0; + goto yy4; + } + goto yy2; + } +yy2: + ++YYCURSOR; + { return "*"; } +yy3: + ++YYCURSOR; + { return "a"; } +yy4: + { return "$"; } +/* *********************************** */ +yyc_y: +yyFillLabel1: + yych = *YYCURSOR; + switch (yych) { + case 'a': goto yy7; + default: + if (YYLIMIT <= YYCURSOR) { + if (YYFILL() == 0) goto yyFillLabel1; + goto yy8; + } + goto yy6; + } +yy6: + ++YYCURSOR; + { return "*"; } +yy7: + ++YYCURSOR; + { return "a"; } +yy8: + { return "$y"; } +} +