parsetl: factor some code
* spot/parsetl/parsetl.yy (parse_ap, sere_ensure_bool, error_false_block): New functions, replacing several similar blocks.
This commit is contained in:
parent
93b9932f90
commit
2df677d2d2
1 changed files with 88 additions and 155 deletions
|
|
@ -1,9 +1,10 @@
|
||||||
/* -*- coding: utf-8 -*-
|
/* -*- coding: utf-8 -*-
|
||||||
** Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Laboratoire
|
|
||||||
** de Recherche et Développement de l'Epita (LRDE).
|
** Copyright (C) 2009-2017 Laboratoire de Recherche et Développement
|
||||||
** Copyright (C) 2003, 2004, 2005, 2006 Laboratoire d'Informatique de
|
** de l'Epita (LRDE).
|
||||||
** Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
** Copyright (C) 2003-2006 Laboratoire d'Informatique de Paris 6
|
||||||
** Université Pierre et Marie Curie.
|
** (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.
|
** This file is part of Spot, a model checking library.
|
||||||
**
|
**
|
||||||
|
|
@ -89,9 +90,52 @@ using namespace spot;
|
||||||
} \
|
} \
|
||||||
while (0);
|
while (0);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
sere_ensure_bool(const fnode* f, const spot::location& loc,
|
||||||
|
const char* oper, spot::parse_error_list& error_list)
|
||||||
|
{
|
||||||
|
if (f->is_boolean())
|
||||||
|
return true;
|
||||||
|
std::string s;
|
||||||
|
s.reserve(80);
|
||||||
|
s = "not a Boolean expression: in a SERE ";
|
||||||
|
s += oper;
|
||||||
|
s += " can only be applied to a Boolean expression";
|
||||||
|
error_list.emplace_back(loc, s);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const fnode*
|
||||||
|
error_false_block(const spot::location& loc,
|
||||||
|
spot::parse_error_list& error_list)
|
||||||
|
{
|
||||||
|
error_list.emplace_back(loc, "treating this block as false");
|
||||||
|
return fnode::ff();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const fnode*
|
||||||
|
parse_ap(const std::string& str,
|
||||||
|
const spot::location& location,
|
||||||
|
spot::environment& env,
|
||||||
|
spot::parse_error_list& error_list)
|
||||||
|
{
|
||||||
|
auto res = env.require(str);
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
std::string s;
|
||||||
|
s.reserve(64);
|
||||||
|
s = "unknown atomic proposition `";
|
||||||
|
s += str;
|
||||||
|
s += "' in ";
|
||||||
|
s += env.name();
|
||||||
|
error_list.emplace_back(location, s);
|
||||||
|
}
|
||||||
|
return res.to_node_();
|
||||||
|
}
|
||||||
|
|
||||||
enum parser_type { parser_ltl, parser_bool, parser_sere };
|
enum parser_type { parser_ltl, parser_bool, parser_sere };
|
||||||
|
|
||||||
static formula
|
static const fnode*
|
||||||
try_recursive_parse(const std::string& str,
|
try_recursive_parse(const std::string& str,
|
||||||
const spot::location& location,
|
const spot::location& location,
|
||||||
spot::environment& env,
|
spot::environment& env,
|
||||||
|
|
@ -135,20 +179,10 @@ using namespace spot;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pf.errors.empty())
|
if (pf.errors.empty())
|
||||||
return pf.f;
|
return pf.f.to_node_();
|
||||||
|
return parse_ap(str, location, env, error_list);
|
||||||
auto f = env.require(str);
|
|
||||||
if (!f)
|
|
||||||
{
|
|
||||||
std::string s = "atomic proposition `";
|
|
||||||
s += str;
|
|
||||||
s += "' rejected by environment `";
|
|
||||||
s += env.name();
|
|
||||||
s += "'";
|
|
||||||
error_list.emplace_back(location, s);
|
|
||||||
}
|
|
||||||
return f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -228,7 +262,7 @@ using namespace spot;
|
||||||
need any precedence). */
|
need any precedence). */
|
||||||
%nonassoc OP_NOT
|
%nonassoc OP_NOT
|
||||||
|
|
||||||
%type <ltl> subformula booleanatom sere lbtformula boolformula
|
%type <ltl> subformula atomprop booleanatom sere lbtformula boolformula
|
||||||
%type <ltl> bracedsere parenthesedsubformula
|
%type <ltl> bracedsere parenthesedsubformula
|
||||||
%type <minmax> starargs fstarargs equalargs sqbracketargs gotoargs
|
%type <minmax> starargs fstarargs equalargs sqbracketargs gotoargs
|
||||||
|
|
||||||
|
|
@ -401,57 +435,19 @@ equalargs: OP_EQUAL_OPEN sqbracketargs
|
||||||
$$.min = $$.max = 0U; }
|
$$.min = $$.max = 0U; }
|
||||||
|
|
||||||
|
|
||||||
booleanatom: ATOMIC_PROP
|
atomprop: ATOMIC_PROP
|
||||||
|
{
|
||||||
|
$$ = parse_ap(*$1, @1, parse_environment, error_list);
|
||||||
|
delete $1;
|
||||||
|
if (!$$)
|
||||||
|
YYERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
booleanatom: atomprop
|
||||||
|
| atomprop OP_POST_POS
|
||||||
|
| atomprop OP_POST_NEG
|
||||||
{
|
{
|
||||||
$$ = parse_environment.require(*$1).to_node_();
|
$$ = fnode::unop(op::Not, $1);
|
||||||
if (! $$)
|
|
||||||
{
|
|
||||||
std::string s = "unknown atomic proposition `";
|
|
||||||
s += *$1;
|
|
||||||
s += "' in environment `";
|
|
||||||
s += parse_environment.name();
|
|
||||||
s += "'";
|
|
||||||
error_list.emplace_back(@1, s);
|
|
||||||
delete $1;
|
|
||||||
YYERROR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
delete $1;
|
|
||||||
}
|
|
||||||
| ATOMIC_PROP OP_POST_POS
|
|
||||||
{
|
|
||||||
$$ = parse_environment.require(*$1).to_node_();
|
|
||||||
if (! $$)
|
|
||||||
{
|
|
||||||
std::string s = "unknown atomic proposition `";
|
|
||||||
s += *$1;
|
|
||||||
s += "' in environment `";
|
|
||||||
s += parse_environment.name();
|
|
||||||
s += "'";
|
|
||||||
error_list.emplace_back(@1, s);
|
|
||||||
delete $1;
|
|
||||||
YYERROR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
delete $1;
|
|
||||||
}
|
|
||||||
| ATOMIC_PROP OP_POST_NEG
|
|
||||||
{
|
|
||||||
$$ = parse_environment.require(*$1).to_node_();
|
|
||||||
if (! $$)
|
|
||||||
{
|
|
||||||
std::string s = "unknown atomic proposition `";
|
|
||||||
s += *$1;
|
|
||||||
s += "' in environment `";
|
|
||||||
s += parse_environment.name();
|
|
||||||
s += "'";
|
|
||||||
error_list.emplace_back(@1, s);
|
|
||||||
delete $1;
|
|
||||||
YYERROR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
delete $1;
|
|
||||||
$$ = fnode::unop(op::Not, $$);
|
|
||||||
}
|
}
|
||||||
| CONST_TRUE
|
| CONST_TRUE
|
||||||
{ $$ = fnode::tt(); }
|
{ $$ = fnode::tt(); }
|
||||||
|
|
@ -461,18 +457,14 @@ booleanatom: ATOMIC_PROP
|
||||||
sere: booleanatom
|
sere: booleanatom
|
||||||
| OP_NOT sere
|
| OP_NOT sere
|
||||||
{
|
{
|
||||||
if ($2->is_boolean())
|
if (sere_ensure_bool($2, @2, "`!'", error_list))
|
||||||
{
|
{
|
||||||
$$ = fnode::unop(op::Not, $2);
|
$$ = fnode::unop(op::Not, $2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_list.emplace_back(@2,
|
|
||||||
"not a boolean expression: inside a SERE `!' can only "
|
|
||||||
"be applied to a Boolean expression");
|
|
||||||
error_list.emplace_back(@$, "treating this block as false");
|
|
||||||
$2->destroy();
|
$2->destroy();
|
||||||
$$ = fnode::ff();
|
$$ = error_false_block(@$, error_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| bracedsere
|
| bracedsere
|
||||||
|
|
@ -480,8 +472,7 @@ sere: booleanatom
|
||||||
{
|
{
|
||||||
$$ =
|
$$ =
|
||||||
try_recursive_parse(*$1, @1, parse_environment,
|
try_recursive_parse(*$1, @1, parse_environment,
|
||||||
debug_level(), parser_sere, error_list)
|
debug_level(), parser_sere, error_list);
|
||||||
.to_node_();
|
|
||||||
delete $1;
|
delete $1;
|
||||||
if (!$$)
|
if (!$$)
|
||||||
YYERROR;
|
YYERROR;
|
||||||
|
|
@ -560,20 +551,15 @@ sere: booleanatom
|
||||||
error_list.emplace_back(@2, "reversed range");
|
error_list.emplace_back(@2, "reversed range");
|
||||||
std::swap($2.max, $2.min);
|
std::swap($2.max, $2.min);
|
||||||
}
|
}
|
||||||
if ($1->is_boolean())
|
if (sere_ensure_bool($1, @1, "[=...]", error_list))
|
||||||
{
|
{
|
||||||
$$ = formula::sugar_equal(formula($1),
|
$$ = formula::sugar_equal(formula($1),
|
||||||
$2.min, $2.max).to_node_();
|
$2.min, $2.max).to_node_();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_list.emplace_back(@1,
|
|
||||||
"not a boolean expression: [=...] can only "
|
|
||||||
"be applied to a Boolean expression");
|
|
||||||
error_list.emplace_back(@$,
|
|
||||||
"treating this block as false");
|
|
||||||
$1->destroy();
|
$1->destroy();
|
||||||
$$ = fnode::ff();
|
$$ = error_false_block(@$, error_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| sere gotoargs
|
| sere gotoargs
|
||||||
|
|
@ -583,96 +569,60 @@ sere: booleanatom
|
||||||
error_list.emplace_back(@2, "reversed range");
|
error_list.emplace_back(@2, "reversed range");
|
||||||
std::swap($2.max, $2.min);
|
std::swap($2.max, $2.min);
|
||||||
}
|
}
|
||||||
if ($1->is_boolean())
|
if (sere_ensure_bool($1, @1, "[->...]", error_list))
|
||||||
{
|
{
|
||||||
$$ = formula::sugar_goto(formula($1),
|
$$ = formula::sugar_goto(formula($1),
|
||||||
$2.min, $2.max).to_node_();
|
$2.min, $2.max).to_node_();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_list.emplace_back(@1,
|
|
||||||
"not a boolean expression: [->...] can only "
|
|
||||||
"be applied to a Boolean expression");
|
|
||||||
error_list.emplace_back(@$,
|
|
||||||
"treating this block as false");
|
|
||||||
$1->destroy();
|
$1->destroy();
|
||||||
$$ = fnode::ff();
|
$$ = error_false_block(@$, error_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| sere OP_XOR sere
|
| sere OP_XOR sere
|
||||||
{
|
{
|
||||||
if ($1->is_boolean() && $3->is_boolean())
|
if (sere_ensure_bool($1, @1, "`^'", error_list)
|
||||||
|
&& sere_ensure_bool($3, @3, "`^'", error_list))
|
||||||
{
|
{
|
||||||
$$ = fnode::binop(op::Xor, $1, $3);
|
$$ = fnode::binop(op::Xor, $1, $3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!$1->is_boolean())
|
|
||||||
{
|
|
||||||
error_list.emplace_back(@1,
|
|
||||||
"not a boolean expression: inside SERE `<->' can only "
|
|
||||||
"be applied to Boolean expressions");
|
|
||||||
}
|
|
||||||
if (!$3->is_boolean())
|
|
||||||
{
|
|
||||||
error_list.emplace_back(@3,
|
|
||||||
"not a boolean expression: inside SERE `<->' can only "
|
|
||||||
"be applied to Boolean expressions");
|
|
||||||
}
|
|
||||||
error_list.emplace_back(@$, "treating this block as false");
|
|
||||||
$1->destroy();
|
$1->destroy();
|
||||||
$3->destroy();
|
$3->destroy();
|
||||||
$$ = fnode::ff();
|
$$ = error_false_block(@$, error_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| sere OP_XOR error
|
| sere OP_XOR error
|
||||||
{ missing_right_binop($$, $1, @2, "xor operator"); }
|
{ missing_right_binop($$, $1, @2, "xor operator"); }
|
||||||
| sere OP_IMPLIES sere
|
| sere OP_IMPLIES sere
|
||||||
{
|
{
|
||||||
if ($1->is_boolean())
|
if (sere_ensure_bool($1, @1, "`->'", error_list))
|
||||||
{
|
{
|
||||||
$$ = fnode::binop(op::Implies, $1, $3);
|
$$ = fnode::binop(op::Implies, $1, $3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!$1->is_boolean())
|
|
||||||
{
|
|
||||||
error_list.emplace_back(@1,
|
|
||||||
"not a boolean expression: inside SERE `->' can only "
|
|
||||||
"be applied to a Boolean expression");
|
|
||||||
}
|
|
||||||
error_list.emplace_back(@$, "treating this block as false");
|
|
||||||
$1->destroy();
|
$1->destroy();
|
||||||
$3->destroy();
|
$3->destroy();
|
||||||
$$ = fnode::ff();
|
$$ = error_false_block(@$, error_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| sere OP_IMPLIES error
|
| sere OP_IMPLIES error
|
||||||
{ missing_right_binop($$, $1, @2, "implication operator"); }
|
{ missing_right_binop($$, $1, @2, "implication operator"); }
|
||||||
| sere OP_EQUIV sere
|
| sere OP_EQUIV sere
|
||||||
{
|
{
|
||||||
if ($1->is_boolean() && $3->is_boolean())
|
if (sere_ensure_bool($1, @1, "`<->'", error_list)
|
||||||
|
&& sere_ensure_bool($3, @3, "`<->'", error_list))
|
||||||
{
|
{
|
||||||
$$ = fnode::binop(op::Equiv, $1, $3);
|
$$ = fnode::binop(op::Equiv, $1, $3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!$1->is_boolean())
|
|
||||||
{
|
|
||||||
error_list.emplace_back(@1,
|
|
||||||
"not a boolean expression: inside SERE `<->' can only "
|
|
||||||
"be applied to Boolean expressions");
|
|
||||||
}
|
|
||||||
if (!$3->is_boolean())
|
|
||||||
{
|
|
||||||
error_list.emplace_back(@3,
|
|
||||||
"not a boolean expression: inside SERE `<->' can only "
|
|
||||||
"be applied to Boolean expressions");
|
|
||||||
}
|
|
||||||
error_list.emplace_back(@$, "treating this block as false");
|
|
||||||
$1->destroy();
|
$1->destroy();
|
||||||
$3->destroy();
|
$3->destroy();
|
||||||
$$ = fnode::ff();
|
$$ = error_false_block(@$, error_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| sere OP_EQUIV error
|
| sere OP_EQUIV error
|
||||||
|
|
@ -709,7 +659,7 @@ bracedsere: BRACE_OPEN sere BRACE_CLOSE
|
||||||
{
|
{
|
||||||
$$ = try_recursive_parse(*$1, @1, parse_environment,
|
$$ = try_recursive_parse(*$1, @1, parse_environment,
|
||||||
debug_level(),
|
debug_level(),
|
||||||
parser_sere, error_list).to_node_();
|
parser_sere, error_list);
|
||||||
delete $1;
|
delete $1;
|
||||||
if (!$$)
|
if (!$$)
|
||||||
YYERROR;
|
YYERROR;
|
||||||
|
|
@ -718,8 +668,7 @@ bracedsere: BRACE_OPEN sere BRACE_CLOSE
|
||||||
parenthesedsubformula: PAR_BLOCK
|
parenthesedsubformula: PAR_BLOCK
|
||||||
{
|
{
|
||||||
$$ = try_recursive_parse(*$1, @1, parse_environment,
|
$$ = try_recursive_parse(*$1, @1, parse_environment,
|
||||||
debug_level(), parser_ltl, error_list)
|
debug_level(), parser_ltl, error_list);
|
||||||
.to_node_();
|
|
||||||
delete $1;
|
delete $1;
|
||||||
if (!$$)
|
if (!$$)
|
||||||
YYERROR;
|
YYERROR;
|
||||||
|
|
@ -756,8 +705,8 @@ boolformula: booleanatom
|
||||||
| PAR_BLOCK
|
| PAR_BLOCK
|
||||||
{
|
{
|
||||||
$$ = try_recursive_parse(*$1, @1, parse_environment,
|
$$ = try_recursive_parse(*$1, @1, parse_environment,
|
||||||
debug_level(), parser_bool, error_list)
|
debug_level(),
|
||||||
.to_node_();
|
parser_bool, error_list);
|
||||||
delete $1;
|
delete $1;
|
||||||
if (!$$)
|
if (!$$)
|
||||||
YYERROR;
|
YYERROR;
|
||||||
|
|
@ -923,31 +872,15 @@ subformula: booleanatom
|
||||||
| BRA_BANG_BLOCK
|
| BRA_BANG_BLOCK
|
||||||
{
|
{
|
||||||
$$ = try_recursive_parse(*$1, @1, parse_environment,
|
$$ = try_recursive_parse(*$1, @1, parse_environment,
|
||||||
debug_level(), parser_sere, error_list)
|
debug_level(),
|
||||||
.to_node_();
|
parser_sere, error_list);
|
||||||
delete $1;
|
delete $1;
|
||||||
if (!$$)
|
if (!$$)
|
||||||
YYERROR;
|
YYERROR;
|
||||||
$$ = fnode::binop(op::EConcat, $$, fnode::tt());
|
$$ = fnode::binop(op::EConcat, $$, fnode::tt());
|
||||||
}
|
}
|
||||||
|
|
||||||
lbtformula: ATOMIC_PROP
|
lbtformula: atomprop
|
||||||
{
|
|
||||||
$$ = parse_environment.require(*$1).to_node_();
|
|
||||||
if (! $$)
|
|
||||||
{
|
|
||||||
std::string s = "atomic proposition `";
|
|
||||||
s += *$1;
|
|
||||||
s += "' rejected by environment `";
|
|
||||||
s += parse_environment.name();
|
|
||||||
s += "'";
|
|
||||||
error_list.emplace_back(@1, s);
|
|
||||||
delete $1;
|
|
||||||
YYERROR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
delete $1;
|
|
||||||
}
|
|
||||||
| '!' lbtformula
|
| '!' lbtformula
|
||||||
{ $$ = fnode::unop(op::Not, $2); }
|
{ $$ = fnode::unop(op::Not, $2); }
|
||||||
| '&' lbtformula lbtformula
|
| '&' lbtformula lbtformula
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue