* src/ltlvisit/tostring.cc (is_bare_word): New function.

(to_string_visitor::visitor(const atomic_prop*)): Use is_bare_word
to better check which atomic proposition need to be quoted.
* src/ltlparse/ltlscan.ll: Do not allow identifiers starting with F_
or G_.
* src/ltltest/equals.test, src/ltltest/tostring.test: More tests.
This commit is contained in:
Alexandre Duret-Lutz 2004-06-23 11:36:03 +00:00
parent 3802528bfd
commit e9fd27e892
5 changed files with 39 additions and 6 deletions

View file

@ -1,4 +1,11 @@
2004-06-23 Alexandre Duret-Lutz <adl@gnu.org> 2004-06-23 Alexandre Duret-Lutz <adl@src.lip6.fr>
* src/ltlvisit/tostring.cc (is_bare_word): New function.
(to_string_visitor::visitor(const atomic_prop*)): Use is_bare_word
to better check which atomic proposition need to be quoted.
* src/ltlparse/ltlscan.ll: Do not allow identifiers starting with F_
or G_.
* src/ltltest/equals.test, src/ltltest/tostring.test: More tests.
* src/tgba/tgbatba.cc (tgba_tba_proxy::format_state): Use * src/tgba/tgbatba.cc (tgba_tba_proxy::format_state): Use
bdd_format_accset to print the acceptance condition part of the state. bdd_format_accset to print the acceptance condition part of the state.

View file

@ -96,10 +96,10 @@ flex_set_buffer(const char* buf)
used by a unary operator (F,G,X), unless this used by a unary operator (F,G,X), unless this
letter is followed by a digit in which case we assume 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 it's an ATOMIC_PROP (even though F0 could be seen as Ffalse, we
don't). don't, because Ffalse is never used in practice).
*/ */
<INITIAL>[a-zA-EH-WYZ_][a-zA-Z0-9_]* | <INITIAL>[a-zA-EH-WYZ_][a-zA-Z0-9_]* |
<INITIAL>[FGX][0-9_][a-zA-Z0-9_]* | <INITIAL>[FGX][0-9][a-zA-Z0-9_]* |
/* /*
However if we have just parsed an atomic proposition, then we However if we have just parsed an atomic proposition, then we
are not expecting another atomic proposition, so we can be stricter are not expecting another atomic proposition, so we can be stricter

View file

@ -57,3 +57,6 @@ run 1 ./equals 'a & b & (c |(f U g)| e)' \
# Precedence # Precedence
run 0 ./equals 'a & b ^ c | d' 'd | c ^ b & a' run 0 ./equals 'a & b ^ c | d' 'd | c ^ b & a'
# Corner cases parsing
run 0 ./equals 'FFG__GFF' 'F(F(G("__GFF")))'

View file

@ -51,3 +51,6 @@ run 0 ./tostring 'G"TruE"'
run 0 ./tostring 'FFALSE' run 0 ./tostring 'FFALSE'
run 0 ./tostring 'GTruE' run 0 ./tostring 'GTruE'
run 0 ./tostring 'p=0UFXp=1' run 0 ./tostring 'p=0UFXp=1'
run 0 ./tostring 'GF"\GF"'
run 0 ./tostring 'GF"foo bar"'
run 0 ./tostring 'FFG__GFF'

View file

@ -21,6 +21,7 @@
#include <cassert> #include <cassert>
#include <sstream> #include <sstream>
#include <ctype.h>
#include "tostring.hh" #include "tostring.hh"
#include "ltlast/visitor.hh" #include "ltlast/visitor.hh"
#include "ltlast/allnodes.hh" #include "ltlast/allnodes.hh"
@ -31,6 +32,27 @@ namespace spot
namespace ltl namespace ltl
{ {
static bool
is_bare_word(const char* str)
{
// Bare words cannot be empty, start with the letter of a unary
// operator, or be the name of an existing constant. Also they
// should start with an letter.
if (!*str
|| *str == 'F'
|| *str == 'G'
|| *str == 'X'
|| !(isalpha(*str) || *str == '_')
|| !strcasecmp(str, "true")
|| !strcasecmp(str, "false"))
return false;
// The remaining of the word must be alphanumeric.
while (*++str)
if (!(isalnum(*str) || *str == '_'))
return false;
return true;
}
class to_string_visitor : public const_visitor class to_string_visitor : public const_visitor
{ {
public: public:
@ -48,9 +70,7 @@ namespace spot
visit(const atomic_prop* ap) visit(const atomic_prop* ap)
{ {
std::string str = ap->name(); std::string str = ap->name();
if (str[0] == 'F' || str[0] == 'G' || str[0] == 'X' if (!is_bare_word(str.c_str()))
|| !strcasecmp(str.c_str(), "true")
|| !strcasecmp(str.c_str(), "false"))
{ {
os_ << '"' << str << '"'; os_ << '"' << str << '"';
} }