* 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
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);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue