tl: add support for X[n], F[n:m] and G[n:m]
* NEWS, doc/tl/tl.tex, doc/tl/tl.bib: Document these new operators. * spot/parsetl/parsetl.yy, spot/parsetl/scantl.ll: Parse those. * spot/tl/formula.cc, spot/tl/formula.hh: Add constructors. * spot/gen/formulas.cc: Use it. * tests/core/sugar.test: New file. * tests/Makefile.am: Add it.
This commit is contained in:
parent
2616ea7c80
commit
e7aa334a71
10 changed files with 364 additions and 12 deletions
|
|
@ -206,6 +206,7 @@ using namespace spot;
|
|||
%token OP_W "weak until operator" OP_M "strong release operator"
|
||||
%token OP_F "sometimes operator" OP_G "always operator"
|
||||
%token OP_X "next operator" OP_NOT "not operator"
|
||||
%token OP_XREP "X[.] operator" OP_FREP "F[.] operator" OP_GREP "G[.] operator"
|
||||
%token OP_STAR "star operator" OP_BSTAR "bracket star operator"
|
||||
%token OP_BFSTAR "bracket fusion-star operator"
|
||||
%token OP_PLUS "plus operator"
|
||||
|
|
@ -250,8 +251,8 @@ using namespace spot;
|
|||
|
||||
/* LTL operators. */
|
||||
%right OP_U OP_R OP_M OP_W
|
||||
%nonassoc OP_F OP_G
|
||||
%nonassoc OP_X
|
||||
%nonassoc OP_F OP_G OP_FREP OP_GREP
|
||||
%nonassoc OP_X OP_XREP
|
||||
|
||||
/* High priority regex operator. */
|
||||
%nonassoc OP_BSTAR OP_STAR_OPEN OP_PLUS
|
||||
|
|
@ -822,14 +823,60 @@ subformula: booleanatom
|
|||
{ $$ = fnode::unop(op::F, $2); }
|
||||
| OP_F error
|
||||
{ missing_right_op($$, @1, "sometimes operator"); }
|
||||
| OP_FREP OP_SQBKT_NUM OP_SQBKT_CLOSE subformula %prec OP_FREP
|
||||
{ $$ = fnode::nested_unop_range(op::X, op::Or, $2, $2, $4);
|
||||
error_list.emplace_back(@1 + @3,
|
||||
"F[n:m] expects two parameters");
|
||||
}
|
||||
| OP_FREP OP_SQBKT_NUM OP_SQBKT_SEP OP_SQBKT_NUM OP_SQBKT_CLOSE
|
||||
subformula %prec OP_FREP
|
||||
{ $$ = fnode::nested_unop_range(op::X, op::Or, $2, $4, $6); }
|
||||
| OP_FREP OP_SQBKT_NUM OP_SQBKT_SEP OP_SQBKT_NUM OP_SQBKT_CLOSE
|
||||
error
|
||||
{ missing_right_op($$, @1 + @5, "F[.] operator"); }
|
||||
| OP_FREP error_opt END_OF_INPUT
|
||||
{ error_list.emplace_back(@$, "missing closing bracket for F[.]");
|
||||
$$ = fnode::ff(); }
|
||||
| OP_FREP error OP_SQBKT_CLOSE subformula %prec OP_FREP
|
||||
{ error_list.emplace_back(@1 + @3,
|
||||
"treating this F[.] as a simple F");
|
||||
$$ = fnode::unop(op::F, $4); }
|
||||
| OP_G subformula
|
||||
{ $$ = fnode::unop(op::G, $2); }
|
||||
| OP_G error
|
||||
{ missing_right_op($$, @1, "always operator"); }
|
||||
| OP_GREP OP_SQBKT_NUM OP_SQBKT_SEP OP_SQBKT_NUM OP_SQBKT_CLOSE
|
||||
subformula %prec OP_GREP
|
||||
{ $$ = fnode::nested_unop_range(op::X, op::And, $2, $4, $6); }
|
||||
| OP_GREP OP_SQBKT_NUM OP_SQBKT_CLOSE subformula %prec OP_GREP
|
||||
{ $$ = fnode::nested_unop_range(op::X, op::And, $2, $2, $4);
|
||||
error_list.emplace_back(@1 + @3,
|
||||
"G[n:m] expects two parameters");
|
||||
}
|
||||
| OP_GREP OP_SQBKT_NUM OP_SQBKT_SEP OP_SQBKT_NUM OP_SQBKT_CLOSE
|
||||
error
|
||||
{ missing_right_op($$, @1 + @5, "G[.] operator"); }
|
||||
| OP_GREP error_opt END_OF_INPUT
|
||||
{ error_list.emplace_back(@$, "missing closing bracket for G[.]");
|
||||
$$ = fnode::ff(); }
|
||||
| OP_GREP error OP_SQBKT_CLOSE subformula %prec OP_GREP
|
||||
{ error_list.emplace_back(@1 + @3,
|
||||
"treating this G[.] as a simple G");
|
||||
$$ = fnode::unop(op::F, $4); }
|
||||
| OP_X subformula
|
||||
{ $$ = fnode::unop(op::X, $2); }
|
||||
| OP_X error
|
||||
{ missing_right_op($$, @1, "next operator"); }
|
||||
| OP_XREP OP_SQBKT_NUM OP_SQBKT_CLOSE subformula %prec OP_XREP
|
||||
{ $$ = fnode::nested_unop_range(op::X, op::Or, $2, $2, $4); }
|
||||
| OP_XREP OP_SQBKT_NUM OP_SQBKT_CLOSE error
|
||||
{ missing_right_op($$, @1 + @3, "X[.] operator"); }
|
||||
| OP_XREP error OP_SQBKT_CLOSE subformula %prec OP_XREP
|
||||
{ error_list.emplace_back(@$, "treating this X[.] as a simple X");
|
||||
$$ = fnode::unop(op::X, $4); }
|
||||
| OP_XREP error_opt END_OF_INPUT
|
||||
{ error_list.emplace_back(@$, "missing closing bracket for X[.]");
|
||||
$$ = fnode::ff(); }
|
||||
| OP_NOT subformula
|
||||
{ $$ = fnode::unop(op::Not, $2); }
|
||||
| OP_NOT error
|
||||
|
|
|
|||
|
|
@ -273,7 +273,21 @@ eol2 (\n\r)+|(\r\n)+
|
|||
{ARROWL}|{DARROWL} BEGIN(0); return token::OP_IMPLIES;
|
||||
{ARROWLR}|{DARROWLR} BEGIN(0); return token::OP_EQUIV;
|
||||
|
||||
/* <>, [], and () are used in Spin. */
|
||||
/* TSLF-like syntactic sugar:
|
||||
X[3]f = XXXf
|
||||
F[2..4]f = XX(f | X(f | Xf))
|
||||
G[2..4]f = XX(f & X(f & Xf))
|
||||
We also have to deal with the Spin-like notation for G.
|
||||
X[]f = XGf
|
||||
*/
|
||||
"X"[ \t\n]*"[]" yyless(1); return token::OP_X;
|
||||
"F"[ \t\n]*"[]" yyless(1); return token::OP_F;
|
||||
"G"[ \t\n]*"[]" yyless(1); return token::OP_G;
|
||||
"X"[ \t\n]*"[" BEGIN(sqbracket); return token::OP_XREP;
|
||||
"F"[ \t\n]*"[" BEGIN(sqbracket); return token::OP_FREP;
|
||||
"G"[ \t\n]*"[" BEGIN(sqbracket); return token::OP_GREP;
|
||||
/* <> (DIAMOND) and [] (BOX), are used in Spin.
|
||||
() (CIRCLE) is not, but would make sense. */
|
||||
"F"|{DIAMOND} BEGIN(0); return token::OP_F;
|
||||
"G"|{BOX} BEGIN(0); return token::OP_G;
|
||||
"U" BEGIN(0); return token::OP_U;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue