diff --git a/NEWS b/NEWS index feef2c0d8..96e3d3431 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,10 @@ New in spot 2.11.2.dev (not yet released) otherwise, libraries get installed in the wrong place on Debian. (Issue #512.) + - The HOA parser used to silently declare unused and undefined states + (e.g., when the State: header declare many more states than the body + of the file). It now warns about those. + New in spot 2.11.2 (2022-10-26) Command-line tools: diff --git a/spot/parseaut/parseaut.yy b/spot/parseaut/parseaut.yy index 52d448c16..4d96b8c1c 100644 --- a/spot/parseaut/parseaut.yy +++ b/spot/parseaut/parseaut.yy @@ -1231,6 +1231,7 @@ body: states // diagnostic, so let not add another one. if (res.states >= 0) n = res.states; + std::vector unused_undeclared; for (unsigned i = 0; i < n; ++i) { auto& p = res.info_states[i]; @@ -1239,17 +1240,43 @@ body: states if (p.used) error(p.used_loc, "state " + std::to_string(i) + " has no definition"); - if (!p.used && res.complete) - if (auto p = res.prop_is_true("complete")) - { - error(res.states_loc, - "state " + std::to_string(i) + - " has no definition..."); - error(p.loc, "... despite 'properties: complete'"); - } + if (!p.used) + unused_undeclared.push_back(i); res.complete = false; } } + if (!unused_undeclared.empty()) + { + std::ostringstream out; + unsigned uus = unused_undeclared.size(); + int rangestart = -2; + int rangecur = -2; + const char* sep = uus > 1 ? "states " : "state "; + auto print_range = [&]() { + if (rangecur < 0) + return; + out << sep << rangestart; + if (rangecur != rangestart) + out << '-' << rangecur; + sep = ","; + }; + for (unsigned s: unused_undeclared) + { + if ((int)s != rangecur + 1) + { + print_range(); + rangestart = s; + } + rangecur = s; + } + print_range(); + out << (uus > 1 ? " are" : " is") << " unused and undefined"; + error(res.states_loc, out.str()); + + if (auto p = res.prop_is_true("complete")) + error(p.loc, "automaton is incomplete because it has " + "undefined states"); + } if (res.complete) if (auto p = res.prop_is_false("complete")) { diff --git a/tests/core/parseaut.test b/tests/core/parseaut.test index 56f2d54eb..7dabd563d 100755 --- a/tests/core/parseaut.test +++ b/tests/core/parseaut.test @@ -230,6 +230,7 @@ input:3.1-8: initial state number is larger than state count... input:4.1-9: ... declared here. input:1.1-4.9: missing 'Acceptance:' header input:3.1-8: initial state 1 has no definition +input:4.1-9: state 0 is unused and undefined EOF cat >input <