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
14
spot/parsetl/.gitignore
vendored
Normal file
14
spot/parsetl/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
location.hh
|
||||
parsetl.cc
|
||||
parsetl.hh
|
||||
parsetl.output
|
||||
scantl.cc
|
||||
position.hh
|
||||
readltl
|
||||
stack.hh
|
||||
*.lo
|
||||
*.la
|
||||
.libs
|
||||
55
spot/parsetl/Makefile.am
Normal file
55
spot/parsetl/Makefile.am
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015
|
||||
## Laboratoire de Recherche et Développement de l'Epita (LRDE).
|
||||
## Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris
|
||||
## 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||
## Université Pierre et Marie Curie.
|
||||
##
|
||||
## 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) -DYY_NO_INPUT
|
||||
# Disable -Werror because too many versions of flex yield warnings.
|
||||
AM_CXXFLAGS = $(WARNING_CXXFLAGS:-Werror=)
|
||||
|
||||
noinst_LTLIBRARIES = libparsetl.la
|
||||
|
||||
PARSETL_YY = parsetl.yy
|
||||
FROM_PARSETL_YY_MAIN = parsetl.cc
|
||||
FROM_PARSETL_YY_OTHERS = \
|
||||
stack.hh \
|
||||
parsetl.hh
|
||||
FROM_PARSETL_YY = $(FROM_PARSETL_YY_MAIN) $(FROM_PARSETL_YY_OTHERS)
|
||||
|
||||
BUILT_SOURCES = $(FROM_PARSETL_YY)
|
||||
MAINTAINERCLEANFILES = $(FROM_PARSETL_YY)
|
||||
|
||||
$(FROM_PARSETL_YY_MAIN): $(srcdir)/$(PARSETL_YY)
|
||||
## We must cd into $(srcdir) first because if we tell bison to read
|
||||
## $(srcdir)/$(PARSETL_YY), it will also use the value of $(srcdir)/
|
||||
## in the generated include statements.
|
||||
cd $(srcdir) && \
|
||||
$(BISON) -Wall -Werror --report=all $(BISON_EXTRA_FLAGS) \
|
||||
$(PARSETL_YY) -o $(FROM_PARSETL_YY_MAIN)
|
||||
$(FROM_PARSETL_YY_OTHERS): $(PARSETL_YY)
|
||||
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) $(FROM_PARSETL_YY_MAIN)
|
||||
|
||||
EXTRA_DIST = $(PARSETL_YY)
|
||||
|
||||
libparsetl_la_SOURCES = \
|
||||
fmterror.cc \
|
||||
$(FROM_PARSETL_YY) \
|
||||
scantl.ll \
|
||||
parsedecl.hh
|
||||
112
spot/parsetl/fmterror.cc
Normal file
112
spot/parsetl/fmterror.cc
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2010, 2012, 2013, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
// Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de Paris
|
||||
// 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||
// Université Pierre et Marie Curie.
|
||||
//
|
||||
// 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 <spot/tl/parse.hh>
|
||||
#include <ostream>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include "utf8/utf8.h"
|
||||
|
||||
namespace spot
|
||||
{
|
||||
void
|
||||
fix_utf8_locations(const std::string& ltl_string,
|
||||
parse_error_list& error_list)
|
||||
{
|
||||
// LUT to convert byte positions to utf8 positions.
|
||||
// (The +2 is to account for position 0, not used,
|
||||
// and position ltl_string.size()+1 denoting EOS.)
|
||||
std::vector<unsigned> b2u(ltl_string.size() + 2);
|
||||
|
||||
// i will iterate over all utf8 characters between b and e
|
||||
std::string::const_iterator b = ltl_string.begin();
|
||||
std::string::const_iterator i = b;
|
||||
std::string::const_iterator e = ltl_string.end();
|
||||
|
||||
unsigned n = 0; // number of current utf8 character
|
||||
unsigned prev = 0; // last byte of previous utf8 character
|
||||
while (i != e)
|
||||
{
|
||||
utf8::next(i, e);
|
||||
++n;
|
||||
unsigned d = std::distance(b, i);
|
||||
while (prev < d)
|
||||
b2u[++prev] = n;
|
||||
}
|
||||
b2u[++prev] = ++n;
|
||||
|
||||
// use b2u to update error_list
|
||||
parse_error_list::iterator it;
|
||||
for (it = error_list.begin(); it != error_list.end(); ++it)
|
||||
{
|
||||
location& l = it->first;
|
||||
l.begin.column = b2u[l.begin.column];
|
||||
l.end.column = b2u[l.end.column];
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
bool
|
||||
format_parse_errors_aux(std::ostream& os,
|
||||
const std::string& ltl_string,
|
||||
const parse_error_list& error_list)
|
||||
{
|
||||
bool printed = false;
|
||||
parse_error_list::const_iterator it;
|
||||
for (it = error_list.begin(); it != error_list.end(); ++it)
|
||||
{
|
||||
os << ">>> " << ltl_string << std::endl;
|
||||
const location& l = it->first;
|
||||
|
||||
unsigned n = 1;
|
||||
for (; n < 4 + l.begin.column; ++n)
|
||||
os << ' ';
|
||||
// Write at least one '^', even if begin==end.
|
||||
os << '^';
|
||||
++n;
|
||||
for (; n < 4 + l.end.column; ++n)
|
||||
os << '^';
|
||||
os << std::endl << it->second << std::endl << std::endl;
|
||||
printed = true;
|
||||
}
|
||||
return printed;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
format_parse_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()))
|
||||
{
|
||||
parse_error_list fixed = error_list;
|
||||
fix_utf8_locations(ltl_string, fixed);
|
||||
return format_parse_errors_aux(os, ltl_string, fixed);
|
||||
}
|
||||
else
|
||||
{
|
||||
return format_parse_errors_aux(os, ltl_string, error_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
35
spot/parsetl/parsedecl.hh
Normal file
35
spot/parsetl/parsedecl.hh
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2010, 2012, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE)
|
||||
// Copyright (C) 2003, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||
// et Marie Curie.
|
||||
//
|
||||
// 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/parsetl/parsetl.hh>
|
||||
#include <spot/misc/location.hh>
|
||||
|
||||
# define YY_DECL \
|
||||
int tlyylex (tlyy::parser::semantic_type *yylval, \
|
||||
spot::location *yylloc, \
|
||||
spot::parse_error_list& error_list)
|
||||
YY_DECL;
|
||||
|
||||
void flex_set_buffer(const std::string& buf, int start_tok, bool lenient);
|
||||
void flex_unset_buffer();
|
||||
1086
spot/parsetl/parsetl.yy
Normal file
1086
spot/parsetl/parsetl.yy
Normal file
File diff suppressed because it is too large
Load diff
396
spot/parsetl/scantl.ll
Normal file
396
spot/parsetl/scantl.ll
Normal file
|
|
@ -0,0 +1,396 @@
|
|||
/* -*- coding: utf-8 -*-
|
||||
** Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, Laboratoire de
|
||||
** Recherche et Développement de l'Epita (LRDE).
|
||||
** Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||
** département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||
** et Marie Curie.
|
||||
**
|
||||
** 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 warn 8bit batch
|
||||
%option prefix="tlyy"
|
||||
%option outfile="lex.yy.c"
|
||||
%option stack
|
||||
%option never-interactive
|
||||
|
||||
%{
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
#include <spot/parsetl/parsedecl.hh>
|
||||
#include "spot/priv/trim.hh"
|
||||
|
||||
#define YY_USER_ACTION \
|
||||
yylloc->columns(yyleng);
|
||||
|
||||
static int start_token = 0;
|
||||
static int parent_level = 0;
|
||||
static bool missing_parent = false;
|
||||
static bool lenient_mode = false;
|
||||
static int orig_cond = 0;
|
||||
static unsigned comment_level = 0;
|
||||
|
||||
typedef tlyy::parser::token token;
|
||||
|
||||
%}
|
||||
|
||||
%s not_prop
|
||||
%x in_par
|
||||
%x in_bra
|
||||
%x sqbracket
|
||||
%x lbt
|
||||
%x in_COMMENT in_STRING
|
||||
|
||||
BOX "[]"|"□"|"⬜"|"◻"
|
||||
DIAMOND "<>"|"◇"|"⋄"|"♢"
|
||||
ARROWL "->"|"-->"|"→"|"⟶"
|
||||
DARROWL "=>"|"⇒"|"⟹"
|
||||
ARROWLR "<->"|"<-->"|"↔"
|
||||
DARROWLR "<=>"|"⇔"
|
||||
CIRCLE "()"|"○"|"◯"
|
||||
NOT "!"|"~"|"¬"
|
||||
BOXARROW {BOX}{ARROWL}|"|"{ARROWL}|"↦"
|
||||
BOXDARROW {BOX}{DARROWL}|"|"{DARROWL}|"⤇"
|
||||
eol \n+|\r+
|
||||
eol2 (\n\r)+|(\r\n)+
|
||||
|
||||
%%
|
||||
|
||||
%{
|
||||
if (start_token)
|
||||
{
|
||||
int t = start_token;
|
||||
start_token = 0;
|
||||
return t;
|
||||
}
|
||||
yylloc->step();
|
||||
std::string s;
|
||||
%}
|
||||
|
||||
<*>"/""*"+ {
|
||||
if (YY_START != in_COMMENT)
|
||||
{
|
||||
orig_cond = YY_START;
|
||||
BEGIN(in_COMMENT);
|
||||
comment_level = 0;
|
||||
}
|
||||
++comment_level;
|
||||
}
|
||||
<in_COMMENT>{
|
||||
[^*/\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) BEGIN(orig_cond);
|
||||
<<EOF>> {
|
||||
BEGIN(orig_cond);
|
||||
error_list.push_back(
|
||||
spot::one_parse_error(*yylloc,
|
||||
"unclosed comment"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
"(" {
|
||||
if (!lenient_mode)
|
||||
{
|
||||
BEGIN(0);
|
||||
return token::PAR_OPEN;
|
||||
}
|
||||
/* Parse any (...) block as a single block,
|
||||
taking care of nested parentheses. The
|
||||
parser will then try to parse this block
|
||||
recursively. */
|
||||
BEGIN(in_par);
|
||||
parent_level = 1;
|
||||
yylval->str = new std::string();
|
||||
}
|
||||
<in_par>{
|
||||
"(" {
|
||||
++parent_level;
|
||||
yylval->str->append(yytext, yyleng);
|
||||
}
|
||||
")" {
|
||||
if (--parent_level)
|
||||
{
|
||||
yylval->str->append(yytext, yyleng);
|
||||
}
|
||||
else
|
||||
{
|
||||
BEGIN(not_prop);
|
||||
spot::trim(*yylval->str);
|
||||
return token::PAR_BLOCK;
|
||||
}
|
||||
}
|
||||
[^()]+ yylval->str->append(yytext, yyleng);
|
||||
<<EOF>> {
|
||||
unput(')');
|
||||
if (!missing_parent)
|
||||
error_list.push_back(
|
||||
spot::one_parse_error(*yylloc,
|
||||
"missing closing parenthese"));
|
||||
missing_parent = true;
|
||||
}
|
||||
}
|
||||
|
||||
"{" {
|
||||
if (!lenient_mode)
|
||||
{
|
||||
BEGIN(0);
|
||||
return token::BRACE_OPEN;
|
||||
}
|
||||
/* Parse any {...} block as a single block,
|
||||
taking care of nested parentheses. The
|
||||
parser will then try to parse this block
|
||||
recursively. */
|
||||
BEGIN(in_bra);
|
||||
parent_level = 1;
|
||||
yylval->str = new std::string();
|
||||
}
|
||||
<in_bra>{
|
||||
"{" {
|
||||
++parent_level;
|
||||
yylval->str->append(yytext, yyleng);
|
||||
}
|
||||
"}"[ \t\n]*"!" {
|
||||
if (--parent_level)
|
||||
{
|
||||
yylval->str->append(yytext, yyleng);
|
||||
}
|
||||
else
|
||||
{
|
||||
BEGIN(not_prop);
|
||||
spot::trim(*yylval->str);
|
||||
return token::BRA_BANG_BLOCK;
|
||||
}
|
||||
}
|
||||
"}" {
|
||||
if (--parent_level)
|
||||
{
|
||||
yylval->str->append(yytext, yyleng);
|
||||
}
|
||||
else
|
||||
{
|
||||
BEGIN(not_prop);
|
||||
spot::trim(*yylval->str);
|
||||
return token::BRA_BLOCK;
|
||||
}
|
||||
}
|
||||
[^{}]+ yylval->str->append(yytext, yyleng);
|
||||
<<EOF>> {
|
||||
unput(')');
|
||||
if (!missing_parent)
|
||||
error_list.push_back(
|
||||
spot::one_parse_error(*yylloc,
|
||||
"missing closing brace"));
|
||||
missing_parent = true;
|
||||
}
|
||||
}
|
||||
|
||||
")" BEGIN(not_prop); return token::PAR_CLOSE;
|
||||
"}"[ \t\n]*"!" BEGIN(not_prop); return token::BRACE_BANG_CLOSE;
|
||||
"}" BEGIN(not_prop); return token::BRACE_CLOSE;
|
||||
|
||||
/* Must go before the other operators, because the F of FALSE
|
||||
should not be mistaken with a unary F. */
|
||||
"1"|[tT][rR][uU][eE] BEGIN(0); return token::CONST_TRUE;
|
||||
"0"|[fF][aA][lL][sS][eE] BEGIN(0); return token::CONST_FALSE;
|
||||
|
||||
|
||||
/* ~ comes from Goal, ! from everybody else */
|
||||
{NOT} BEGIN(0); return token::OP_NOT;
|
||||
|
||||
/* PSL operators */
|
||||
{BOXARROW} BEGIN(0); return token::OP_UCONCAT;
|
||||
{DIAMOND}{ARROWL} BEGIN(0); return token::OP_ECONCAT;
|
||||
{BOXDARROW} BEGIN(0); return token::OP_UCONCAT_NONO;
|
||||
{DIAMOND}{DARROWL} BEGIN(0); return token::OP_ECONCAT_NONO;
|
||||
";" BEGIN(0); return token::OP_CONCAT;
|
||||
":" BEGIN(0); return token::OP_FUSION;
|
||||
"*" BEGIN(0); return token::OP_STAR;
|
||||
"[*]" BEGIN(0); return token::OP_BSTAR;
|
||||
"[+]" BEGIN(0); return token::OP_PLUS;
|
||||
"[*" BEGIN(sqbracket); return token::OP_STAR_OPEN;
|
||||
"[:*]" BEGIN(0); return token::OP_BFSTAR;
|
||||
"[:+]" BEGIN(0); return token::OP_FPLUS;
|
||||
"[:*" BEGIN(sqbracket); return token::OP_FSTAR_OPEN;
|
||||
"[=" BEGIN(sqbracket); return token::OP_EQUAL_OPEN;
|
||||
"["{ARROWL} BEGIN(sqbracket); return token::OP_GOTO_OPEN;
|
||||
<sqbracket>"]" BEGIN(0); return token::OP_SQBKT_CLOSE;
|
||||
<sqbracket>[0-9]+ {
|
||||
errno = 0;
|
||||
unsigned long n = strtoul(yytext, 0, 10);
|
||||
yylval->num = n;
|
||||
if (errno || yylval->num != n)
|
||||
{
|
||||
error_list.push_back(
|
||||
spot::one_parse_error(*yylloc,
|
||||
"value too large ignored"));
|
||||
// Skip this number and read next token
|
||||
yylloc->step();
|
||||
}
|
||||
else
|
||||
{
|
||||
return token::OP_SQBKT_NUM;
|
||||
}
|
||||
}
|
||||
/* .. is from PSL and EDL
|
||||
: is from Verilog and PSL
|
||||
to is from VHDL
|
||||
, is from Perl */
|
||||
<sqbracket>","|".."|":"|"to" return token::OP_SQBKT_SEP;
|
||||
|
||||
/* In SVA you use [=1:$] instead of [=1..]. We will also accept
|
||||
[=1..$] and [=1:]. The PSL LRM shows examples like [=1:inf]
|
||||
instead, so will accept this too. */
|
||||
<sqbracket>"$"|"inf" return token::OP_UNBOUNDED;
|
||||
|
||||
/* & and | come from Spin. && and || from LTL2BA.
|
||||
/\, \/, and xor are from LBTT.
|
||||
--> and <--> come from Goal.
|
||||
+,*,^ are from Wring. */
|
||||
"||"|"|"|"+"|"\\/"|"∨"|"∪" BEGIN(0); return token::OP_OR;
|
||||
"&&"|"/\\"|"∧"|"∩" BEGIN(0); return token::OP_AND;
|
||||
"&" BEGIN(0); return token::OP_SHORT_AND;
|
||||
"^"|"xor"|"⊕" BEGIN(0); return token::OP_XOR;
|
||||
{ARROWL}|{DARROWL} BEGIN(0); return token::OP_IMPLIES;
|
||||
{ARROWLR}|{DARROWLR} BEGIN(0); return token::OP_EQUIV;
|
||||
|
||||
/* <>, [], and () are used in Spin. */
|
||||
"F"|{DIAMOND} BEGIN(0); return token::OP_F;
|
||||
"G"|{BOX} BEGIN(0); return token::OP_G;
|
||||
"U" BEGIN(0); return token::OP_U;
|
||||
"R"|"V" BEGIN(0); return token::OP_R;
|
||||
"X"|{CIRCLE} BEGIN(0); return token::OP_X;
|
||||
"W" BEGIN(0); return token::OP_W;
|
||||
"M" BEGIN(0); return token::OP_M;
|
||||
|
||||
/* The combining overline or macron (overbar) should normally
|
||||
occur only after a single letter, but we do not check that. */
|
||||
"=0"|"̅"|"̄" return token::OP_POST_NEG;
|
||||
"=1" return token::OP_POST_POS;
|
||||
|
||||
<*>[ \t\n]+ /* discard whitespace */ yylloc->step ();
|
||||
|
||||
/* An Atomic proposition cannot start with the letter
|
||||
used by a unary operator (F,G,X), unless this
|
||||
letter is followed by a digit in which case we assume
|
||||
it's an ATOMIC_PROP (even though F0 could be seen as Ffalse, we
|
||||
don't, because Ffalse is never used in practice).
|
||||
*/
|
||||
<INITIAL>[a-zA-EH-WYZ_.][a-zA-Z0-9_.]* |
|
||||
<INITIAL>[FGX][0-9][a-zA-Z0-9_.]* |
|
||||
/*
|
||||
However if we have just parsed an atomic proposition, then we are
|
||||
not expecting another atomic proposition, so we can be stricter
|
||||
and disallow propositions that start with M, U, R, V, and W. If
|
||||
you wonder why we do this, consider the Wring formula `p=0Uq=1'.
|
||||
When p is parsed, we enter the not_prop start condition, we
|
||||
remain into this condition when `=0' is processed, and then
|
||||
because we are in this condition we will not consider `Uq' as an
|
||||
atomic proposition but as a `U' operator followed by a `q' atomic
|
||||
proposition.
|
||||
|
||||
We also disable atomic proposition that may look like a combination
|
||||
of a binary operator followed by several unary operators.
|
||||
E.g. UFXp. This way, `p=0UFXp=1' will be parsed as `(p=0)U(F(X(p=1)))'.
|
||||
*/
|
||||
<not_prop>[a-zA-EH-LN-QSTYZ_.][a-zA-EH-WYZ0-9_.]* |
|
||||
<not_prop>[a-zA-EH-LN-QSTYZ_.][a-zA-EH-WYZ0-9_.][a-zA-Z0-9_.]* {
|
||||
yylval->str = new std::string(yytext, yyleng);
|
||||
BEGIN(not_prop);
|
||||
return token::ATOMIC_PROP;
|
||||
}
|
||||
|
||||
/* Atomic propositions can also be enclosed in double quotes.
|
||||
|
||||
orig_cond stores the parsing condition to use after the
|
||||
string has been parsed. */
|
||||
"\"" {
|
||||
orig_cond = not_prop;
|
||||
BEGIN(in_STRING);
|
||||
}
|
||||
<lbt>"\"" {
|
||||
orig_cond = lbt;
|
||||
BEGIN(in_STRING);
|
||||
}
|
||||
|
||||
<in_STRING>{
|
||||
\" {
|
||||
BEGIN(orig_cond);
|
||||
yylval->str = new std::string(s);
|
||||
return token::ATOMIC_PROP;
|
||||
}
|
||||
{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::one_parse_error(*yylloc,
|
||||
"unclosed string"));
|
||||
BEGIN(orig_cond);
|
||||
yylval->str = new std::string(s);
|
||||
return token::ATOMIC_PROP;
|
||||
}
|
||||
}
|
||||
|
||||
/* these are operators */
|
||||
<lbt>[eitfXFGUVRWM] return *yytext;
|
||||
/* in LBT's format, atomic proposition look like p0 or p3141592, but
|
||||
for compatibility with ltl2dstar we also accept any alphanumeric
|
||||
string that is not an operator. */
|
||||
<lbt>[a-zA-Z._][a-zA-Z0-9._]* {
|
||||
yylval->str = new std::string(yytext, yyleng);
|
||||
return token::ATOMIC_PROP;
|
||||
}
|
||||
|
||||
|
||||
<*>. return *yytext;
|
||||
|
||||
<<EOF>> return token::END_OF_INPUT;
|
||||
|
||||
%%
|
||||
|
||||
void
|
||||
flex_set_buffer(const std::string& buf,
|
||||
int start_tok, bool lenient)
|
||||
{
|
||||
yypush_buffer_state(YY_CURRENT_BUFFER);
|
||||
(void) yy_scan_bytes(buf.c_str(), buf.size());
|
||||
start_token = start_tok;
|
||||
if (start_tok == token::START_LBT)
|
||||
yy_push_state(lbt);
|
||||
else
|
||||
yy_push_state(0);
|
||||
lenient_mode = lenient;
|
||||
}
|
||||
|
||||
void
|
||||
flex_unset_buffer()
|
||||
{
|
||||
(void)&yy_top_state; // shut up a g++ warning.
|
||||
yy_pop_state();
|
||||
yypop_buffer_state();
|
||||
missing_parent = false;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue