parsetl: change the interface to return a parsed_formula

This gets the interface of all the functions parsing formula in line
with the interface of the automaton parser: both return a "parsed_*"
object (parsed_formula or parsed_automaton) that contains the said
object and its list of errors.  Doing so avoid having to declare the
parse_error_list in advance.

* spot/tl/parse.hh, spot/parsetl/parsetl.yy: Do the change.
* spot/parsetl/fmterror.cc: Adjust the error printer.
* NEWS: Document it.
* bin/common_finput.cc, bin/common_finput.hh, bin/ltlcross.cc,
bin/ltldo.cc, bin/ltlfilt.cc, doc/org/tut01.org, doc/org/tut02.org,
doc/org/tut10.org, doc/org/tut20.org, python/ajax/spotcgi.in,
python/spot/impl.i, spot/parseaut/parseaut.yy, tests/core/checkpsl.cc,
tests/core/checkta.cc, tests/core/consterm.cc, tests/core/emptchk.cc,
tests/core/equalsf.cc, tests/core/ikwiad.cc, tests/core/kind.cc,
tests/core/length.cc, tests/core/ltlprod.cc, tests/core/ltlrel.cc,
tests/core/randtgba.cc, tests/core/readltl.cc, tests/core/reduc.cc,
tests/core/safra.cc, tests/core/syntimpl.cc, tests/core/tostring.cc,
tests/ltsmin/modelcheck.cc, tests/python/alarm.py,
tests/python/interdep.py, tests/python/ltl2tgba.py,
tests/python/ltlparse.py: Adjust all uses.
This commit is contained in:
Alexandre Duret-Lutz 2016-02-17 19:39:43 +01:00
parent cf4f58c34b
commit 22f442f758
37 changed files with 359 additions and 374 deletions

26
NEWS
View file

@ -102,6 +102,32 @@ New in spot 1.99.7a (not yet released)
* The twa::transition_annotation() and * The twa::transition_annotation() and
twa::compute_support_conditions() methods have been removed. twa::compute_support_conditions() methods have been removed.
* The interface for all functions parsing formulas (LTL, PSL, SERE,
etc.) has been changed to use an interface similar to the one used
for parsing automata. These function now return a parsed_formula
object that includes both a formula and a list of syntax errors.
Typically a function written as
spot::formula read(std::string input)
{
spot::parse_error_list pel;
spot::formula f = spot::parse_infix_psl(input, pel);
if (spot::format_parse_errors(std::cerr, input, pel))
exit(2);
return f;
}
should be updated to
spot::formula read(std::string input)
{
spot::parsed_formula pf = spot::parse_infix_psl(input);
if (pf.format_errors(std::cerr))
exit(2);
return pf.f;
}
Python: Python:
* The ltsmin interface has been binded in Python. It also * The ltsmin interface has been binded in Python. It also

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et // Copyright (C) 2012, 2013, 2014, 2015, 2016 Laboratoire de Recherche
// Développement de l'Epita (LRDE). // et Développement de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
// //
@ -76,14 +76,14 @@ parse_opt_finput(int key, char* arg, struct argp_state*)
return 0; return 0;
} }
spot::formula spot::parsed_formula
parse_formula(const std::string& s, spot::parse_error_list& pel) parse_formula(const std::string& s)
{ {
if (lbt_input) if (lbt_input)
return spot::parse_prefix_ltl(s, pel); return spot::parse_prefix_ltl(s);
else else
return spot::parse_infix_psl return spot::parse_infix_psl
(s, pel, spot::default_environment::instance(), false, lenient); (s, spot::default_environment::instance(), false, lenient);
} }
job_processor::job_processor() job_processor::job_processor()
@ -108,17 +108,16 @@ job_processor::process_string(const std::string& input,
const char* filename, const char* filename,
int linenum) int linenum)
{ {
spot::parse_error_list pel; auto pf = parse_formula(input);
auto f = parse_formula(input, pel);
if (!f || !pel.empty()) if (!pf.f || !pf.errors.empty())
{ {
if (filename) if (filename)
error_at_line(0, 0, filename, linenum, "parse error:"); error_at_line(0, 0, filename, linenum, "parse error:");
spot::format_parse_errors(std::cerr, input, pel); pf.format_errors(std::cerr);
return 1; return 1;
} }
return process_formula(f, filename, linenum); return process_formula(pf.f, filename, linenum);
} }
int int

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2012, 2013, 2015 Laboratoire de Recherche et // Copyright (C) 2012, 2013, 2015, 2016 Laboratoire de Recherche et
// Développement de l'Epita (LRDE). // Développement de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
@ -44,8 +44,7 @@ extern const struct argp finput_argp;
int parse_opt_finput(int key, char* arg, struct argp_state* state); int parse_opt_finput(int key, char* arg, struct argp_state* state);
spot::formula spot::parsed_formula parse_formula(const std::string& s);
parse_formula(const std::string& s, spot::parse_error_list& error_list);
class job_processor class job_processor

View file

@ -837,16 +837,15 @@ namespace
const char* filename, const char* filename,
int linenum) int linenum)
{ {
spot::parse_error_list pel; auto pf = parse_formula(input);
spot::formula f = parse_formula(input, pel); if (!pf.f || !pf.errors.empty())
if (!f || !pel.empty())
{ {
if (filename) if (filename)
error_at_line(0, 0, filename, linenum, "parse error:"); error_at_line(0, 0, filename, linenum, "parse error:");
spot::format_parse_errors(std::cerr, input, pel); pf.format_errors(std::cerr);
return 1; return 1;
} }
auto f = pf.f;
int res = process_formula(f, filename, linenum); int res = process_formula(f, filename, linenum);

View file

@ -237,19 +237,18 @@ namespace
const char* filename, const char* filename,
int linenum) int linenum)
{ {
spot::parse_error_list pel; spot::parsed_formula pf = parse_formula(input);
spot::formula f = parse_formula(input, pel);
if (!f || !pel.empty()) if (!pf.f || !pf.errors.empty())
{ {
if (filename) if (filename)
error_at_line(0, 0, filename, linenum, "parse error:"); error_at_line(0, 0, filename, linenum, "parse error:");
spot::format_parse_errors(std::cerr, input, pel); pf.format_errors(std::cerr);
return 1; return 1;
} }
inputf = input; inputf = input;
process_formula(f, filename, linenum); process_formula(pf.f, filename, linenum);
return 0; return 0;
} }

View file

@ -288,11 +288,10 @@ static std::string unabbreviate;
static spot::formula static spot::formula
parse_formula_arg(const std::string& input) parse_formula_arg(const std::string& input)
{ {
spot::parse_error_list pel; spot::parsed_formula pf = parse_formula(input);
spot::formula f = parse_formula(input, pel); if (pf.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, input, pel))
error(2, 0, "parse error when parsing an argument"); error(2, 0, "parse error when parsing an argument");
return f; return pf.f;
} }
static int static int
@ -482,20 +481,19 @@ namespace
process_string(const std::string& input, process_string(const std::string& input,
const char* filename = nullptr, int linenum = 0) const char* filename = nullptr, int linenum = 0)
{ {
spot::parse_error_list pel; spot::parsed_formula pf = parse_formula(input);
spot::formula f = parse_formula(input, pel);
if (!f || pel.size() > 0) if (!pf.f || !pf.errors.empty())
{ {
if (!ignore_errors) if (!ignore_errors)
{ {
if (filename) if (filename)
error_at_line(0, 0, filename, linenum, "parse error:"); error_at_line(0, 0, filename, linenum, "parse error:");
spot::format_parse_errors(std::cerr, input, pel); pf.format_errors(std::cerr);
} }
if (error_style == skip_errors) if (error_style == skip_errors)
std::cout << input << std::endl; std::cout << input << '\n';
else else
assert(error_style == drop_errors); assert(error_style == drop_errors);
check_cout(); check_cout();
@ -503,7 +501,7 @@ namespace
} }
try try
{ {
return process_formula(f, filename, linenum); return process_formula(pf.f, filename, linenum);
} }
catch (const std::runtime_error& e) catch (const std::runtime_error& e)
{ {

View file

@ -119,11 +119,10 @@ Here is how to call the infix parser explicitly:
int main() int main()
{ {
std::string input = "[]<>p0 || <>[]p1"; std::string input = "[]<>p0 || <>[]p1";
spot::parse_error_list pel; spot::parsed_formula pf = spot::parse_infix_psl(input);
spot::formula f = spot::parse_infix_psl(input, pel); if (pf.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, input, pel))
return 1; return 1;
std::cout << f << '\n'; std::cout << pf.f << '\n';
return 0; return 0;
} }
#+END_SRC #+END_SRC
@ -131,26 +130,27 @@ Here is how to call the infix parser explicitly:
#+RESULTS: #+RESULTS:
: GFp0 | FGp1 : GFp0 | FGp1
So =parse_infix_psl()= processes =input=, and stores any diagnostic in Note that as its name implies, this parser can read more than LTL
=pel=, which is a list of pairs associating each error to a location. formulas: the fragment of PSL we support is basically LTL extended
You could iterate over that list to print it by yourself as you wish, with regular expressions.
or you can call =format_parse_errors()= to do that for you. Note that
as its name implies, this parser can read more than LTL formulas (the
fragment of PSL we support is basically LTL extended with regular
expressions).
If =pel= is empty, =format_parse_errors()= will do nothing and return The =parse_infix_psl()= function processes =input=, and returns a
false. =spot::parsed_formula= object. In addition to the =spot::formula= we
desire (stored as the =spot::parsed_formula::f= attribute), the
=spot::parsed_formula= also stores any diagnostic collected during the
parsing. Those diagnostics are stored in the
=spot::parsed_formula::errors= attribute, but they can conveniently be
printed by calling the =spot::parsed::format_errors()= method: this
method returns true if and only if a diagnostic was output, so this is
usually used to abort the program with an error status as above.
If =pel= is non empty, =format_parse_errors()= will display the errors
messages and return true. In the above code, we have decided to
aborts the execution in this case.
However the parser usually tries to do some error recovery. For The parser usually tries to do some error recovery, so the =f=
instance if you have input =(a U b))= the parser will complain about attribute can be non-null even if some parsing errors where returned.
the extra parenthesis (=pel= not empty), but it will still return an For instance if you have input =(a U b))= the parser will complain
=f= that is equivalent to =a U b=. So you could decide to continue about the extra parenthesis, but it will still return a formula that
with the "fixed" formula if you wish. Here is an example: is equivalent to =a U b=. So you could decide to continue with the
"fixed" formula if you wish. Here is an example:
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++ :results verbatim :exports both
#include <string> #include <string>
@ -161,14 +161,13 @@ with the "fixed" formula if you wish. Here is an example:
int main() int main()
{ {
std::string input = "(a U b))"; std::string input = "(a U b))";
spot::parse_error_list pel; spot::parsed_formula pf = spot::parse_infix_psl(input);
spot::formula f = spot::parse_infix_psl(input, pel);
// Use std::cout instead of std::cerr because we can only // Use std::cout instead of std::cerr because we can only
// show the output of std::cout in this documentation. // show the output of std::cout in this documentation.
(void) spot::format_parse_errors(std::cout, input, pel); (void) pf.format_errors(std::cout);
if (f == nullptr) if (pf.f == nullptr)
return 1; return 1;
std::cout << "Parsed formula: " << f << '\n'; std::cout << "Parsed formula: " << pf.f << '\n';
return 0; return 0;
} }
#+END_SRC #+END_SRC
@ -185,8 +184,8 @@ with the "fixed" formula if you wish. Here is an example:
: Parsed formula: a U b : Parsed formula: a U b
The formula =f= is only returned as null when the parser really cannot The formula =pf.f= would only be returned as null when the parser
recover anything. really cannot recover anything.
** Calling the prefix parser explicitly ** Calling the prefix parser explicitly
@ -202,10 +201,10 @@ of =parse_infix_psl()=.
int main() int main()
{ {
std::string input = "& & G p0 p1 p2"; std::string input = "& & G p0 p1 p2";
spot::parse_error_list pel; spot::parsed_formula pf = spot::parse_prefix_ltl(input);
spot::formula f = spot::parse_prefix_ltl(input, pel); if (pf.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, input, pel))
return 1; return 1;
spot::formula f = pf.f;
print_latex_psl(std::cout, f) << '\n'; print_latex_psl(std::cout, f) << '\n';
print_lbt_ltl(std::cout, f) << '\n'; print_lbt_ltl(std::cout, f) << '\n';
print_spin_ltl(std::cout, f, true) << '\n'; print_spin_ltl(std::cout, f, true) << '\n';
@ -246,11 +245,10 @@ For instance, let's see what happens if a PSL formulas is passed to
int main() int main()
{ {
std::string input = "{a*;b}<>->(a U (b & GF c))"; std::string input = "{a*;b}<>->(a U (b & GF c))";
spot::parse_error_list pel; spot::parsed_formula pf = spot::parse_infix_psl(input);
spot::formula f = spot::parse_infix_psl(input, pel); if (pf.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, input, pel))
return 1; return 1;
print_spin_ltl(std::cout, f) << '\n'; print_spin_ltl(std::cout, pf.f) << '\n';
return 0; return 0;
} }
#+END_SRC #+END_SRC
@ -276,10 +274,10 @@ The first is to simply diagnose non-LTL formulas.
int main() int main()
{ {
std::string input = "{a*;b}<>->(a U (b & GF c))"; std::string input = "{a*;b}<>->(a U (b & GF c))";
spot::parse_error_list pel; spot::parsed_formula pf = spot::parse_infix_psl(input);
spot::formula f = spot::parse_infix_psl(input, pel); if (pf.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, input, pel))
return 1; return 1;
spot::formula f = pf.f;
if (!f.is_ltl_formula()) if (!f.is_ltl_formula())
{ {
std::cerr << "Only LTL formulas are supported.\n"; std::cerr << "Only LTL formulas are supported.\n";
@ -306,10 +304,10 @@ prepared to reject the formula any way. In our example, we are lucky
int main() int main()
{ {
std::string input = "{a*;b}<>->(a U (b & GF c))"; std::string input = "{a*;b}<>->(a U (b & GF c))";
spot::parse_error_list pel; spot::parsed_formula pf = spot::parse_infix_psl(input);
spot::formula f = spot::parse_infix_psl(input, pel); if (pf.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, input, pel))
return 1; return 1;
spot::formula f = pf.f;
if (!f.is_ltl_formula()) if (!f.is_ltl_formula())
{ {
spot::tl_simplifier simp; spot::tl_simplifier simp;

View file

@ -85,10 +85,10 @@ destructor.
int main() int main()
{ {
std::string input = "\"Proc@Here\" U (\"var > 10\" | \"var < 4\")"; std::string input = "\"Proc@Here\" U (\"var > 10\" | \"var < 4\")";
spot::parse_error_list pel; spot::parsed_formula pf = spot::parse_infix_psl(input);
spot::formula f = spot::parse_infix_psl(input, pel); if (pf.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, input, pel))
return 1; return 1;
spot::formula f = pf.f;
spot::relabeling_map m; spot::relabeling_map m;
f = spot::relabel(f, spot::Pnn, &m); f = spot::relabel(f, spot::Pnn, &m);
for (auto& i: m) for (auto& i: m)

View file

@ -137,13 +137,12 @@ never claim is done via the =print_never_claim= function.
int main() int main()
{ {
std::string input = "[]<>p0 || <>[]p1"; std::string input = "[]<>p0 || <>[]p1";
spot::parse_error_list pel; spot::parsed_formula pf = spot::parse_infix_psl(input);
spot::formula f = spot::parse_infix_psl(input, pel); if (pf.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, input, pel))
return 1; return 1;
spot::translator trans; spot::translator trans;
trans.set_type(spot::postprocessor::BA); trans.set_type(spot::postprocessor::BA);
spot::twa_graph_ptr aut = trans.run(f); spot::twa_graph_ptr aut = trans.run(pf.f);
print_never_claim(std::cout, aut) << '\n'; print_never_claim(std::cout, aut) << '\n';
return 0; return 0;
} }
@ -154,23 +153,23 @@ never claim is done via the =print_never_claim= function.
never { never {
T0_init: T0_init:
if if
:: ((p1)) -> goto accept_S0 :: (p1) -> goto accept_S0
:: ((true)) -> goto T0_init :: (true) -> goto T0_init
:: ((p0)) -> goto accept_S2 :: (p0) -> goto accept_S2
fi; fi;
accept_S0: accept_S0:
if if
:: ((p1)) -> goto accept_S0 :: (p1) -> goto accept_S0
fi; fi;
accept_S2: accept_S2:
if if
:: ((p0)) -> goto accept_S2 :: (p0) -> goto accept_S2
:: ((!(p0))) -> goto T0_S3 :: (!(p0)) -> goto T0_S3
fi; fi;
T0_S3: T0_S3:
if if
:: ((p0)) -> goto accept_S2 :: (p0) -> goto accept_S2
:: ((!(p0))) -> goto T0_S3 :: (!(p0)) -> goto T0_S3
fi; fi;
} }
#+end_example #+end_example

View file

@ -122,7 +122,7 @@ State: 4
* C++ * C++
Parsing an automaton is almost similar to [[file:tut01.org][parsing an LTL formula]]. The Parsing an automaton is similar to [[file:tut01.org][parsing an LTL formula]]. The
=parse_aut()= function takes a filename and a BDD dictionary (to be =parse_aut()= function takes a filename and a BDD dictionary (to be
discussed later on this page). It returns a shared pointer to a discussed later on this page). It returns a shared pointer to a
structure that has a couple of important fields: =aborted= is a structure that has a couple of important fields: =aborted= is a

View file

@ -435,19 +435,18 @@ for g in form.getlist('g'):
formula = form.getfirst('f', '') formula = form.getfirst('f', '')
env = spot.default_environment.instance() env = spot.default_environment.instance()
pel = spot.empty_parse_error_list() pf = spot.parse_infix_psl(formula, env)
f = spot.parse_infix_psl(formula, pel, env)
if pel: if pf.errors:
# Try the LBT parser in case someone is throwing LBT formulas at us. # Try the LBT parser in case someone is throwing LBT formulas at us.
pel2 = spot.empty_parse_error_list() pg = spot.parse_prefix_ltl(formula, env)
g = spot.parse_prefix_ltl(formula, pel2, env) if pg.errors:
if pel2:
unbufprint('<div class="parse-error">') unbufprint('<div class="parse-error">')
err = spot.format_parse_errors(spot.get_cout(), formula, pel) err = pf.format_errors(spot.get_cout())
unbufprint('</div>') unbufprint('</div>')
f = pf.f
else: else:
f = g f = pg.f
# Do not continue if we could not parse anything sensible. # Do not continue if we could not parse anything sensible.
if not f: if not f:

View file

@ -692,20 +692,6 @@ bool fnode_instances_check()
return spot::fnode::instances_check(); return spot::fnode::instances_check();
} }
spot::parse_error_list
empty_parse_error_list()
{
parse_error_list l;
return l;
}
spot::parse_aut_error_list
empty_parse_aut_error_list()
{
parse_aut_error_list l;
return l;
}
spot::twa_graph_ptr spot::twa_graph_ptr
ensure_digraph(const spot::twa_ptr& a) ensure_digraph(const spot::twa_ptr& a)
{ {

View file

@ -1633,10 +1633,9 @@ nc-formula: nc-formula-or-ident
auto i = res.fcache.find(*$1); auto i = res.fcache.find(*$1);
if (i == res.fcache.end()) if (i == res.fcache.end())
{ {
spot::parse_error_list pel; auto pf = spot::parse_infix_boolean(*$1, *res.env, debug_level(),
auto f = spot::parse_infix_boolean(*$1, pel, *res.env, true);
debug_level(), true); for (auto& j: pf.errors)
for (auto& j: pel)
{ {
// Adjust the diagnostic to the current position. // Adjust the diagnostic to the current position.
spot::location here = @1; spot::location here = @1;
@ -1647,8 +1646,9 @@ nc-formula: nc-formula-or-ident
res.h->errors.emplace_back(here, j.second); res.h->errors.emplace_back(here, j.second);
} }
bdd cond = bddfalse; bdd cond = bddfalse;
if (f) if (pf.f)
cond = spot::formula_to_bdd(f, res.h->aut->get_dict(), res.h->aut); cond = spot::formula_to_bdd(pf.f,
res.h->aut->get_dict(), res.h->aut);
$$ = (res.fcache[*$1] = cond).id(); $$ = (res.fcache[*$1] = cond).id();
} }
else else
@ -1814,16 +1814,15 @@ lbtt-acc: { $$ = 0U; }
} }
lbtt-guard: STRING lbtt-guard: STRING
{ {
spot::parse_error_list pel; auto pf = spot::parse_prefix_ltl(*$1, *res.env);
auto f = spot::parse_prefix_ltl(*$1, pel, *res.env); if (!pf.f || !pf.errors.empty())
if (!f || !pel.empty())
{ {
std::string s = "failed to parse guard: "; std::string s = "failed to parse guard: ";
s += *$1; s += *$1;
error(@$, s); error(@$, s);
} }
if (!pel.empty()) if (!pf.errors.empty())
for (auto& j: pel) for (auto& j: pf.errors)
{ {
// Adjust the diagnostic to the current position. // Adjust the diagnostic to the current position.
spot::location here = @1; spot::location here = @1;
@ -1833,13 +1832,13 @@ lbtt-guard: STRING
here.begin.column += j.first.begin.column - 1; here.begin.column += j.first.begin.column - 1;
res.h->errors.emplace_back(here, j.second); res.h->errors.emplace_back(here, j.second);
} }
if (!f) if (!pf.f)
{ {
res.cur_label = bddtrue; res.cur_label = bddtrue;
} }
else else
{ {
if (!f.is_boolean()) if (!pf.f.is_boolean())
{ {
error(@$, error(@$,
"non-Boolean transition label (replaced by true)"); "non-Boolean transition label (replaced by true)");
@ -1848,7 +1847,7 @@ lbtt-guard: STRING
else else
{ {
res.cur_label = res.cur_label =
formula_to_bdd(f, res.h->aut->get_dict(), res.h->aut); formula_to_bdd(pf.f, res.h->aut->get_dict(), res.h->aut);
} }
} }
delete $1; delete $1;

View file

@ -72,11 +72,10 @@ namespace spot
const parse_error_list& error_list) const parse_error_list& error_list)
{ {
bool printed = false; bool printed = false;
parse_error_list::const_iterator it; for (auto it: error_list)
for (it = error_list.begin(); it != error_list.end(); ++it)
{ {
os << ">>> " << ltl_string << std::endl; os << ">>> " << ltl_string << '\n';
const location& l = it->first; const location& l = it.first;
unsigned n = 1; unsigned n = 1;
for (; n < 4 + l.begin.column; ++n) for (; n < 4 + l.begin.column; ++n)
@ -86,7 +85,7 @@ namespace spot
++n; ++n;
for (; n < 4 + l.end.column; ++n) for (; n < 4 + l.end.column; ++n)
os << '^'; os << '^';
os << std::endl << it->second << std::endl << std::endl; os << '\n' << it.second << "\n\n";
printed = true; printed = true;
} }
return printed; return printed;
@ -94,19 +93,17 @@ namespace spot
} }
bool bool
format_parse_errors(std::ostream& os, parsed_formula::format_errors(std::ostream& os)
const std::string& ltl_string,
const parse_error_list& error_list)
{ {
if (utf8::is_valid(ltl_string.begin(), ltl_string.end())) if (utf8::is_valid(input.begin(), input.end()))
{ {
parse_error_list fixed = error_list; parse_error_list fixed = errors;
fix_utf8_locations(ltl_string, fixed); fix_utf8_locations(input, fixed);
return format_parse_errors_aux(os, ltl_string, fixed); return format_parse_errors_aux(os, input, fixed);
} }
else else
{ {
return format_parse_errors_aux(os, ltl_string, error_list); return format_parse_errors_aux(os, input, errors);
} }
} }
} }

View file

@ -1,5 +1,5 @@
/* -*- coding: utf-8 -*- /* -*- coding: utf-8 -*-
** Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Laboratoire ** Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Laboratoire
** de Recherche et Développement de l'Epita (LRDE). ** de Recherche et Développement de l'Epita (LRDE).
** Copyright (C) 2003, 2004, 2005, 2006 Laboratoire d'Informatique de ** Copyright (C) 2003, 2004, 2005, 2006 Laboratoire d'Informatique de
** Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC), ** Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
@ -120,25 +120,24 @@ using namespace spot;
return nullptr; return nullptr;
} }
spot::parse_error_list suberror; spot::parsed_formula pf;
formula f;
switch (type) switch (type)
{ {
case parser_sere: case parser_sere:
f = spot::parse_infix_sere(str, suberror, env, debug, true); pf = spot::parse_infix_sere(str, env, debug, true);
break; break;
case parser_bool: case parser_bool:
f = spot::parse_infix_boolean(str, suberror, env, debug, true); pf = spot::parse_infix_boolean(str, env, debug, true);
break; break;
case parser_ltl: case parser_ltl:
f = spot::parse_infix_psl(str, suberror, env, debug, true); pf = spot::parse_infix_psl(str, env, debug, true);
break; break;
} }
if (suberror.empty()) if (pf.errors.empty())
return f; return pf.f;
f = env.require(str); auto f = env.require(str);
if (!f) if (!f)
{ {
std::string s = "atomic proposition `"; std::string s = "atomic proposition `";
@ -993,69 +992,65 @@ tlyy::parser::error(const location_type& location, const std::string& message)
namespace spot namespace spot
{ {
formula parsed_formula
parse_infix_psl(const std::string& ltl_string, parse_infix_psl(const std::string& ltl_string,
parse_error_list& error_list,
environment& env, environment& env,
bool debug, bool lenient) bool debug, bool lenient)
{ {
formula result = nullptr; parsed_formula result(ltl_string);
flex_set_buffer(ltl_string, flex_set_buffer(ltl_string,
tlyy::parser::token::START_LTL, tlyy::parser::token::START_LTL,
lenient); lenient);
tlyy::parser parser(error_list, env, result); tlyy::parser parser(result.errors, env, result.f);
parser.set_debug_level(debug); parser.set_debug_level(debug);
parser.parse(); parser.parse();
flex_unset_buffer(); flex_unset_buffer();
return result; return result;
} }
formula parsed_formula
parse_infix_boolean(const std::string& ltl_string, parse_infix_boolean(const std::string& ltl_string,
parse_error_list& error_list,
environment& env, environment& env,
bool debug, bool lenient) bool debug, bool lenient)
{ {
formula result = nullptr; parsed_formula result(ltl_string);
flex_set_buffer(ltl_string, flex_set_buffer(ltl_string,
tlyy::parser::token::START_BOOL, tlyy::parser::token::START_BOOL,
lenient); lenient);
tlyy::parser parser(error_list, env, result); tlyy::parser parser(result.errors, env, result.f);
parser.set_debug_level(debug); parser.set_debug_level(debug);
parser.parse(); parser.parse();
flex_unset_buffer(); flex_unset_buffer();
return result; return result;
} }
formula parsed_formula
parse_prefix_ltl(const std::string& ltl_string, parse_prefix_ltl(const std::string& ltl_string,
parse_error_list& error_list,
environment& env, environment& env,
bool debug) bool debug)
{ {
formula result = nullptr; parsed_formula result(ltl_string);
flex_set_buffer(ltl_string, flex_set_buffer(ltl_string,
tlyy::parser::token::START_LBT, tlyy::parser::token::START_LBT,
false); false);
tlyy::parser parser(error_list, env, result); tlyy::parser parser(result.errors, env, result.f);
parser.set_debug_level(debug); parser.set_debug_level(debug);
parser.parse(); parser.parse();
flex_unset_buffer(); flex_unset_buffer();
return result; return result;
} }
formula parsed_formula
parse_infix_sere(const std::string& sere_string, parse_infix_sere(const std::string& sere_string,
parse_error_list& error_list,
environment& env, environment& env,
bool debug, bool debug,
bool lenient) bool lenient)
{ {
formula result = nullptr; parsed_formula result(sere_string);
flex_set_buffer(sere_string, flex_set_buffer(sere_string,
tlyy::parser::token::START_SERE, tlyy::parser::token::START_SERE,
lenient); lenient);
tlyy::parser parser(error_list, env, result); tlyy::parser parser(result.errors, env, result.f);
parser.set_debug_level(debug); parser.set_debug_level(debug);
parser.parse(); parser.parse();
flex_unset_buffer(); flex_unset_buffer();
@ -1065,19 +1060,17 @@ namespace spot
formula formula
parse_formula(const std::string& ltl_string, environment& env) parse_formula(const std::string& ltl_string, environment& env)
{ {
parse_error_list pel; parsed_formula pf = parse_infix_psl(ltl_string, env);
formula f = parse_infix_psl(ltl_string, pel, env);
std::ostringstream s; std::ostringstream s;
if (format_parse_errors(s, ltl_string, pel)) if (pf.format_errors(s))
{ {
parse_error_list pel2; parsed_formula pg = parse_prefix_ltl(ltl_string, env);
formula g = parse_prefix_ltl(ltl_string, pel2, env); if (pg.errors.empty())
if (pel2.empty()) return pg.f;
return g;
else else
throw parse_error(s.str()); throw parse_error(s.str());
} }
return f; return pf.f;
} }
} }

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 Laboratoire de // Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016 Laboratoire
// Recherche et Développement de l'Epita (LRDE). // de Recherche et Développement de l'Epita (LRDE).
// Copyright (C) 2003, 2004, 2005, 2006 Laboratoire d'Informatique de // Copyright (C) 2003, 2004, 2005, 2006 Laboratoire d'Informatique de
// Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC), // Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
// Université Pierre et Marie Curie. // Université Pierre et Marie Curie.
@ -45,10 +45,40 @@ namespace spot
struct parse_error_list {}; struct parse_error_list {};
#endif #endif
/// \brief The result of a formula parser.
struct SPOT_API parsed_formula final
{
/// \brief The parsed formula.
///
/// This could be formula(nullptr) in case of a serious parse error.
formula f = nullptr;
/// The input text, before parsing.
std::string input;
/// \brief Syntax errors that occurred during parsing.
///
/// Note that the parser does not print any diagnostic.
/// Deciding how to output those errors is up to you.
///
/// \see format_errors
parse_error_list errors;
parsed_formula(const std::string& str = "")
: input(str)
{
}
/// \brief Format diagnostics.
///
/// \param os Where diagnostics should be output.
/// \return \c true iff any diagnostic was output.
bool format_errors(std::ostream& os);
};
/// \brief Build a formula from an LTL string. /// \brief Build a formula from an LTL string.
/// \param ltl_string The string to parse. /// \param ltl_string The string to parse.
/// \param error_list A list that will be filled with
/// parse errors that occured during parsing.
/// \param env The environment into which parsing should take place. /// \param env The environment into which parsing should take place.
/// \param debug When true, causes the parser to trace its execution. /// \param debug When true, causes the parser to trace its execution.
/// \param lenient When true, parenthesized blocks that cannot be /// \param lenient When true, parenthesized blocks that cannot be
@ -57,15 +87,16 @@ namespace spot
/// \return A formula built from \a ltl_string, or /// \return A formula built from \a ltl_string, or
/// formula(nullptr) if the input was unparsable. /// formula(nullptr) if the input was unparsable.
/// ///
/// Note that the parser usually tries to recover from errors. It can ///
/// return a non zero value even if it encountered error during the /// Note that the parser usually tries to recover from errors. The
/// parsing of \a ltl_string. If you want to make sure \a ltl_string /// field parsed_formula::f in the returned object can be a non-zero
/// was parsed succesfully, check \a error_list for emptiness. /// value even if it encountered error during the parsing of \a
/// ltl_string. If you want to make sure \a ltl_string was parsed
/// succesfully, check \a parsed_formula::errors for emptiness.
/// ///
/// \warning This function is not reentrant. /// \warning This function is not reentrant.
SPOT_API SPOT_API
formula parse_infix_psl(const std::string& ltl_string, parsed_formula parse_infix_psl(const std::string& ltl_string,
parse_error_list& error_list,
environment& env = environment& env =
default_environment::instance(), default_environment::instance(),
bool debug = false, bool debug = false,
@ -73,25 +104,22 @@ namespace spot
/// \brief Build a Boolean formula from a string. /// \brief Build a Boolean formula from a string.
/// \param ltl_string The string to parse. /// \param ltl_string The string to parse.
/// \param error_list A list that will be filled with
/// parse errors that occured during parsing.
/// \param env The environment into which parsing should take place. /// \param env The environment into which parsing should take place.
/// \param debug When true, causes the parser to trace its execution. /// \param debug When true, causes the parser to trace its execution.
/// \param lenient When true, parenthesized blocks that cannot be /// \param lenient When true, parenthesized blocks that cannot be
/// parsed as subformulas will be considered as /// parsed as subformulas will be considered as
/// atomic propositions. /// atomic propositions.
/// \return A formula built from \a ltl_string, or /// \return A parsed_formula
/// formula(nullptr) if the input was unparsable.
/// ///
/// Note that the parser usually tries to recover from errors. It can /// Note that the parser usually tries to recover from errors. The
/// return a non zero value even if it encountered error during the /// field parsed_formula::f in the returned object can be a non-zero
/// parsing of \a ltl_string. If you want to make sure \a ltl_string /// value even if it encountered error during the parsing of \a
/// was parsed succesfully, check \a error_list for emptiness. /// ltl_string. If you want to make sure \a ltl_string was parsed
/// succesfully, check \a parsed_formula::errors for emptiness.
/// ///
/// \warning This function is not reentrant. /// \warning This function is not reentrant.
SPOT_API SPOT_API
formula parse_infix_boolean(const std::string& ltl_string, parsed_formula parse_infix_boolean(const std::string& ltl_string,
parse_error_list& error_list,
environment& env = environment& env =
default_environment::instance(), default_environment::instance(),
bool debug = false, bool debug = false,
@ -99,17 +127,16 @@ namespace spot
/// \brief Build a formula from an LTL string in LBT's format. /// \brief Build a formula from an LTL string in LBT's format.
/// \param ltl_string The string to parse. /// \param ltl_string The string to parse.
/// \param error_list A list that will be filled with
/// parse errors that occured during parsing.
/// \param env The environment into which parsing should take place. /// \param env The environment into which parsing should take place.
/// \param debug When true, causes the parser to trace its execution. /// \param debug When true, causes the parser to trace its execution.
/// \return A formula built from \a ltl_string, or /// \return A formula built from \a ltl_string, or
/// formula(nullptr) if the input was unparsable. /// formula(nullptr) if the input was unparsable.
/// ///
/// Note that the parser usually tries to recover from errors. It can /// Note that the parser usually tries to recover from errors. The
/// return an non zero value even if it encountered error during the /// field parsed_formula::f in the returned object can be a non-zero
/// parsing of \a ltl_string. If you want to make sure \a ltl_string /// value even if it encountered error during the parsing of \a
/// was parsed succesfully, check \a error_list for emptiness. /// ltl_string. If you want to make sure \a ltl_string was parsed
/// succesfully, check \a parsed_formula::errors for emptiness.
/// ///
/// The LBT syntax, also used by the lbtt and scheck tools, is /// The LBT syntax, also used by the lbtt and scheck tools, is
/// extended to support W, and M operators (as done in lbtt), and /// extended to support W, and M operators (as done in lbtt), and
@ -117,8 +144,7 @@ namespace spot
/// ///
/// \warning This function is not reentrant. /// \warning This function is not reentrant.
SPOT_API SPOT_API
formula parse_prefix_ltl(const std::string& ltl_string, parsed_formula parse_prefix_ltl(const std::string& ltl_string,
parse_error_list& error_list,
environment& env = environment& env =
default_environment::instance(), default_environment::instance(),
bool debug = false); bool debug = false);
@ -135,8 +161,6 @@ namespace spot
/// \brief Build a formula from a string representing a SERE. /// \brief Build a formula from a string representing a SERE.
/// \param sere_string The string to parse. /// \param sere_string The string to parse.
/// \param error_list A list that will be filled with
/// parse errors that occured during parsing.
/// \param env The environment into which parsing should take place. /// \param env The environment into which parsing should take place.
/// \param debug When true, causes the parser to trace its execution. /// \param debug When true, causes the parser to trace its execution.
/// \param lenient When true, parenthesized blocks that cannot be /// \param lenient When true, parenthesized blocks that cannot be
@ -145,38 +169,20 @@ namespace spot
/// \return A formula built from \a sere_string, or /// \return A formula built from \a sere_string, or
/// formula(0) if the input was unparsable. /// formula(0) if the input was unparsable.
/// ///
/// Note that the parser usually tries to recover from errors. It can /// Note that the parser usually tries to recover from errors. The
/// return an non zero value even if it encountered error during the /// field parsed_formula::f in the returned object can be a non-zero
/// parsing of \a ltl_string. If you want to make sure \a ltl_string /// value even if it encountered error during the parsing of \a
/// was parsed succesfully, check \a error_list for emptiness. /// ltl_string. If you want to make sure \a ltl_string was parsed
/// succesfully, check \a parsed_formula::errors for emptiness.
/// ///
/// \warning This function is not reentrant. /// \warning This function is not reentrant.
SPOT_API SPOT_API
formula parse_infix_sere(const std::string& sere_string, parsed_formula parse_infix_sere(const std::string& sere_string,
parse_error_list& error_list,
environment& env = environment& env =
default_environment::instance(), default_environment::instance(),
bool debug = false, bool debug = false,
bool lenient = false); bool lenient = false);
/// \brief Format diagnostics produced by spot::parse
/// or spot::ratexp
///
/// If the string is utf8 encoded, spot::fix_utf8_locations()
/// will be used to report correct utf8 locations (assuming the
/// output is utf8 aware). Nonetheless, the supplied \a
/// error_list will not be modified.
///
/// \param os Where diagnostics should be output.
/// \param input_string The string that were parsed.
/// \param error_list The error list filled by spot::parse
/// or spot::parse_sere while parsing \a input_string.
/// \return \c true iff any diagnostic was output.
SPOT_API
bool format_parse_errors(std::ostream& os,
const std::string& input_string,
const parse_error_list& error_list);
/// \brief Fix location of diagnostics assuming the input is utf8. /// \brief Fix location of diagnostics assuming the input is utf8.
/// ///
/// The different parser functions return a parse_error_list that /// The different parser functions return a parse_error_list that

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement // Copyright (C) 2014, 2015, 2016 Laboratoire de Recherche et Développement
// de l'Epita (LRDE). // de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
@ -60,11 +60,10 @@ main(int argc, char** argv)
if (s.empty() || s[0] == '#') // Skip comments if (s.empty() || s[0] == '#') // Skip comments
continue; continue;
spot::parse_error_list pe; auto pfpos = spot::parse_infix_psl(s);
auto fpos = spot::parse_infix_psl(s, pe); if (pfpos.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, s, pe))
return 2; return 2;
auto fpos = pfpos.f;
auto fneg = spot::formula::Not(fpos); auto fneg = spot::formula::Not(fpos);

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement // Copyright (C) 2014, 2015, 2016 Laboratoire de Recherche et
// de l'Epita (LRDE). // Développement de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
// //
@ -85,11 +85,11 @@ main(int argc, char** argv)
if (s.empty() || s[0] == '#') // Skip comments if (s.empty() || s[0] == '#') // Skip comments
continue; continue;
spot::parse_error_list pe; auto pf = spot::parse_infix_psl(s);
auto f = spot::parse_infix_psl(s, pe);
if (spot::format_parse_errors(std::cerr, s, pe)) if (pf.format_errors(std::cerr))
return 2; return 2;
auto f = pf.f;
{ {

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2010, 2011, 2012, 2015 Laboratoire de Recherche et // Copyright (C) 2010, 2011, 2012, 2015, 2016 Laboratoire de Recherche
// Dévelopement de l'Epita (LRDE). // et Dévelopement de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
// //
@ -58,12 +58,11 @@ main(int argc, char **argv)
std::getline(ss, form, ','); std::getline(ss, form, ',');
ss >> expected; ss >> expected;
spot::parse_error_list p1; auto pf1 = spot::parse_infix_sere(form);
auto f1 = spot::parse_infix_sere(form, p1); if (pf1.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, form, p1))
return 2; return 2;
bool b = f1.accepts_eword(); bool b = pf1.f.accepts_eword();
std::cout << form << ',' << b << '\n'; std::cout << form << ',' << b << '\n';
if (b != expected) if (b != expected)
{ {

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement de // Copyright (C) 2014, 2015, 2016 Laboratoire de Recherche et
// l'Epita (LRDE). // Développement de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
// //
@ -89,10 +89,10 @@ main(int argc, char** argv)
int runs = atoi(tokens[0].c_str()); int runs = atoi(tokens[0].c_str());
spot::parse_error_list pe; auto pf = spot::parse_infix_psl(tokens[1]);
auto f = spot::parse_infix_psl(tokens[1], pe); if (pf.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, tokens[1], pe))
return 2; return 2;
auto f = pf.f;
auto d = spot::make_bdd_dict(); auto d = spot::make_bdd_dict();

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2008, 2009, 2010, 2011, 2012, 2014, 2015 Laboratoire de // Copyright (C) 2008, 2009, 2010, 2011, 2012, 2014, 2015, 2016 Laboratoire de
// Recherche et Développement de l'Epita (LRDE). // Recherche et Développement de l'Epita (LRDE).
// Copyright (C) 2003, 2004, 2006 Laboratoire d'Informatique de // Copyright (C) 2003, 2004, 2006 Laboratoire d'Informatique de
// Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC), // Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
@ -95,21 +95,20 @@ main(int argc, char** argv)
return 2; return 2;
} }
spot::parse_error_list p2; auto pf2 = spot::parse_infix_psl(formulas[size - 1]);
auto f2 = spot::parse_infix_psl(formulas[size - 1], p2);
if (spot::format_parse_errors(std::cerr, formulas[size - 1], p2)) if (pf2.format_errors(std::cerr))
return 2; return 2;
auto f2 = pf2.f;
for (unsigned n = 0; n < size - 1; ++n) for (unsigned n = 0; n < size - 1; ++n)
{ {
spot::parse_error_list p1; auto pf1 = spot::parse_infix_psl(formulas[n]);
auto f1 = spot::parse_infix_psl(formulas[n], p1);
if (check_first && if (check_first && pf1.format_errors(std::cerr))
spot::format_parse_errors(std::cerr, formulas[n], p1))
return 2; return 2;
auto f1 = pf1.f;
int exit_code = 0; int exit_code = 0;

View file

@ -908,11 +908,11 @@ checked_main(int argc, char** argv)
case TransTAA: case TransTAA:
case TransCompo: case TransCompo:
{ {
spot::parse_error_list pel;
tm.start("parsing formula"); tm.start("parsing formula");
f = spot::parse_infix_psl(input, pel, env, debug_opt); auto pf = spot::parse_infix_psl(input, env, debug_opt);
tm.stop("parsing formula"); tm.stop("parsing formula");
exit_code = spot::format_parse_errors(std::cerr, input, pel); exit_code = pf.format_errors(std::cerr);
f = pf.f;
} }
break; break;
} }

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2010, 2012, 2015 Laboratoire de Recherche et // Copyright (C) 2010, 2012, 2015, 2016 Laboratoire de Recherche et
// Developement de l'Epita (LRDE). // Developement de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
@ -59,9 +59,10 @@ main(int argc, char **argv)
std::getline(ss, expected); std::getline(ss, expected);
spot::parse_error_list p1; spot::parse_error_list p1;
auto f1 = spot::parse_infix_psl(form, p1); auto pf1 = spot::parse_infix_psl(form);
if (spot::format_parse_errors(std::cerr, form, p1)) if (pf1.format_errors(std::cerr))
return 2; return 2;
auto f1 = pf1.f;
std::ostringstream so; std::ostringstream so;
spot::print_formula_props(so, f1, true); spot::print_formula_props(so, f1, true);

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2012, 2015 Laboratoire de Recherche et Developement de // Copyright (C) 2012, 2015, 2016 Laboratoire de Recherche et
// l'Epita (LRDE). // Developement de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
// //
@ -45,11 +45,10 @@ main(int argc, char **argv)
} }
{ {
spot::parse_error_list p1; auto pf1 = spot::parse_infix_psl(argv[1]);
auto f1 = spot::parse_infix_psl(argv[1], p1); if (pf1.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, argv[1], p1))
return 2; return 2;
auto f1 = pf1.f;
if (boolone) if (boolone)
std::cout << spot::length_boolone(f1) << std::endl; std::cout << spot::length_boolone(f1) << std::endl;

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2008, 2009, 2012, 2014, 2015 Laboratoire de Recherche // Copyright (C) 2008, 2009, 2012, 2014, 2015, 2016 Laboratoire de
// et Développement de l'Epita (LRDE). // Recherche et Développement de l'Epita (LRDE).
// Copyright (C) 2003, 2004 Laboratoire d'Informatique de // Copyright (C) 2003, 2004 Laboratoire d'Informatique de
// Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC), // Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
// Université Pierre et Marie Curie. // Université Pierre et Marie Curie.
@ -46,17 +46,15 @@ main(int argc, char** argv)
{ {
spot::environment& env(spot::default_environment::instance()); spot::environment& env(spot::default_environment::instance());
spot::parse_error_list pel1; auto pf1 = spot::parse_infix_psl(argv[1], env);
auto f1 = spot::parse_infix_psl(argv[1], pel1, env); if (pf1.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, argv[1], pel1))
return 2; return 2;
auto f1 = pf1.f;
spot::parse_error_list pel2; auto pf2 = spot::parse_infix_psl(argv[2], env);
auto f2 = spot::parse_infix_psl(argv[2], pel2, env); if (pf2.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, argv[2], pel2))
return 2; return 2;
auto f2 = pf2.f;
auto dict = spot::make_bdd_dict(); auto dict = spot::make_bdd_dict();
{ {

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2013, 2014, 2015 Laboratoire de Recherche et Developement // Copyright (C) 2013, 2014, 2015, 2016 Laboratoire de Recherche et Developement
// de l'Epita (LRDE). // de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
@ -38,11 +38,10 @@ main(int argc, char **argv)
syntax(argv[0]); syntax(argv[0]);
{ {
spot::parse_error_list p1; auto pf1 = spot::parse_infix_psl(argv[1]);
auto f1 = spot::parse_infix_psl(argv[1], p1); if (pf1.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, argv[1], p1))
return 2; return 2;
auto f1 = pf1.f;
spot::relabeling_map* m = new spot::relabeling_map; spot::relabeling_map* m = new spot::relabeling_map;
auto f2 = spot::relabel_bse(f1, spot::Pnn, m); auto f2 = spot::relabel_bse(f1, spot::Pnn, m);

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2008, 2009, 2010, 2011, 2012, 2014, 2015 Laboratoire // Copyright (C) 2008, 2009, 2010, 2011, 2012, 2014, 2015, 2016 Laboratoire
// de Recherche et Développement de l'Epita (LRDE). // de Recherche et Développement de l'Epita (LRDE).
// Copyright (C) 2004, 2005 Laboratoire d'Informatique de Paris // Copyright (C) 2004, 2005 Laboratoire d'Informatique de Paris
// 6 (LIP6), département Systèmes Répartis Coopératifs (SRC), // 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
@ -860,15 +860,14 @@ main(int argc, char** argv)
break; break;
else if (input == "") else if (input == "")
break; break;
spot::parse_error_list pel; auto pf = spot::parse_infix_psl(input, env);
auto f = spot::parse_infix_psl(input, pel, env); if (pf.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, input, pel))
{ {
exit_code = 1; exit_code = 1;
break; break;
} }
formula = spot::ltl_to_tgba_fm(f, dict, true); formula = spot::ltl_to_tgba_fm(pf.f, dict, true);
auto* tmp = spot::atomic_prop_collect(f); auto* tmp = spot::atomic_prop_collect(pf.f);
for (auto i: *tmp) for (auto i: *tmp)
apf->insert(i); apf->insert(i);
delete tmp; delete tmp;

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2008, 2009, 2012, 2015 Laboratoire de Recherche et // Copyright (C) 2008, 2009, 2012, 2015, 2016 Laboratoire de Recherche
// Développement de l'Epita (LRDE). // et Développement de l'Epita (LRDE).
// Copyright (C) 2003 Laboratoire d'Informatique de Paris 6 // Copyright (C) 2003 Laboratoire d'Informatique de Paris 6
// (LIP6), département Systèmes Répartis Coopératifs (SRC), Université // (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
// Pierre et Marie Curie. // Pierre et Marie Curie.
@ -55,12 +55,13 @@ main(int argc, char** argv)
{ {
spot::environment& env(spot::default_environment::instance()); spot::environment& env(spot::default_environment::instance());
spot::parse_error_list pel;
auto f = spot::parse_infix_psl(argv[formula_index], pel, env, debug);
exit_code =
spot::format_parse_errors(std::cerr, argv[formula_index], pel);
auto f = [&]()
{
auto pf = spot::parse_infix_psl(argv[formula_index], env, debug);
exit_code = pf.format_errors(std::cerr);
return pf.f;
}();
if (f) if (f)
{ {

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*_ // -*- coding: utf-8 -*_
// Copyright (C) 2008, 2009, 2010, 2011, 2012, 2014, 2015 Laboratoire // Copyright (C) 2008, 2009, 2010, 2011, 2012, 2014, 2015, 2016 Laboratoire
// de Recherche et Développement de l'Epita (LRDE). // de Recherche et Développement de l'Epita (LRDE).
// Copyright (C) 2004, 2006, 2007 Laboratoire d'Informatique de Paris // Copyright (C) 2004, 2006, 2007 Laboratoire d'Informatique de Paris
// 6 (LIP6), département Systèmes Répartis Coopératifs (SRC), // 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
@ -178,17 +178,17 @@ main(int argc, char** argv)
} }
while (input == ""); while (input == "");
spot::parse_error_list p1; auto pf1 = spot::parse_infix_psl(input);
f1 = spot::parse_infix_psl(input, p1); if (pf1.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, input, p1))
return 2; return 2;
f1 = pf1.f;
} }
else else
{ {
spot::parse_error_list p1; auto pf1 = spot::parse_infix_psl(argv[2]);
f1 = spot::parse_infix_psl(argv[2], p1); if (pf1.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, argv[2], p1))
return 2; return 2;
f1 = pf1.f;
} }
if (argc == 4) if (argc == 4)
@ -199,10 +199,10 @@ main(int argc, char** argv)
exit(2); exit(2);
} }
spot::parse_error_list p2; auto pf2 = spot::parse_infix_psl(argv[3]);
f2 = spot::parse_infix_psl(argv[3], p2); if (pf2.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, argv[3], p2))
return 2; return 2;
f2 = pf2.f;
} }
{ {

View file

@ -111,13 +111,12 @@ int main(int argc, char* argv[])
spot::twa_graph_ptr res; spot::twa_graph_ptr res;
if (in_ltl) if (in_ltl)
{ {
spot::parse_error_list pel; auto pf = spot::parse_infix_psl(input);
spot::formula f = spot::parse_infix_psl(input, pel); if (pf.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, input, pel))
return 2; return 2;
spot::translator trans(dict); spot::translator trans(dict);
trans.set_pref(spot::postprocessor::Deterministic); trans.set_pref(spot::postprocessor::Deterministic);
auto tmp = trans.run(f); auto tmp = trans.run(pf.f);
res = spot::tgba_determinize(tmp, pretty_print, scc_opt, res = spot::tgba_determinize(tmp, pretty_print, scc_opt,
use_bisim, use_stutter); use_bisim, use_stutter);
} }

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2008, 2009, 2010, 2011, 2012, 2014, 2015 Laboratoire de // Copyright (C) 2008, 2009, 2010, 2011, 2012, 2014, 2015, 2016
// Recherche et Développement de l'Epita (LRDE). // Laboratoire de Recherche et Développement de l'Epita (LRDE).
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 // Copyright (C) 2004 Laboratoire d'Informatique de Paris 6
// (LIP6), département Systèmes Répartis Coopératifs (SRC), Université // (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
// Pierre et Marie Curie. // Pierre et Marie Curie.
@ -45,20 +45,18 @@ main(int argc, char** argv)
int exit_return = 0; int exit_return = 0;
{ {
spot::parse_error_list p1; auto ftmp1 = spot::parse_infix_psl(argv[2]);
auto ftmp1 = spot::parse_infix_psl(argv[2], p1);
if (spot::format_parse_errors(std::cerr, argv[2], p1)) if (ftmp1.format_errors(std::cerr))
return 2; return 2;
spot::parse_error_list p2; auto ftmp2 = spot::parse_infix_psl(argv[3]);
auto ftmp2 = spot::parse_infix_psl(argv[3], p2);
if (spot::format_parse_errors(std::cerr, argv[3], p2)) if (ftmp2.format_errors(std::cerr))
return 2; return 2;
spot::formula f1 = spot::negative_normal_form(ftmp1); spot::formula f1 = spot::negative_normal_form(ftmp1.f);
spot::formula f2 = spot::negative_normal_form(ftmp2); spot::formula f2 = spot::negative_normal_form(ftmp2.f);
std::string f1s = spot::str_psl(f1); std::string f1s = spot::str_psl(f1);
std::string f2s = spot::str_psl(f2); std::string f2s = spot::str_psl(f2);

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2008, 2009, 2012, 2015 Laboratoire de Recherche et // Copyright (C) 2008, 2009, 2012, 2015, 2016 Laboratoire de Recherche
// Développement de l'Epita (LRDE). // et Développement de l'Epita (LRDE).
// Copyright (C) 2003 Laboratoire d'Informatique de Paris 6 (LIP6), // Copyright (C) 2003 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre // département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie. // et Marie Curie.
@ -40,11 +40,10 @@ main(int argc, char **argv)
syntax(argv[0]); syntax(argv[0]);
{ {
spot::parse_error_list p1; auto pf1 = spot::parse_infix_psl(argv[1]);
auto f1 = spot::parse_infix_psl(argv[1], p1); if (pf1.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, argv[1], p1))
return 2; return 2;
auto f1 = pf1.f;
// The string generated from an abstract tree should be parsable // The string generated from an abstract tree should be parsable
// again. // again.
@ -52,10 +51,10 @@ main(int argc, char **argv)
std::string f1s = spot::str_psl(f1); std::string f1s = spot::str_psl(f1);
std::cout << f1s << '\n'; std::cout << f1s << '\n';
auto f2 = spot::parse_infix_psl(f1s, p1); auto pf2 = spot::parse_infix_psl(f1s);
if (pf2.format_errors(std::cerr))
if (spot::format_parse_errors(std::cerr, f1s, p1))
return 2; return 2;
auto f2 = pf2.f;
// This second abstract tree should be equal to the first. // This second abstract tree should be equal to the first.

View file

@ -192,9 +192,9 @@ checked_main(int argc, char **argv)
tm.start("parsing formula"); tm.start("parsing formula");
{ {
spot::parse_error_list pel; auto pf = spot::parse_infix_psl(argv[2], env, false);
f = spot::parse_infix_psl(argv[2], pel, env, false); exit_code = pf.format_errors(std::cerr);
exit_code = spot::format_parse_errors(std::cerr, argv[2], pel); f = pf.f;
} }
tm.stop("parsing formula"); tm.stop("parsing formula");

View file

@ -1,6 +1,6 @@
# -*- mode: python; coding: utf-8 -*- # -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2012, 2014, 2015 Laboratoire de Recherche et Développement # Copyright (C) 2012, 2014, 2015, 2016 Laboratoire de Recherche et
# de l'Epita # Développement de l'Epita
# #
# This file is part of Spot, a model checking library. # This file is part of Spot, a model checking library.
# #
@ -43,8 +43,7 @@ P_Rbt2.moins || P_Rbt2.stop))-> G((F "map[0]==1") && (F "map[1]==1")
"map[9]==3")))""" "map[9]==3")))"""
e = spot.default_environment.instance() e = spot.default_environment.instance()
p = spot.empty_parse_error_list() pf = spot.parse_infix_psl(f, e)
f = spot.parse_infix_psl(f, p, e)
d = spot.make_bdd_dict() d = spot.make_bdd_dict()
spot.unblock_signal(signal.SIGALRM) spot.unblock_signal(signal.SIGALRM)
@ -58,9 +57,9 @@ if child != 0:
# If the child returns, before we get the alarm it's a bug. # If the child returns, before we get the alarm it's a bug.
exit(1) exit(1)
# This is expected to take WAY more that 2s. # This is expected to take WAY more than 2s.
print("Before") print("Before")
spot.ltl_to_tgba_fm(f, d, True) spot.ltl_to_tgba_fm(pf.f, d, True)
print("After") print("After")
exit(1) exit(1)

View file

@ -1,5 +1,5 @@
# -*- mode: python; coding: utf-8 -*- # -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2010, 2012, 2014, 2015 Laboratoire de Recherche et # Copyright (C) 2010, 2012, 2014, 2015, 2016 Laboratoire de Recherche et
# Développement de l'EPITA. # Développement de l'EPITA.
# Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 # Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6
# (LIP6), département Systèmes Répartis Coopératifs (SRC), Université # (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
@ -29,12 +29,11 @@ import sys
simp = spot.tl_simplifier() simp = spot.tl_simplifier()
e = spot.default_environment.instance() e = spot.default_environment.instance()
p = spot.empty_parse_error_list() pf = spot.parse_infix_psl('GFa', e)
f = spot.parse_infix_psl('GFa', p, e)
d = simp.get_dict() d = simp.get_dict()
a = spot.ltl_to_tgba_fm(f, d) a = spot.ltl_to_tgba_fm(pf.f, d)
g = spot.parse_infix_boolean('b&c', p, e) g = spot.parse_infix_boolean('b&c', e)
b = simp.as_bdd(g) b = simp.as_bdd(g.f)
buddy.bdd_printset(b); spot.nl_cout() buddy.bdd_printset(b); spot.nl_cout()
del g del g
@ -54,5 +53,5 @@ del it
del s0 del s0
del b del b
del c del c
del f del pf
del simp del simp

View file

@ -1,5 +1,5 @@
# -*- mode: python; coding: utf-8 -*- # -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2009, 2010, 2012, 2014, 2015 Laboratoire de Recherche et # Copyright (C) 2009, 2010, 2012, 2014, 2015, 2016 Laboratoire de Recherche et
# Développement de l'Epita (LRDE). # Développement de l'Epita (LRDE).
# Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6), # Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
# département Systèmes Répartis Coopératifs (SRC), Université Pierre # département Systèmes Répartis Coopératifs (SRC), Université Pierre
@ -83,11 +83,11 @@ cout = spot.get_cout()
cerr = spot.get_cerr() cerr = spot.get_cerr()
e = spot.default_environment.instance() e = spot.default_environment.instance()
p = spot.empty_parse_error_list()
f = spot.parse_infix_psl(args[0], p, e, debug_opt) pf = spot.parse_infix_psl(args[0], e, debug_opt)
if spot.format_parse_errors(cerr, args[0], p): if pf.format_errors(cerr):
exit_code = 1 exit_code = 1
f = pf.f
dict = spot.make_bdd_dict() dict = spot.make_bdd_dict()
@ -128,5 +128,6 @@ if f:
else: else:
exit_code = 1 exit_code = 1
del pf
del dict del dict
assert spot.fnode_instances_check() assert spot.fnode_instances_check()

View file

@ -1,5 +1,5 @@
# -*- mode: python; coding: utf-8 -*- # -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2009, 2010, 2012, 2014, 2015 Laboratoire de Recherche et # Copyright (C) 2009, 2010, 2012, 2014, 2015, 2016 Laboratoire de Recherche et
# Développement de l'Epita (LRDE). # Développement de l'Epita (LRDE).
# Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6), # Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
# département Systèmes Répartis Coopératifs (SRC), Université Pierre # département Systèmes Répartis Coopératifs (SRC), Université Pierre
@ -24,22 +24,21 @@ import sys
import spot import spot
e = spot.default_environment.instance() e = spot.default_environment.instance()
p = spot.empty_parse_error_list()
l = ['GFa', 'a U (((b)) xor c)', '!(FFx <=> Fx)', 'a \/ a \/ b \/ a \/ a']; l = ['GFa', 'a U (((b)) xor c)', '!(FFx <=> Fx)', 'a \/ a \/ b \/ a \/ a'];
for str1 in l: for str1 in l:
f = spot.parse_infix_psl(str1, p, e, False) pf = spot.parse_infix_psl(str1, e, False)
if spot.format_parse_errors(spot.get_cout(), str1, p): if pf.format_errors(spot.get_cout()):
sys.exit(1) sys.exit(1)
str2 = str(f) str2 = str(pf.f)
del f del pf
sys.stdout.write(str2 + "\n") sys.stdout.write(str2 + "\n")
# Try to reparse the stringified formula # Try to reparse the stringified formula
f = spot.parse_infix_psl(str2, p, e) pf = spot.parse_infix_psl(str2, e)
if spot.format_parse_errors(spot.get_cout(), str2, p): if pf.format_errors(spot.get_cout()):
sys.exit(1) sys.exit(1)
sys.stdout.write(str(f) + "\n") sys.stdout.write(str(pf.f) + "\n")
del f del pf
assert spot.fnode_instances_check() assert spot.fnode_instances_check()