* configure.ac: Output src/tgbaparse/Makefile.
* src/Makefile.am (SUBDIRS): Add tgbaparse. (libspot_la_LDADD): Add tgbaparse/libtgbaparse.la. * src/tgba/tgbaexplicit.cc (tgba_explicit::get_condition, tgba_explicit::get_promise, tgba_explicit::add_neg_condition, tgba_explicit::add_neg_promise): New methods. * src/tgba/tgbaexplicit.hh: Declare them. * src/tgbaparse/Makefile.am, src/tgbaparse/fmterror.cc, src/tgbaparse/parsedecl.hh, src/tgbaparse/public.hh, src/tgbaparse/tgbaparse.yy, src/tgbaparse/tgbascan.ll, src/tgbatest/tgbaread.cc, src/tgbatest/tgbaread.test: New files. * src/tgbatest/Makefile.am (check_PROGRAMS): Add tgbaread. (TESTS): Add tgbaread.cc. (CLEANFILES): Add input. (tgbaread_SOURCES): New variable.
This commit is contained in:
parent
cebffb11e8
commit
6884a7f985
18 changed files with 495 additions and 14 deletions
16
ChangeLog
16
ChangeLog
|
|
@ -1,5 +1,21 @@
|
||||||
2003-06-05 Alexandre Duret-Lutz <aduret@src.lip6.fr>
|
2003-06-05 Alexandre Duret-Lutz <aduret@src.lip6.fr>
|
||||||
|
|
||||||
|
* configure.ac: Output src/tgbaparse/Makefile.
|
||||||
|
* src/Makefile.am (SUBDIRS): Add tgbaparse.
|
||||||
|
(libspot_la_LDADD): Add tgbaparse/libtgbaparse.la.
|
||||||
|
* src/tgba/tgbaexplicit.cc (tgba_explicit::get_condition,
|
||||||
|
tgba_explicit::get_promise, tgba_explicit::add_neg_condition,
|
||||||
|
tgba_explicit::add_neg_promise): New methods.
|
||||||
|
* src/tgba/tgbaexplicit.hh: Declare them.
|
||||||
|
* src/tgbaparse/Makefile.am, src/tgbaparse/fmterror.cc,
|
||||||
|
src/tgbaparse/parsedecl.hh, src/tgbaparse/public.hh,
|
||||||
|
src/tgbaparse/tgbaparse.yy, src/tgbaparse/tgbascan.ll,
|
||||||
|
src/tgbatest/tgbaread.cc, src/tgbatest/tgbaread.test: New files.
|
||||||
|
* src/tgbatest/Makefile.am (check_PROGRAMS): Add tgbaread.
|
||||||
|
(TESTS): Add tgbaread.cc.
|
||||||
|
(CLEANFILES): Add input.
|
||||||
|
(tgbaread_SOURCES): New variable.
|
||||||
|
|
||||||
* src/ltlparse/ltlparse.yy: Typo in comment.
|
* src/ltlparse/ltlparse.yy: Typo in comment.
|
||||||
|
|
||||||
* configure.ac: Output src/tgbatest/Makefile and src/tgbatest/defs.
|
* configure.ac: Output src/tgbatest/Makefile and src/tgbatest/defs.
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ AC_CONFIG_FILES([
|
||||||
src/ltlvisit/Makefile
|
src/ltlvisit/Makefile
|
||||||
src/tgba/Makefile
|
src/tgba/Makefile
|
||||||
src/tgbaalgos/Makefile
|
src/tgbaalgos/Makefile
|
||||||
|
src/tgbaparse/Makefile
|
||||||
src/tgbatest/Makefile
|
src/tgbatest/Makefile
|
||||||
src/tgbatest/defs
|
src/tgbatest/defs
|
||||||
src/misc/Makefile
|
src/misc/Makefile
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS = subdir-objects
|
||||||
|
|
||||||
# List directories in the order they must be built.
|
# List directories in the order they must be built.
|
||||||
# Keep tests at the end.
|
# Keep tests at the end.
|
||||||
SUBDIRS = misc ltlenv ltlast ltlvisit ltlparse tgba tgbaalgos . \
|
SUBDIRS = misc ltlenv ltlast ltlvisit ltlparse tgba tgbaalgos tgbaparse . \
|
||||||
ltltest tgbatest
|
ltltest tgbatest
|
||||||
|
|
||||||
lib_LTLIBRARIES = libspot.la
|
lib_LTLIBRARIES = libspot.la
|
||||||
|
|
@ -13,4 +13,5 @@ libspot_la_LIBADD = \
|
||||||
ltlvisit/libltlvisit.la \
|
ltlvisit/libltlvisit.la \
|
||||||
ltlast/libltlast.la \
|
ltlast/libltlast.la \
|
||||||
tgba/libtgba.la \
|
tgba/libtgba.la \
|
||||||
tgbaalgos/libtgbaalgos.la
|
tgbaalgos/libtgbaalgos.la \
|
||||||
|
tgbaparse/libtgbaparse.la
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ main(int argc, char** argv)
|
||||||
spot::ltl::formula* f = spot::ltl::parse(argv[formula_index],
|
spot::ltl::formula* f = spot::ltl::parse(argv[formula_index],
|
||||||
pel, env, debug);
|
pel, env, debug);
|
||||||
|
|
||||||
spot::ltl::parse_error_list::iterator it;
|
|
||||||
exit_code =
|
exit_code =
|
||||||
spot::ltl::format_parse_errors(std::cerr, argv[formula_index], pel);
|
spot::ltl::format_parse_errors(std::cerr, argv[formula_index], pel);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ namespace spot
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tgba_explicit::add_condition(transition* t, ltl::formula* f)
|
int tgba_explicit::get_condition(ltl::formula* f)
|
||||||
{
|
{
|
||||||
assert(dynamic_cast<ltl::atomic_prop*>(f));
|
assert(dynamic_cast<ltl::atomic_prop*>(f));
|
||||||
tgba_bdd_dict::fv_map::iterator i = dict_.var_map.find(f);
|
tgba_bdd_dict::fv_map::iterator i = dict_.var_map.find(f);
|
||||||
|
|
@ -137,10 +137,20 @@ namespace spot
|
||||||
{
|
{
|
||||||
v = i->second;
|
v = i->second;
|
||||||
}
|
}
|
||||||
t->condition &= ithvar(v);
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tgba_explicit::add_promise(transition* t, ltl::formula* f)
|
void tgba_explicit::add_condition(transition* t, ltl::formula* f)
|
||||||
|
{
|
||||||
|
t->condition &= ithvar(get_condition(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tgba_explicit::add_neg_condition(transition* t, ltl::formula* f)
|
||||||
|
{
|
||||||
|
t->condition &= ! ithvar(get_condition(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
int tgba_explicit::get_promise(ltl::formula* f)
|
||||||
{
|
{
|
||||||
tgba_bdd_dict::fv_map::iterator i = dict_.prom_map.find(f);
|
tgba_bdd_dict::fv_map::iterator i = dict_.prom_map.find(f);
|
||||||
int v;
|
int v;
|
||||||
|
|
@ -154,7 +164,17 @@ namespace spot
|
||||||
{
|
{
|
||||||
v = i->second;
|
v = i->second;
|
||||||
}
|
}
|
||||||
t->promise &= ithvar(v);
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tgba_explicit::add_promise(transition* t, ltl::formula* f)
|
||||||
|
{
|
||||||
|
t->promise &= ithvar(get_promise(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tgba_explicit::add_neg_promise(transition* t, ltl::formula* f)
|
||||||
|
{
|
||||||
|
t->promise &= ! ithvar(get_promise(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
state*
|
state*
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,9 @@ namespace spot
|
||||||
create_transition(const std::string& source, const std::string& dest);
|
create_transition(const std::string& source, const std::string& dest);
|
||||||
|
|
||||||
void add_condition(transition* t, ltl::formula* f);
|
void add_condition(transition* t, ltl::formula* f);
|
||||||
|
void add_neg_condition(transition* t, ltl::formula* f);
|
||||||
void add_promise(transition* t, ltl::formula* f);
|
void add_promise(transition* t, ltl::formula* f);
|
||||||
|
void add_neg_promise(transition* t, ltl::formula* f);
|
||||||
|
|
||||||
// tgba interface
|
// tgba interface
|
||||||
virtual ~tgba_explicit();
|
virtual ~tgba_explicit();
|
||||||
|
|
@ -44,6 +46,9 @@ namespace spot
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
state* add_state(const std::string& name);
|
state* add_state(const std::string& name);
|
||||||
|
int get_condition(ltl::formula* f);
|
||||||
|
int get_promise(ltl::formula* f);
|
||||||
|
|
||||||
typedef std::map<const std::string, tgba_explicit::state*> ns_map;
|
typedef std::map<const std::string, tgba_explicit::state*> ns_map;
|
||||||
typedef std::map<const tgba_explicit::state*, std::string> sn_map;
|
typedef std::map<const tgba_explicit::state*, std::string> sn_map;
|
||||||
ns_map name_state_map_;
|
ns_map name_state_map_;
|
||||||
|
|
|
||||||
13
src/tgbaparse/.cvsignore
Normal file
13
src/tgbaparse/.cvsignore
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
.deps
|
||||||
|
Makefile
|
||||||
|
Makefile.in
|
||||||
|
location.hh
|
||||||
|
tgbaparse.cc
|
||||||
|
tgbaparse.hh
|
||||||
|
tgbaparse.output
|
||||||
|
tgbascan.cc
|
||||||
|
position.hh
|
||||||
|
stack.hh
|
||||||
|
*.lo
|
||||||
|
*.la
|
||||||
|
.libs
|
||||||
31
src/tgbaparse/Makefile.am
Normal file
31
src/tgbaparse/Makefile.am
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
AM_CPPFLAGS = -I$(srcdir)/..
|
||||||
|
AM_CXXFLAGS = $(WARNING_CXXFLAGS)
|
||||||
|
|
||||||
|
noinst_LTLIBRARIES = libtgbaparse.la
|
||||||
|
|
||||||
|
TGBAPARSE_YY = tgbaparse.yy
|
||||||
|
FROM_TGBAPARSE_YY_MAIN = tgbaparse.cc
|
||||||
|
FROM_TGBAPARSE_YY_OTHERS = \
|
||||||
|
stack.hh \
|
||||||
|
position.hh \
|
||||||
|
location.hh \
|
||||||
|
tgbaparse.hh
|
||||||
|
FROM_TGBAPARSE_YY = $(FROM_TGBAPARSE_YY_MAIN) $(FROM_TGBAPARSE_YY_OTHERS)
|
||||||
|
|
||||||
|
BUILT_SOURCES = $(FROM_TGBAPARSE_YY)
|
||||||
|
MAINTAINERCLEANFILES = $(FROM_TGBAPARSE_YY)
|
||||||
|
|
||||||
|
$(FROM_TGBAPARSE_YY_MAIN): $(srcdir)/$(TGBAPARSE_YY)
|
||||||
|
bison --defines --locations --skeleton=lalr1.cc --report=all \
|
||||||
|
$(srcdir)/$(TGBAPARSE_YY) -o $@
|
||||||
|
$(FROM_TGBAPARSE_YY_OTHERS): $(TGBAPARSE_YY)
|
||||||
|
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) $(FROM_TGBAPARSE_YY_MAIN)
|
||||||
|
|
||||||
|
EXTRA_DIST = $(TGBAPARSE_YY)
|
||||||
|
|
||||||
|
libtgbaparse_la_SOURCES = \
|
||||||
|
fmterror.cc \
|
||||||
|
$(FROM_TGBAPARSE_YY) \
|
||||||
|
tgbascan.ll \
|
||||||
|
parsedecl.hh \
|
||||||
|
public.hh
|
||||||
20
src/tgbaparse/fmterror.cc
Normal file
20
src/tgbaparse/fmterror.cc
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include "public.hh"
|
||||||
|
|
||||||
|
namespace spot
|
||||||
|
{
|
||||||
|
bool
|
||||||
|
format_tgba_parse_errors(std::ostream& os,
|
||||||
|
tgba_parse_error_list& error_list)
|
||||||
|
{
|
||||||
|
bool printed = false;
|
||||||
|
spot::tgba_parse_error_list::iterator it;
|
||||||
|
for (it = error_list.begin(); it != error_list.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->first.begin.filename != "")
|
||||||
|
os << it->first << ": ";
|
||||||
|
os << it->second << std::endl;
|
||||||
|
printed = true;
|
||||||
|
}
|
||||||
|
return printed;
|
||||||
|
}
|
||||||
|
}
|
||||||
32
src/tgbaparse/parsedecl.hh
Normal file
32
src/tgbaparse/parsedecl.hh
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef SPOT_TGBAPARSE_PARSEDECL_HH
|
||||||
|
# define SPOT_TGBAPARSE_PARSEDECL_HH
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "tgbaparse.hh"
|
||||||
|
#include "location.hh"
|
||||||
|
|
||||||
|
# define YY_DECL \
|
||||||
|
int tgbayylex (yystype *yylval, yy::Location *yylloc)
|
||||||
|
YY_DECL;
|
||||||
|
|
||||||
|
namespace spot
|
||||||
|
{
|
||||||
|
int tgbayyopen(const std::string& name);
|
||||||
|
void tgbayyclose();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Gross kludge to compile yy::Parser in another namespace (tgbayy::)
|
||||||
|
// but still use yy::Location. The reason is that Bison's C++
|
||||||
|
// skeleton does not support anything close to %name-prefix at the
|
||||||
|
// moment. All parser are named yy::Parser which makes it somewhat
|
||||||
|
// difficult to define multiple parsers.
|
||||||
|
namespace tgbayy
|
||||||
|
{
|
||||||
|
using namespace yy;
|
||||||
|
}
|
||||||
|
#define yy tgbayy
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // SPOT_TGBAPARSE_PARSEDECL_HH
|
||||||
49
src/tgbaparse/public.hh
Normal file
49
src/tgbaparse/public.hh
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
#ifndef SPOT_TGBAPARSE_PUBLIC_HH
|
||||||
|
# define SPOT_TGBAPARSE_PUBLIC_HH
|
||||||
|
|
||||||
|
# include "tgba/tgbaexplicit.hh"
|
||||||
|
# include "location.hh"
|
||||||
|
# include "ltlenv/defaultenv.hh"
|
||||||
|
# include <string>
|
||||||
|
# include <list>
|
||||||
|
# include <utility>
|
||||||
|
# include <iostream>
|
||||||
|
|
||||||
|
namespace spot
|
||||||
|
{
|
||||||
|
/// \brief A parse diagnostic with its location.
|
||||||
|
typedef std::pair<yy::Location, std::string> tgba_parse_error;
|
||||||
|
/// \brief A list of parser diagnostics, as filled by parse.
|
||||||
|
typedef std::list<tgba_parse_error> tgba_parse_error_list;
|
||||||
|
|
||||||
|
/// \brief Build a spot::tgba_explicit from a text file.
|
||||||
|
/// \param filename The name of the file 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 debug When true, causes the parser to trace its execution.
|
||||||
|
/// \return A pointer to the tgba built from \a filename, or
|
||||||
|
/// 0 if the file could not be opened.
|
||||||
|
///
|
||||||
|
/// Note that the parser usually tries to recover from errors. It can
|
||||||
|
/// return an non zero value even if it encountered error during the
|
||||||
|
/// parsing of \a filename. If you want to make sure \a filename
|
||||||
|
/// was parsed succesfully, check \a error_list for emptiness.
|
||||||
|
///
|
||||||
|
/// \warning This function is not reentrant.
|
||||||
|
tgba_explicit* tgba_parse(const std::string& filename,
|
||||||
|
tgba_parse_error_list& error_list,
|
||||||
|
ltl::environment& env
|
||||||
|
= ltl::default_environment::instance(),
|
||||||
|
bool debug = false);
|
||||||
|
|
||||||
|
/// \brief Format diagnostics produced by spot::tgba_parse.
|
||||||
|
/// \param os Where diagnostics should be output.
|
||||||
|
/// \param error_list The error list filled by spot::ltl::parse while
|
||||||
|
/// parsing \a ltl_string.
|
||||||
|
/// \return \c true iff any diagnostic was output.
|
||||||
|
bool format_tgba_parse_errors(std::ostream& os,
|
||||||
|
tgba_parse_error_list& error_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SPOT_TGBAPARSE_PUBLIC_HH
|
||||||
128
src/tgbaparse/tgbaparse.yy
Normal file
128
src/tgbaparse/tgbaparse.yy
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
%{
|
||||||
|
#include <string>
|
||||||
|
#include "public.hh"
|
||||||
|
%}
|
||||||
|
|
||||||
|
%parse-param {spot::tgba_parse_error_list &error_list}
|
||||||
|
%parse-param {spot::ltl::environment &parse_environment}
|
||||||
|
%parse-param {spot::tgba_explicit* &result}
|
||||||
|
%debug
|
||||||
|
%error-verbose
|
||||||
|
%union
|
||||||
|
{
|
||||||
|
int token;
|
||||||
|
std::string* str;
|
||||||
|
std::list<std::pair<bool, spot::ltl::formula*> >* list;
|
||||||
|
}
|
||||||
|
|
||||||
|
%{
|
||||||
|
/* tgbaparse.hh and parsedecl.hh include each other recursively.
|
||||||
|
We mut ensure that YYSTYPE is declared (by the above %union)
|
||||||
|
before parsedecl.hh uses it. */
|
||||||
|
#include "parsedecl.hh"
|
||||||
|
using namespace spot::ltl;
|
||||||
|
|
||||||
|
/* Ugly hack so that Bison use tgbayylex, not yylex.
|
||||||
|
(%name-prefix doesn't work for the lalr1.cc skeleton
|
||||||
|
at the time of writing.) */
|
||||||
|
#define yylex tgbayylex
|
||||||
|
|
||||||
|
typedef std::pair<bool, spot::ltl::formula*> pair;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%token <str> STRING
|
||||||
|
%token <str> IDENT
|
||||||
|
%type <str> strident
|
||||||
|
%type <list> prop_list
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
lines:
|
||||||
|
| lines line
|
||||||
|
;
|
||||||
|
|
||||||
|
line: strident ',' strident ',' prop_list ',' prop_list ';'
|
||||||
|
{
|
||||||
|
spot::tgba_explicit::transition* t
|
||||||
|
= result->create_transition(*$1, *$3);
|
||||||
|
std::list<pair>::iterator i;
|
||||||
|
for (i = $5->begin(); i != $5->end(); ++i)
|
||||||
|
if (i->first)
|
||||||
|
result->add_neg_condition(t, i->second);
|
||||||
|
else
|
||||||
|
result->add_condition(t, i->second);
|
||||||
|
for (i = $7->begin(); i != $7->end(); ++i)
|
||||||
|
if (i->first)
|
||||||
|
result->add_neg_promise(t, i->second);
|
||||||
|
else
|
||||||
|
result->add_promise(t, i->second);
|
||||||
|
delete $1;
|
||||||
|
delete $3;
|
||||||
|
delete $5;
|
||||||
|
delete $7;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
strident: STRING | IDENT;
|
||||||
|
|
||||||
|
prop_list:
|
||||||
|
{
|
||||||
|
$$ = new std::list<pair>;
|
||||||
|
}
|
||||||
|
| prop_list IDENT
|
||||||
|
{
|
||||||
|
$1->push_back(pair(false, parse_environment.require(*$2)));
|
||||||
|
delete $2;
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
|
| prop_list '!' IDENT
|
||||||
|
{
|
||||||
|
$1->push_back(pair(true, parse_environment.require(*$3)));
|
||||||
|
delete $3;
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
void
|
||||||
|
yy::Parser::print_()
|
||||||
|
{
|
||||||
|
if (looka_ == STRING || looka_ == IDENT)
|
||||||
|
YYCDEBUG << " '" << *value.str << "'";
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
yy::Parser::error_()
|
||||||
|
{
|
||||||
|
error_list.push_back(spot::tgba_parse_error(location, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace spot
|
||||||
|
{
|
||||||
|
tgba_explicit*
|
||||||
|
tgba_parse(const std::string& name,
|
||||||
|
tgba_parse_error_list& error_list,
|
||||||
|
environment& env,
|
||||||
|
bool debug)
|
||||||
|
{
|
||||||
|
if (tgbayyopen(name))
|
||||||
|
{
|
||||||
|
error_list.push_back
|
||||||
|
(tgba_parse_error(yy::Location(),
|
||||||
|
std::string("Cannot open file ") + name));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
tgba_explicit* result = new tgba_explicit;
|
||||||
|
tgbayy::Parser parser(debug, yy::Location(), error_list, env, result);
|
||||||
|
parser.parse();
|
||||||
|
tgbayyclose();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Local Variables:
|
||||||
|
// mode: c++
|
||||||
|
// End:
|
||||||
81
src/tgbaparse/tgbascan.ll
Normal file
81
src/tgbaparse/tgbascan.ll
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
%option noyywrap
|
||||||
|
%option prefix="tgbayy"
|
||||||
|
%option outfile="lex.yy.c"
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include <string>
|
||||||
|
#include "parsedecl.hh"
|
||||||
|
|
||||||
|
#define YY_USER_ACTION \
|
||||||
|
yylloc->columns(yyleng);
|
||||||
|
|
||||||
|
#define YY_USER_INIT \
|
||||||
|
do { \
|
||||||
|
yylloc->begin.filename = current_file; \
|
||||||
|
yylloc->end.filename = current_file; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define YY_NEVER_INTERACTIVE 1
|
||||||
|
|
||||||
|
static std::string current_file;
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
eol \n|\r|\n\r|\r\n
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
%{
|
||||||
|
yylloc->step ();
|
||||||
|
%}
|
||||||
|
|
||||||
|
\"[^\"]*\" {
|
||||||
|
yylval->str = new std::string(yytext + 1,
|
||||||
|
yyleng - 2);
|
||||||
|
return STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
[a-zA-Z][a-zA-Z0-9_]* {
|
||||||
|
yylval->str = new std::string(yytext);
|
||||||
|
return IDENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* discard whitespace */
|
||||||
|
{eol} yylloc->lines(yyleng); yylloc->step();
|
||||||
|
[ \t]+ yylloc->step();
|
||||||
|
|
||||||
|
. return *yytext;
|
||||||
|
|
||||||
|
%{
|
||||||
|
/* Dummy use of yyunput to shut up a gcc warning. */
|
||||||
|
(void) &yyunput;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
namespace spot
|
||||||
|
{
|
||||||
|
int
|
||||||
|
tgbayyopen(const std::string &name)
|
||||||
|
{
|
||||||
|
if (name == "-")
|
||||||
|
{
|
||||||
|
yyin = stdin;
|
||||||
|
current_file = "standard input";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yyin = fopen (name.c_str (), "r");
|
||||||
|
current_file = name;
|
||||||
|
if (!yyin)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tgbayyclose()
|
||||||
|
{
|
||||||
|
fclose(yyin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,3 +4,4 @@ Makefile.in
|
||||||
defs
|
defs
|
||||||
explicit
|
explicit
|
||||||
.libs
|
.libs
|
||||||
|
tgbaread
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,16 @@ LDADD = ../libspot.la
|
||||||
check_SCRIPTS = defs
|
check_SCRIPTS = defs
|
||||||
# Keep this sorted alphabetically.
|
# Keep this sorted alphabetically.
|
||||||
check_PROGRAMS = \
|
check_PROGRAMS = \
|
||||||
explicit
|
explicit \
|
||||||
|
tgbaread
|
||||||
|
|
||||||
explicit_SOURCES = explicit.cc
|
explicit_SOURCES = explicit.cc
|
||||||
|
tgbaread_SOURCES = tgbaread.cc
|
||||||
|
|
||||||
TESTS = \
|
TESTS = \
|
||||||
explicit.test
|
explicit.test \
|
||||||
|
tgbaread.test
|
||||||
|
|
||||||
EXTRA_DIST = $(TESTS)
|
EXTRA_DIST = $(TESTS)
|
||||||
|
|
||||||
CLEANFILES = stdout expected
|
CLEANFILES = inpu stdout expected
|
||||||
|
|
|
||||||
50
src/tgbatest/tgbaread.cc
Normal file
50
src/tgbatest/tgbaread.cc
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include "tgbaparse/public.hh"
|
||||||
|
#include "tgba/tgbaexplicit.hh"
|
||||||
|
#include "tgbaalgos/dotty.hh"
|
||||||
|
|
||||||
|
void
|
||||||
|
syntax(char* prog)
|
||||||
|
{
|
||||||
|
std::cerr << prog << " [-d] filename" << std::endl;
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int exit_code = 0;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
syntax(argv[0]);
|
||||||
|
|
||||||
|
bool debug = false;
|
||||||
|
int filename_index = 1;
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "-d"))
|
||||||
|
{
|
||||||
|
debug = true;
|
||||||
|
if (argc < 3)
|
||||||
|
syntax(argv[0]);
|
||||||
|
filename_index = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
spot::ltl::environment& env(spot::ltl::default_environment::instance());
|
||||||
|
spot::tgba_parse_error_list pel;
|
||||||
|
spot::tgba_explicit* a = spot::tgba_parse(argv[filename_index],
|
||||||
|
pel, env, debug);
|
||||||
|
|
||||||
|
exit_code =
|
||||||
|
spot::format_tgba_parse_errors(std::cerr, pel);
|
||||||
|
|
||||||
|
if (a)
|
||||||
|
{
|
||||||
|
spot::dotty_reachable(std::cout, *a);
|
||||||
|
delete a;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
exit_code = 1;
|
||||||
|
}
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
31
src/tgbatest/tgbaread.test
Executable file
31
src/tgbatest/tgbaread.test
Executable file
|
|
@ -0,0 +1,31 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. ./defs
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cat >input <<EOF
|
||||||
|
s1, "s2", a!b, c d;
|
||||||
|
"s2", "state 3", a, !c;
|
||||||
|
"state 3", s1,,;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
./tgbaread input > stdout
|
||||||
|
|
||||||
|
cat >expected <<EOF
|
||||||
|
digraph G {
|
||||||
|
size="7.26,10.69"
|
||||||
|
0 [label="", style=invis]
|
||||||
|
1 [label="s1"]
|
||||||
|
0 -> 1
|
||||||
|
2 [label="s2"]
|
||||||
|
1 -> 2 [label="<a:1, b:0>\n<Prom[c]:1, Prom[d]:1>"]
|
||||||
|
3 [label="state 3"]
|
||||||
|
2 -> 3 [label="<a:1>\n<Prom[c]:0>"]
|
||||||
|
3 -> 1 [label="T\nT"]
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
diff stdout expected
|
||||||
|
|
||||||
|
rm input stdout expected
|
||||||
Loading…
Add table
Add a link
Reference in a new issue