acc_code: parse from the constructor

* spot/twa/acc.hh, spot/twa/acc.cc (parse_acc_code): Rename as...
(acc_cond::acc_code): ... this, making it a lot easier to build
acceptance conditions from strings.
* NEWS: Mention the change.
* spot/twaalgos/dtwasat.cc, spot/bin/randaut.cc, spot/tests/acc.cc:
Adjust.
* wrap/python/tests/acc_cond.ipynb, wrap/python/tests/accparse.ipynb,
wrap/python/tests/accparse2.py: Simplify, but not completely to exercise
all variants.
* wrap/python/spot_impl.i: Make acc_code's constructor implicit.
This commit is contained in:
Alexandre Duret-Lutz 2015-12-18 17:47:16 +01:00
parent d0b29051b2
commit df1ef302e8
10 changed files with 189 additions and 133 deletions

View file

@ -347,7 +347,7 @@ main(int argc, char** argv)
spot::acc_cond::acc_code code;
if (opt_acceptance)
{
code = spot::parse_acc_code(opt_acceptance);
code = spot::acc_cond::acc_code(opt_acceptance);
accs = code.used_sets().max_set();
if (opt_colored && accs == 0)
error(2, 0, "--colored requires at least one acceptance set; "

View file

@ -158,14 +158,14 @@ int main()
std::cout << code3 << ' ' << "{0} false\n";
print(code3.missing(m, false));
std::cout << spot::parse_acc_code("t") << '\n';
std::cout << spot::parse_acc_code("f") << '\n';
std::cout << spot::parse_acc_code("Fin(2)") << '\n';
std::cout << spot::parse_acc_code("Inf(2)") << '\n';
std::cout << spot::parse_acc_code("Fin(2) | Inf(2)") << '\n';
std::cout << spot::parse_acc_code("Inf(2) & Fin(2)") << '\n';
auto c1 = spot::parse_acc_code("Fin(0)|Inf(1)&Fin(2)|Fin(3)");
auto c2 = spot::parse_acc_code
std::cout << spot::acc_cond::acc_code("t") << '\n';
std::cout << spot::acc_cond::acc_code("f") << '\n';
std::cout << spot::acc_cond::acc_code("Fin(2)") << '\n';
std::cout << spot::acc_cond::acc_code("Inf(2)") << '\n';
std::cout << spot::acc_cond::acc_code("Fin(2) | Inf(2)") << '\n';
std::cout << spot::acc_cond::acc_code("Inf(2) & Fin(2)") << '\n';
auto c1 = spot::acc_cond::acc_code("Fin(0)|Inf(1)&Fin(2)|Fin(3)");
auto c2 = spot::acc_cond::acc_code
("( Fin ( 0 )) | (Inf ( 1) & Fin(2 ))| Fin (3) ");
std::cout << c1 << '\n';
std::cout << c2 << '\n';

View file

@ -1544,7 +1544,7 @@ namespace spot
}
acc_cond::acc_code parse_acc_code(const char* input)
acc_cond::acc_code::acc_code(const char* input)
{
skip_space(input);
acc_cond::acc_code c;
@ -1630,6 +1630,6 @@ namespace spot
s << "syntax error at '" << input << "', unexpected character.";
throw parse_error(s.str());
}
return c;
std::swap(c, *this);
}
}

View file

@ -889,6 +889,38 @@ namespace spot
std::function<void(std::ostream&, int)>
set_printer = nullptr) const;
/// \brief Construct an acc_code from a string.
///
/// The string can follow the following grammar:
///
/// <pre>
/// acc ::= "t"
/// | "f"
/// | "Inf" "(" num ")"
/// | "Fin" "(" num ")"
/// | "(" acc ")"
/// | acc "&" acc
/// | acc "|" acc
/// </pre>
///
/// Where num is an integer and "&" has priority over "|". Note that
/// "Fin(!x)" and "Inf(!x)" are not supported by this parser.
///
/// Or the string can be the name of an acceptance condition, as
/// speficied in the HOA format. (E.g. "Rabin 2", "parity max odd 3",
/// "generalized-Rabin 4 2 1", etc.).
///
/// A spot::parse_error is thrown on syntax error.
acc_code(const char* input);
/// \brief Build an empty acceptance condition.
///
/// This is the same as t().
acc_code()
{
}
// Calls to_text
SPOT_API
friend std::ostream& operator<<(std::ostream& os, const acc_code& code);
@ -1167,26 +1199,6 @@ namespace spot
};
/// \brief Parse a string into an acc_code
///
/// The string should follow the following grammar:
///
/// <pre>
/// acc ::= "t"
/// | "f"
/// | "Inf" "(" num ")"
/// | "Fin" "(" num ")"
/// | "(" acc ")"
/// | acc "&" acc
/// | acc "|" acc
/// </pre>
///
/// Where num is an integer and "&" has priority over "|". Note that
/// "Fin(!x)" and "Inf(!x)" are not supported by this parser.
///
/// A spot::parse_error is thrown on syntax error.
SPOT_API acc_cond::acc_code parse_acc_code(const char* input);
SPOT_API
std::ostream& operator<<(std::ostream& os, const acc_cond& acc);
}

View file

@ -1313,7 +1313,7 @@ namespace spot
if (!accstr.empty())
{
user_supplied_acc = true;
target_acc = parse_acc_code(accstr.c_str());
target_acc = acc_cond::acc_code(accstr.c_str());
// Just in case we were given something like
// Fin(1) | Inf(3)
// Rewrite it as