rename src/ as spot/ and use include <spot/...>
* NEWS: Mention the change. * src/: Rename as ... * spot/: ... this, adjust all headers to include <spot/...> instead of "...", and adjust all Makefile.am to search headers from the top-level directory. * HACKING: Add conventions about #include. * spot/sanity/style.test: Add a few more grep to catch cases that do not follow these conventions. * .gitignore, Makefile.am, README, bench/stutter/Makefile.am, bench/stutter/stutter_invariance_formulas.cc, bench/stutter/stutter_invariance_randomgraph.cc, configure.ac, debian/rules, doc/Doxyfile.in, doc/Makefile.am, doc/org/.dir-locals.el.in, doc/org/g++wrap.in, doc/org/init.el.in, doc/org/tut01.org, doc/org/tut02.org, doc/org/tut03.org, doc/org/tut10.org, doc/org/tut20.org, doc/org/tut21.org, doc/org/tut22.org, doc/org/tut30.org, iface/ltsmin/Makefile.am, iface/ltsmin/kripke.test, iface/ltsmin/ltsmin.cc, iface/ltsmin/ltsmin.hh, iface/ltsmin/modelcheck.cc, wrap/python/Makefile.am, wrap/python/ajax/spotcgi.in, wrap/python/spot_impl.i, wrap/python/tests/ltl2tgba.py, wrap/python/tests/randgen.py, wrap/python/tests/run.in: Adjust.
This commit is contained in:
parent
1fddfe60ec
commit
f120dd3206
529 changed files with 1308 additions and 1262 deletions
7
spot/parseaut/.gitignore
vendored
Normal file
7
spot/parseaut/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
position.hh
|
||||
parseaut.cc
|
||||
parseaut.output
|
||||
parseaut.hh
|
||||
scanaut.cc
|
||||
stack.hh
|
||||
location.hh
|
||||
57
spot/parseaut/Makefile.am
Normal file
57
spot/parseaut/Makefile.am
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## Copyright (C) 2013, 2014 Laboratoire de Recherche et Développement de
|
||||
## l'Epita (LRDE).
|
||||
##
|
||||
## This file is part of Spot, a model checking library.
|
||||
##
|
||||
## Spot is free software; you can redistribute it and/or modify it
|
||||
## under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
## License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) $(BUDDY_CPPFLAGS) -DYY_NO_INPUT
|
||||
# Disable -Werror because too many versions of flex yield warnings.
|
||||
AM_CXXFLAGS = $(WARNING_CXXFLAGS:-Werror=)
|
||||
|
||||
parseautdir = $(pkgincludedir)/parseaut
|
||||
|
||||
parseaut_HEADERS = public.hh
|
||||
|
||||
noinst_LTLIBRARIES = libparseaut.la
|
||||
|
||||
HOAPARSE_YY = parseaut.yy
|
||||
FROM_HOAPARSE_YY_MAIN = parseaut.cc
|
||||
FROM_HOAPARSE_YY_OTHERS = \
|
||||
stack.hh \
|
||||
parseaut.hh
|
||||
|
||||
FROM_HOAPARSE_YY = $(FROM_HOAPARSE_YY_MAIN) $(FROM_HOAPARSE_YY_OTHERS)
|
||||
|
||||
BUILT_SOURCES = $(FROM_HOAPARSE_YY)
|
||||
MAINTAINERCLEANFILES = $(FROM_HOAPARSE_YY)
|
||||
|
||||
$(FROM_HOAPARSE_YY_MAIN): $(srcdir)/$(HOAPARSE_YY)
|
||||
## We must cd into $(srcdir) first because if we tell bison to read
|
||||
## $(srcdir)/$(HOAPARSE_YY), it will also use the value of $(srcdir)/
|
||||
## in the generated include statements.
|
||||
cd $(srcdir) && \
|
||||
$(BISON) -Wall -Werror -Wno-yacc --report=all $(BISON_EXTRA_FLAGS) \
|
||||
$(HOAPARSE_YY) -o $(FROM_HOAPARSE_YY_MAIN)
|
||||
$(FROM_HOAPARSE_YY_OTHERS): $(HOAPARSE_YY)
|
||||
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) $(FROM_HOAPARSE_YY_MAIN)
|
||||
|
||||
EXTRA_DIST = $(HOAPARSE_YY)
|
||||
|
||||
libparseaut_la_SOURCES = \
|
||||
fmterror.cc \
|
||||
$(FROM_HOAPARSE_YY) \
|
||||
scanaut.ll \
|
||||
parsedecl.hh
|
||||
40
spot/parseaut/fmterror.cc
Normal file
40
spot/parseaut/fmterror.cc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <ostream>
|
||||
#include <spot/parseaut/public.hh>
|
||||
|
||||
namespace spot
|
||||
{
|
||||
bool
|
||||
parsed_aut::format_errors(std::ostream& os)
|
||||
{
|
||||
bool printed = false;
|
||||
spot::parse_aut_error_list::iterator it;
|
||||
for (auto& err : errors)
|
||||
{
|
||||
if (!filename.empty() && filename != "-")
|
||||
os << filename << ':';
|
||||
os << err.first << ": ";
|
||||
os << err.second << std::endl;
|
||||
printed = true;
|
||||
}
|
||||
return printed;
|
||||
}
|
||||
}
|
||||
2149
spot/parseaut/parseaut.yy
Normal file
2149
spot/parseaut/parseaut.yy
Normal file
File diff suppressed because it is too large
Load diff
45
spot/parseaut/parsedecl.hh
Normal file
45
spot/parseaut/parsedecl.hh
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement
|
||||
// de l'EPITA.
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <spot/parseaut/parseaut.hh>
|
||||
#include <spot/misc/location.hh>
|
||||
|
||||
# define YY_DECL \
|
||||
int hoayylex(hoayy::parser::semantic_type *yylval, \
|
||||
spot::location *yylloc, \
|
||||
spot::parse_aut_error_list& error_list)
|
||||
YY_DECL;
|
||||
|
||||
namespace spot
|
||||
{
|
||||
void hoayyreset();
|
||||
int hoayyopen(const std::string& name);
|
||||
int hoayyopen(int fd);
|
||||
int hoayystring(const char* data);
|
||||
void hoayyclose();
|
||||
|
||||
// This exception is thrown by the lexer when it reads "--ABORT--".
|
||||
struct hoa_abort
|
||||
{
|
||||
spot::location pos;
|
||||
};
|
||||
}
|
||||
194
spot/parseaut/public.hh
Normal file
194
spot/parseaut/public.hh
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2013, 2014, 2015 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <spot/twa/twagraph.hh>
|
||||
#include <spot/kripke/kripkegraph.hh>
|
||||
#include <spot/misc/location.hh>
|
||||
#include <spot/tl/defaultenv.hh>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include <iosfwd>
|
||||
#include <spot/misc/bitvect.hh>
|
||||
|
||||
namespace spot
|
||||
{
|
||||
/// \addtogroup twa_io
|
||||
/// @{
|
||||
|
||||
#ifndef SWIG
|
||||
/// \brief A parse diagnostic with its location.
|
||||
typedef std::pair<spot::location, std::string> parse_aut_error;
|
||||
/// \brief A list of parser diagnostics, as filled by parse.
|
||||
typedef std::list<parse_aut_error> parse_aut_error_list;
|
||||
#else
|
||||
// Turn parse_aut_error_list into an opaque type for Swig.
|
||||
struct parse_aut_error_list {};
|
||||
#endif
|
||||
|
||||
enum class parsed_aut_type { HOA, NeverClaim, LBTT, DRA, DSA, Unknown };
|
||||
|
||||
/// \brief Result of the automaton parser
|
||||
struct SPOT_API parsed_aut final
|
||||
{
|
||||
/// \brief The parsed automaton.
|
||||
///
|
||||
/// May be null if the parser reached the end of the stream or a
|
||||
/// serious error. In the latter case, \c errors is non-empty.
|
||||
/// May also be null if the parser is used to parse a Kripke
|
||||
/// structure.
|
||||
twa_graph_ptr aut;
|
||||
/// \brief The parsed kripke structure.
|
||||
///
|
||||
/// Used instead of \c aut when the parser is called with option
|
||||
/// want_kripke.
|
||||
kripke_graph_ptr ks;
|
||||
|
||||
/// Whether an HOA file was termined with <code>--ABORT</code>
|
||||
bool aborted = false;
|
||||
/// Location of the automaton in the stream.
|
||||
spot::location loc;
|
||||
/// Format of the automaton.
|
||||
parsed_aut_type type = parsed_aut_type::Unknown;
|
||||
/// Name of the stream (used for displaying syntax errors)
|
||||
const std::string filename;
|
||||
/// \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.
|
||||
parse_aut_error_list errors;
|
||||
|
||||
parsed_aut(const std::string& str)
|
||||
: filename(str)
|
||||
{
|
||||
}
|
||||
/// \brief Format diagnostics produced by spot::parse_aut.
|
||||
/// \param os Where diagnostics should be output.
|
||||
/// \return \c true iff any diagnostic was output.
|
||||
bool format_errors(std::ostream& os);
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<parsed_aut> parsed_aut_ptr;
|
||||
typedef std::shared_ptr<const parsed_aut> const_parsed_aut_ptr;
|
||||
|
||||
struct automaton_parser_options final
|
||||
{
|
||||
bool ignore_abort = false; ///< Skip aborted automata
|
||||
bool debug = false; ///< Run the parser in debug mode?
|
||||
bool trust_hoa = true; ///< Trust properties in HOA files
|
||||
bool raise_errors = false; ///< Raise errors as exceptions.
|
||||
bool want_kripke = false; ///< Parse as a Kripke structure.
|
||||
};
|
||||
|
||||
/// \brief Parse a stream of automata
|
||||
///
|
||||
/// This object should be constructed for a given stream (a file, a
|
||||
/// file descriptor, or a raw buffer), and then it parse() method
|
||||
/// may be called in a loop to parse each automaton in the stream.
|
||||
///
|
||||
/// Several input formats are supported, and automatically
|
||||
/// recognized: HOA, LBTT, DSTAR, or neverclaim. We recommend
|
||||
/// using the HOA format, because it is the most general.
|
||||
///
|
||||
/// The specification of the HOA format can be found at
|
||||
/// http://adl.github.io/hoaf/
|
||||
///
|
||||
/// The grammar of neverclaim will not accept every possible
|
||||
/// neverclaim output. It has been tuned to accept the output of
|
||||
/// spin -f, ltl2ba, ltl3ba, and modella. If you know of some other
|
||||
/// tool that produce Büchi automata in the form of a neverclaim,
|
||||
/// but is not understood by this parser, please report it to
|
||||
/// spot@lrde.epita.fr.
|
||||
class SPOT_API automaton_stream_parser final
|
||||
{
|
||||
spot::location last_loc;
|
||||
std::string filename_;
|
||||
automaton_parser_options opts_;
|
||||
public:
|
||||
/// \brief Parse from a file opened file descriptor.
|
||||
///
|
||||
/// \param filename The file to read from.
|
||||
/// \param opts Parser options.
|
||||
automaton_stream_parser(const std::string& filename,
|
||||
automaton_parser_options opts = {});
|
||||
|
||||
/// \brief Parse from an already opened file descriptor.
|
||||
///
|
||||
/// \param fd The file descriptor to read from.
|
||||
/// \param filename What to display in error messages.
|
||||
/// \param opts Parser options.
|
||||
automaton_stream_parser(int fd, const std::string& filename,
|
||||
automaton_parser_options opts = {});
|
||||
|
||||
/// \brief Parse from a buffer
|
||||
///
|
||||
/// \param data The buffer to read from.
|
||||
/// \param filename What to display in error messages.
|
||||
/// \param opts Parser options.
|
||||
automaton_stream_parser(const char* data,
|
||||
const std::string& filename,
|
||||
automaton_parser_options opts = {});
|
||||
|
||||
~automaton_stream_parser();
|
||||
|
||||
/// \brief Parse the next automaton in the stream.
|
||||
///
|
||||
/// Note that the parser usually tries to recover from errors. It
|
||||
/// can return an automaton even if it encountered an error during
|
||||
/// parsing. If you want to make sure the input was parsed
|
||||
/// successfully, make sure \c errors is empty and \c aborted is
|
||||
/// false in the result. (Testing \c aborted is obviously
|
||||
/// superfluous if the parser is configured to skip aborted
|
||||
/// automata.)
|
||||
///
|
||||
/// The \c aut field of the result can be null in two conditions:
|
||||
/// some serious error occurred (in this case \c errors is non
|
||||
/// empty), or the end of the stream was reached.
|
||||
///
|
||||
/// \warning This function is not reentrant.
|
||||
parsed_aut_ptr parse(const bdd_dict_ptr& dict,
|
||||
environment& env =
|
||||
default_environment::instance());
|
||||
};
|
||||
|
||||
/// \brief Read the first spot::twa_graph from a file.
|
||||
/// \param filename The name of the file to parse.
|
||||
/// \param dict The BDD dictionary where to use.
|
||||
/// \param env The environment of atomic proposition into which parsing
|
||||
/// should take place.
|
||||
/// \param opts Additional options to pass to the parser.
|
||||
/// \return A pointer to a \c parsed_aut structure.
|
||||
///
|
||||
/// This is a wrapper around spot::automaton_stream_parser that returns
|
||||
/// the first automaton of the file. Empty inputs are reported as
|
||||
/// syntax errors, so the \c aut field of the result is guaranteed not
|
||||
/// to be null if \c errors is empty. (This is unlike
|
||||
/// automaton_stream_parser::parse() where a null \c aut denots the
|
||||
/// end of a stream.)
|
||||
///
|
||||
/// \warning This function is not reentrant.
|
||||
SPOT_API parsed_aut_ptr
|
||||
parse_aut(const std::string& filename,
|
||||
const bdd_dict_ptr& dict,
|
||||
environment& env = default_environment::instance(),
|
||||
automaton_parser_options opts = {});
|
||||
/// @}
|
||||
}
|
||||
473
spot/parseaut/scanaut.ll
Normal file
473
spot/parseaut/scanaut.ll
Normal file
|
|
@ -0,0 +1,473 @@
|
|||
/* -*- coding: utf-8 -*-
|
||||
** Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement
|
||||
** de l'Epita (LRDE).
|
||||
**
|
||||
** This file is part of Spot, a model checking library.
|
||||
**
|
||||
** Spot is free software; you can redistribute it and/or modify it
|
||||
** under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
** License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
%option noyywrap
|
||||
%option prefix="hoayy"
|
||||
%option outfile="lex.yy.c"
|
||||
/* %option debug */
|
||||
|
||||
%{
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
#include <spot/parseaut/parsedecl.hh>
|
||||
#include "spot/priv/trim.hh"
|
||||
|
||||
#define YY_USER_ACTION yylloc->columns(yyleng);
|
||||
#define YY_NEVER_INTERACTIVE 1
|
||||
|
||||
typedef hoayy::parser::token token;
|
||||
static unsigned comment_level = 0;
|
||||
static unsigned parent_level = 0;
|
||||
static int orig_cond = 0;
|
||||
static bool lbtt_s = false;
|
||||
static bool lbtt_t = false;
|
||||
static unsigned lbtt_states = 0;
|
||||
|
||||
%}
|
||||
|
||||
eol \n+|\r+
|
||||
eol2 (\n\r)+|(\r\n)+
|
||||
eols ({eol}|{eol2})*
|
||||
identifier [[:alpha:]_][[:alnum:]_.-]*
|
||||
|
||||
%x in_COMMENT in_STRING in_NEVER_PAR
|
||||
%s in_HOA in_NEVER in_LBTT_HEADER
|
||||
%s in_LBTT_STATE in_LBTT_INIT in_LBTT_TRANS
|
||||
%s in_LBTT_T_ACC in_LBTT_S_ACC in_LBTT_GUARD
|
||||
%s in_DSTAR
|
||||
%%
|
||||
|
||||
%{
|
||||
std::string s;
|
||||
yylloc->step();
|
||||
|
||||
auto parse_int = [&](){
|
||||
errno = 0;
|
||||
char* end;
|
||||
unsigned long n = strtoul(yytext, &end, 10);
|
||||
yylval->num = n;
|
||||
if (errno || yylval->num != n)
|
||||
{
|
||||
error_list.push_back(spot::parse_aut_error(*yylloc, "value too large"));
|
||||
yylval->num = 0;
|
||||
}
|
||||
return end;
|
||||
};
|
||||
%}
|
||||
|
||||
|
||||
/* skip blanks and comments */
|
||||
{eol} yylloc->lines(yyleng); yylloc->step();
|
||||
{eol2} yylloc->lines(yyleng / 2); yylloc->step();
|
||||
[ \t\v\f]+ yylloc->step();
|
||||
"/""*"+ {
|
||||
orig_cond = YY_START;
|
||||
BEGIN(in_COMMENT);
|
||||
comment_level = 1;
|
||||
}
|
||||
<INITIAL>"HOA:" BEGIN(in_HOA); return token::HOA;
|
||||
<INITIAL,in_HOA>"--ABORT--" BEGIN(INITIAL); throw spot::hoa_abort{*yylloc};
|
||||
<INITIAL>"never" BEGIN(in_NEVER); return token::NEVER;
|
||||
<INITIAL>"DSA" BEGIN(in_DSTAR); return token::DSA;
|
||||
<INITIAL>"DRA" BEGIN(in_DSTAR); return token::DRA;
|
||||
|
||||
<INITIAL>[0-9]+[ \t][0-9]+[ts]? {
|
||||
BEGIN(in_LBTT_HEADER);
|
||||
char* end = 0;
|
||||
errno = 0;
|
||||
unsigned long n = strtoul(yytext, &end, 10);
|
||||
yylval->num = n;
|
||||
unsigned s = end - yytext;
|
||||
yylloc->end = yylloc->begin;
|
||||
yylloc->end.columns(s);
|
||||
yyless(s);
|
||||
if (errno || yylval->num != n)
|
||||
{
|
||||
error_list.push_back(
|
||||
spot::parse_aut_error(*yylloc,
|
||||
"value too large"));
|
||||
yylval->num = 0;
|
||||
}
|
||||
lbtt_states = yylval->num;
|
||||
return token::LBTT;
|
||||
}
|
||||
|
||||
<in_HOA>{
|
||||
"States:" return token::STATES;
|
||||
"Start:" return token::START;
|
||||
"AP:" return token::AP;
|
||||
"Alias:" return token::ALIAS;
|
||||
"Acceptance:" return token::ACCEPTANCE;
|
||||
"acc-name:" return token::ACCNAME;
|
||||
"tool:" return token::TOOL;
|
||||
"name:" return token::NAME;
|
||||
"properties:" return token::PROPERTIES;
|
||||
"--BODY--" return token::BODY;
|
||||
"--END--" BEGIN(INITIAL); return token::END;
|
||||
"State:" return token::STATE;
|
||||
[tf{}()\[\]&|!] return *yytext;
|
||||
|
||||
{identifier} {
|
||||
yylval->str = new std::string(yytext, yyleng);
|
||||
return token::IDENTIFIER;
|
||||
}
|
||||
{identifier}":" {
|
||||
yylval->str = new std::string(yytext, yyleng - 1);
|
||||
return token::HEADERNAME;
|
||||
}
|
||||
"@"[[:alnum:]_.-]+ {
|
||||
yylval->str = new std::string(yytext + 1, yyleng - 1);
|
||||
return token::ANAME;
|
||||
}
|
||||
[0-9]+ parse_int(); return token::INT;
|
||||
}
|
||||
|
||||
<in_DSTAR>{
|
||||
"States:" return token::STATES;
|
||||
"State:" return token::STATE;
|
||||
"Start:" return token::START;
|
||||
"AP:" return token::AP;
|
||||
"v2" return token::V2;
|
||||
"explicit" return token::EXPLICIT;
|
||||
"Comment:".* yylloc->step();
|
||||
"//".* yylloc->step();
|
||||
"Acceptance-Pairs:" return token::ACCPAIRS;
|
||||
"Acc-Sig:" return token::ACCSIG;
|
||||
"---" return token::ENDOFHEADER;
|
||||
[0-9]+ parse_int(); return token::INT;
|
||||
/* The start of any automaton is the end of this one.
|
||||
We do not try to detect LBTT automata, as that would
|
||||
be too hard to distinguish from state numbers. */
|
||||
{eols}("HOA:"|"never"|"DSA"|"DRA") {
|
||||
yylloc->end = yylloc->begin;
|
||||
yyless(0);
|
||||
BEGIN(INITIAL);
|
||||
return token::ENDDSTAR;
|
||||
}
|
||||
<<EOF>> return token::ENDDSTAR;
|
||||
}
|
||||
|
||||
<in_NEVER>{
|
||||
"skip" return token::SKIP;
|
||||
"if" return token::IF;
|
||||
"fi" return token::FI;
|
||||
"do" return token::DO;
|
||||
"od" return token::OD;
|
||||
"->" return token::ARROW;
|
||||
"goto" return token::GOTO;
|
||||
"false"|"0" return token::FALSE;
|
||||
"atomic" return token::ATOMIC;
|
||||
"assert" return token::ASSERT;
|
||||
|
||||
("!"[ \t]*)?"(" {
|
||||
parent_level = 1;
|
||||
BEGIN(in_NEVER_PAR);
|
||||
yylval->str = new std::string(yytext, yyleng);
|
||||
}
|
||||
|
||||
"true"|"1" {
|
||||
yylval->str = new std::string(yytext, yyleng);
|
||||
return token::FORMULA;
|
||||
}
|
||||
|
||||
[a-zA-Z][a-zA-Z0-9_]* {
|
||||
yylval->str = new std::string(yytext, yyleng);
|
||||
return token::IDENTIFIER;
|
||||
}
|
||||
}
|
||||
|
||||
/* Note: the LBTT format is scanf friendly, but not Bison-friendly.
|
||||
If we only tokenize it as a stream of INTs, the parser will have
|
||||
a very hard time recognizing what is a state from what is a
|
||||
transitions. As a consequence we abuse the start conditions to
|
||||
maintain a state an return integers with different semantic types
|
||||
depending on the purpose of those integers. */
|
||||
<in_LBTT_HEADER>{
|
||||
[0-9]+[st]* {
|
||||
BEGIN(in_LBTT_STATE);
|
||||
auto end = parse_int();
|
||||
lbtt_s = false;
|
||||
lbtt_t = false;
|
||||
if (end)
|
||||
while (int c = *end++)
|
||||
if (c == 's')
|
||||
lbtt_s = true;
|
||||
else // c == 't'
|
||||
lbtt_t = true;
|
||||
if (!lbtt_t)
|
||||
lbtt_s = true;
|
||||
if (lbtt_states == 0)
|
||||
{
|
||||
BEGIN(INITIAL);
|
||||
return token::LBTT_EMPTY;
|
||||
}
|
||||
if (lbtt_s && !lbtt_t)
|
||||
return token::INT_S;
|
||||
else
|
||||
return token::INT;
|
||||
}
|
||||
}
|
||||
|
||||
<in_LBTT_STATE>[0-9]+ {
|
||||
parse_int();
|
||||
BEGIN(in_LBTT_INIT);
|
||||
return token::STATE_NUM;
|
||||
}
|
||||
<in_LBTT_INIT>[01] {
|
||||
yylval->num = *yytext - '0';
|
||||
if (lbtt_s)
|
||||
BEGIN(in_LBTT_S_ACC);
|
||||
else
|
||||
BEGIN(in_LBTT_TRANS);
|
||||
return token::INT;
|
||||
}
|
||||
<in_LBTT_S_ACC>{
|
||||
[0-9]+ parse_int(); return token::ACC;
|
||||
"-1" BEGIN(in_LBTT_TRANS); yylloc->step();
|
||||
}
|
||||
<in_LBTT_TRANS>{
|
||||
[0-9]+ {
|
||||
parse_int();
|
||||
if (lbtt_t)
|
||||
BEGIN(in_LBTT_T_ACC);
|
||||
else
|
||||
BEGIN(in_LBTT_GUARD);
|
||||
return token::DEST_NUM;
|
||||
}
|
||||
"-1" {
|
||||
if (--lbtt_states)
|
||||
{
|
||||
BEGIN(in_LBTT_STATE);
|
||||
yylloc->step();
|
||||
}
|
||||
else
|
||||
{
|
||||
BEGIN(INITIAL);
|
||||
return token::ENDAUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
<in_LBTT_T_ACC>{
|
||||
[0-9]+ parse_int(); return token::ACC;
|
||||
"-1" BEGIN(in_LBTT_GUARD); yylloc->step();
|
||||
}
|
||||
<in_LBTT_GUARD>{
|
||||
[^\n\r]* {
|
||||
yylval->str = new std::string(yytext, yyleng);
|
||||
BEGIN(in_LBTT_TRANS);
|
||||
return token::STRING;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
<in_COMMENT>{
|
||||
"/""*"+ ++comment_level;
|
||||
[^*/\n\r]* continue;
|
||||
"/"[^*\n\r]* continue;
|
||||
"*"+[^*/\n\r]* continue;
|
||||
{eol} yylloc->lines(yyleng); yylloc->end.column = 1;
|
||||
{eol2} yylloc->lines(yyleng / 2); yylloc->end.column = 1;
|
||||
"*"+"/" {
|
||||
if (--comment_level == 0)
|
||||
{
|
||||
yylloc->step();
|
||||
BEGIN(orig_cond);
|
||||
}
|
||||
}
|
||||
<<EOF>> {
|
||||
BEGIN(orig_cond);
|
||||
error_list.push_back(
|
||||
spot::parse_aut_error(*yylloc,
|
||||
"unclosed comment"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* matched late, so that the in_LBTT_GUARD pattern has precedence */
|
||||
"\"" {
|
||||
orig_cond = YY_START;
|
||||
BEGIN(in_STRING);
|
||||
comment_level = 1;
|
||||
}
|
||||
|
||||
<in_STRING>{
|
||||
\" {
|
||||
BEGIN(orig_cond);
|
||||
yylval->str = new std::string(s);
|
||||
return token::STRING;
|
||||
}
|
||||
{eol} {
|
||||
s.append(yytext, yyleng);
|
||||
yylloc->lines(yyleng); yylloc->end.column = 1;
|
||||
}
|
||||
{eol2} {
|
||||
s.append(yytext, yyleng);
|
||||
yylloc->lines(yyleng / 2); yylloc->end.column = 1;
|
||||
}
|
||||
\\. s += yytext[1];
|
||||
[^\\\"\n\r]+ s.append(yytext, yyleng);
|
||||
<<EOF>> {
|
||||
error_list.push_back(
|
||||
spot::parse_aut_error(*yylloc,
|
||||
"unclosed string"));
|
||||
BEGIN(orig_cond);
|
||||
yylval->str = new std::string(s);
|
||||
return token::STRING;
|
||||
}
|
||||
}
|
||||
|
||||
<in_NEVER_PAR>{
|
||||
"(" {
|
||||
++parent_level;
|
||||
yylval->str->append(yytext, yyleng);
|
||||
}
|
||||
/* if we match ")&&(" or ")||(", stay in <in_NEVER_PAR> mode */
|
||||
")"[ \t]*("&&"|"||")[ \t!]*"(" {
|
||||
yylval->str->append(yytext, yyleng);
|
||||
}
|
||||
")" {
|
||||
yylval->str->append(yytext, yyleng);
|
||||
if (!--parent_level)
|
||||
{
|
||||
BEGIN(in_NEVER);
|
||||
spot::trim(*yylval->str);
|
||||
return token::FORMULA;
|
||||
}
|
||||
}
|
||||
{eol} {
|
||||
yylval->str->append(yytext, yyleng);
|
||||
yylloc->lines(yyleng); yylloc->end.column = 1;
|
||||
}
|
||||
{eol2} {
|
||||
yylval->str->append(yytext, yyleng);
|
||||
yylloc->lines(yyleng / 2); yylloc->end.column = 1;
|
||||
}
|
||||
[^()\n\r]+ yylval->str->append(yytext, yyleng);
|
||||
<<EOF>> {
|
||||
error_list.push_back(
|
||||
spot::parse_aut_error(*yylloc,
|
||||
"missing closing parenthese"));
|
||||
yylval->str->append(parent_level, ')');
|
||||
BEGIN(in_NEVER);
|
||||
spot::trim(*yylval->str);
|
||||
return token::FORMULA;
|
||||
}
|
||||
}
|
||||
|
||||
. return *yytext;
|
||||
|
||||
%{
|
||||
/* Dummy use of yyunput to shut up a gcc warning. */
|
||||
(void) &yyunput;
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
namespace spot
|
||||
{
|
||||
void
|
||||
hoayyreset()
|
||||
{
|
||||
BEGIN(INITIAL);
|
||||
comment_level = 0;
|
||||
parent_level = 0;
|
||||
}
|
||||
|
||||
int
|
||||
hoayyopen(const std::string &name)
|
||||
{
|
||||
bool want_interactive = false;
|
||||
|
||||
// yy_flex_debug = 1;
|
||||
if (name == "-")
|
||||
{
|
||||
// If the input is a pipe, make the scanner
|
||||
// interactive so that it does not wait for the input
|
||||
// buffer to be full to process automata.
|
||||
struct stat s;
|
||||
if (fstat(fileno(stdin), &s) < 0)
|
||||
throw std::runtime_error("fstat failed");
|
||||
if (S_ISFIFO(s.st_mode))
|
||||
want_interactive = true;
|
||||
|
||||
// Only set yyin once we know we will use
|
||||
// it, so that we do not close it otherwise.
|
||||
yyin = stdin;
|
||||
}
|
||||
else
|
||||
{
|
||||
yyin = fopen(name.c_str(), "r");
|
||||
if (!yyin)
|
||||
return 1;
|
||||
}
|
||||
// Reset the lexer in case a previous parse
|
||||
// ended badly.
|
||||
YY_NEW_FILE;
|
||||
hoayyreset();
|
||||
if (want_interactive)
|
||||
yy_set_interactive(true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hoayystring(const char* data)
|
||||
{
|
||||
yy_scan_string(data);
|
||||
hoayyreset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hoayyopen(int fd)
|
||||
{
|
||||
bool want_interactive = false;
|
||||
|
||||
yyin = fdopen(fd, "r");
|
||||
|
||||
if (!yyin)
|
||||
throw std::runtime_error("fdopen failed");
|
||||
|
||||
// If the input is a pipe, make the scanner
|
||||
// interactive so that it does not wait for the input
|
||||
// buffer to be full to process automata.
|
||||
struct stat s;
|
||||
if (fstat(fd, &s) < 0)
|
||||
throw std::runtime_error("fstat failed");
|
||||
if (S_ISFIFO(s.st_mode))
|
||||
want_interactive = true;
|
||||
|
||||
// Reset the lexer in case a previous parse
|
||||
// ended badly.
|
||||
YY_NEW_FILE;
|
||||
hoayyreset();
|
||||
if (want_interactive)
|
||||
yy_set_interactive(true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
hoayyclose()
|
||||
{
|
||||
if (yyin)
|
||||
{
|
||||
fclose(yyin);
|
||||
yyin = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue