Add support for [+].

* src/ltlast/bunop.cc (bunop::format): Output [*1..] as [+].
* src/ltlvisit/tostring.cc: Output "a*" as "a[*]" for consistency.
* src/ltlparse/ltlparse.yy, src/ltlparse/ltlscan.ll: Recognize [+].
* src/ltltest/tostring.test, src/ltltest/equals.test,
src/tgbatest/ltl2tgba.test: More tests.
This commit is contained in:
Alexandre Duret-Lutz 2010-05-19 17:01:11 +02:00
parent 126b724a98
commit 567b460738
7 changed files with 28 additions and 12 deletions

View file

@ -119,6 +119,14 @@ namespace spot
bunop::format() const bunop::format() const
{ {
std::ostringstream out; std::ostringstream out;
// Syntactic sugaring
if (min_ == 1 && max_ == unbounded)
{
out << "[+]";
return out.str();
}
out << "[*"; out << "[*";
if (min_ != 0 || max_ != unbounded) if (min_ != 0 || max_ != unbounded)
{ {

View file

@ -90,6 +90,7 @@ using namespace spot::ltl;
%token OP_W "weak until operator" OP_M "strong release operator" %token OP_W "weak until operator" OP_M "strong release operator"
%token OP_F "sometimes operator" OP_G "always operator" %token OP_F "sometimes operator" OP_G "always operator"
%token OP_X "next operator" OP_NOT "not operator" OP_STAR "star operator" %token OP_X "next operator" OP_NOT "not operator" OP_STAR "star operator"
%token OP_PLUS "plus operator"
%token OP_STAR_OPEN "opening bracket for star operator" %token OP_STAR_OPEN "opening bracket for star operator"
%token OP_STAR_CLOSE "closing bracket for star operator" %token OP_STAR_CLOSE "closing bracket for star operator"
%token <num> OP_STAR_NUM "number for star operator" %token <num> OP_STAR_NUM "number for star operator"
@ -123,7 +124,7 @@ using namespace spot::ltl;
%nonassoc OP_X %nonassoc OP_X
/* High priority regex operator. */ /* High priority regex operator. */
%nonassoc OP_STAR OP_STAR_OPEN %nonassoc OP_STAR OP_STAR_OPEN OP_PLUS
/* Not has the most important priority after Wring's `=0' and `=1'. */ /* Not has the most important priority after Wring's `=0' and `=1'. */
%nonassoc OP_NOT %nonassoc OP_NOT
@ -191,6 +192,8 @@ error_opt: | error
starargs: OP_STAR starargs: OP_STAR
{ $$.min = 0U; $$.max = bunop::unbounded; } { $$.min = 0U; $$.max = bunop::unbounded; }
| OP_PLUS
{ $$.min = 1U; $$.max = bunop::unbounded; }
| OP_STAR_OPEN OP_STAR_NUM OP_STAR_SEP OP_STAR_NUM OP_STAR_CLOSE | OP_STAR_OPEN OP_STAR_NUM OP_STAR_SEP OP_STAR_NUM OP_STAR_CLOSE
{ $$.min = $2; $$.max = $4; } { $$.min = $2; $$.max = $4; }
| OP_STAR_OPEN OP_STAR_NUM OP_STAR_SEP OP_STAR_CLOSE | OP_STAR_OPEN OP_STAR_NUM OP_STAR_SEP OP_STAR_CLOSE
@ -200,7 +203,7 @@ starargs: OP_STAR
| OP_STAR_OPEN OP_STAR_SEP_opt OP_STAR_CLOSE | OP_STAR_OPEN OP_STAR_SEP_opt OP_STAR_CLOSE
{ $$.min = 0U; $$.max = bunop::unbounded; } { $$.min = 0U; $$.max = bunop::unbounded; }
| OP_STAR_OPEN OP_STAR_NUM OP_STAR_CLOSE | OP_STAR_OPEN OP_STAR_NUM OP_STAR_CLOSE
{ $$.min = $2; $$.max = $2; } { $$.min = $$.max = $2; }
| OP_STAR_OPEN error OP_STAR_CLOSE | OP_STAR_OPEN error OP_STAR_CLOSE
{ error_list.push_back(parse_error(@$, { error_list.push_back(parse_error(@$,
"treating this star block as [*]")); "treating this star block as [*]"));

View file

@ -95,6 +95,7 @@ flex_set_buffer(const char* buf, int start_tok)
";" BEGIN(0); return token::OP_CONCAT; ";" BEGIN(0); return token::OP_CONCAT;
":" BEGIN(0); return token::OP_FUSION; ":" BEGIN(0); return token::OP_FUSION;
"*"|"[*]" BEGIN(0); return token::OP_STAR; "*"|"[*]" BEGIN(0); return token::OP_STAR;
"[+]" BEGIN(0); return token::OP_PLUS;
"[*" BEGIN(star); return token::OP_STAR_OPEN; "[*" BEGIN(star); return token::OP_STAR_OPEN;
<star>"]" BEGIN(0); return token::OP_STAR_CLOSE; <star>"]" BEGIN(0); return token::OP_STAR_CLOSE;
<star>[0-9]+ { <star>[0-9]+ {

View file

@ -134,3 +134,8 @@ run 0 ../equals '{a[*..3][*2]}' '{a[*..6]}'
run 0 ../equals '{a[*..3][*..2]}' '{a[*..6]}' run 0 ../equals '{a[*..3][*..2]}' '{a[*..6]}'
run 0 ../equals '{a[*..3][*2..]}' '{a[*]}' run 0 ../equals '{a[*..3][*2..]}' '{a[*]}'
run 0 ../equals '{a[*..3][*2..]}' '{a[*]}' run 0 ../equals '{a[*..3][*2..]}' '{a[*]}'
run 0 ../equals '{a[*1..]}' '{a[+]}'
run 0 ../equals '{a[+][*1..3]}' '{a[+]}'
run 0 ../equals '{a[*1..3][+]}' '{a[+]}'
run 0 ../equals '{[*2][+]}' '{[*2][+]}'
run 0 ../equals '{[+][*2]}' '{[*2..]}'

View file

@ -66,4 +66,6 @@ run 0 ../tostring '{a[*0..1]}'
run 0 ../tostring '{a[*0..]}' run 0 ../tostring '{a[*0..]}'
run 0 ../tostring '{a[*..]}' run 0 ../tostring '{a[*..]}'
run 0 ../tostring '{a[*1..]}' run 0 ../tostring '{a[*1..]}'
run 0 ../tostring '{a[+]}'
run 0 ../tostring '{[+]}'
run 0 ../tostring '{a[*2..3][*4..5]}' run 0 ../tostring '{a[*2..3][*4..5]}'

View file

@ -1,4 +1,4 @@
// Copyright (C) 2008, 2010, 2011 Laboratoire de Recherche et Développement // Copyright (C) 2008, 2010, 2011 Laboratoire de Recherche et Développement
// de l'Epita (LRDE). // de l'Epita (LRDE).
// Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6), // Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre // département Systèmes Répartis Coopératifs (SRC), Université Pierre
@ -182,12 +182,12 @@ namespace spot
void void
visit(const bunop* bo) visit(const bunop* bo)
{ {
// Abbreviate "1*" as "*". // Abbreviate "1[*]" as "[*]".
if (bo->child() != constant::true_instance()) if (bo->child() != constant::true_instance())
{ {
// a* is OK, no need to print {a}*. // a[*] is OK, no need to print {a}[*].
// However want braces for {!a}*, the only unary // However want braces for {!a}[*], the only unary
// operator that can be nested with *. // operator that can be nested with [*].
bool need_parent = !!dynamic_cast<const unop*>(bo->child()); bool need_parent = !!dynamic_cast<const unop*>(bo->child());
if (need_parent || full_parent_) if (need_parent || full_parent_)
@ -197,10 +197,6 @@ namespace spot
closep(); closep();
} }
// Output "*" instead of "[*]".
if (bo->min() == 0 && bo->max() == bunop::unbounded)
os_ << "*";
else
os_ << bo->format(); os_ << bo->format();
} }

View file

@ -83,6 +83,7 @@ check_psl '{((!c;b*) & d);e}'
check_psl '{(a* & (c;b*) & d);e}' check_psl '{(a* & (c;b*) & d);e}'
check_psl '{[*2];a[*2..4]}|->b' check_psl '{[*2];a[*2..4]}|->b'
check_psl '{a[*2..5] && b[*..3]}|->c' check_psl '{a[*2..5] && b[*..3]}|->c'
check_psl '{{[+];a;[+]} && {[+];b;[+]}}<>->c'
# Example from "Beyond Hardware Verification" by Glazberg, Moulin, Orni, # Example from "Beyond Hardware Verification" by Glazberg, Moulin, Orni,
# Ruah, Zarpas (2007). # Ruah, Zarpas (2007).
check_psl '{[*];req;ack}|=>{start;busy[*];done}' check_psl '{[*];req;ack}|=>{start;busy[*];done}'