Skip to content

Commit

Permalink
Don't fail when zero condition <> has no end-of-inpt rule $.
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
skvadrik committed Dec 28, 2024
1 parent 2b80343 commit 90bd315
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/adfa/adfa.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 4 additions & 2 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ LOCAL_NODISCARD(Ret ast_to_dfa(
const loc_t& loc = block.loc;
Msg& msg = output.msg;
const std::vector<AstRule>& 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;

Expand Down Expand Up @@ -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);

Expand Down
3 changes: 2 additions & 1 deletion src/parse/ast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
}
Expand Down
58 changes: 57 additions & 1 deletion test/conditions/condition_16.c
Original file line number Diff line number Diff line change
@@ -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"; }
}

0 comments on commit 90bd315

Please sign in to comment.