Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
OpenGEODE
Commits
c84fefa3
Commit
c84fefa3
authored
Apr 18, 2021
by
Maxime Perrotin
Browse files
Merge
https://github.com/esa/opengeode
into feature_buster
parents
57a1772b
84cbb9a6
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
c84fefa3
...
...
@@ -124,6 +124,9 @@ The background pattern was downloaded from www.subtlepatterns.com
Changelog
=========
**3.5.3 (04/2021)**
-
Model checking observers: add support for parameters in input/output expressions
**3.5.2 (04/2021)**
-
Model checking observers: run only one transition per call
-
Support field names called "state"
...
...
opengeode/AdaGenerator.py
View file @
c84fefa3
...
...
@@ -314,6 +314,29 @@ LD_LIBRARY_PATH=./lib:.:$LD_LIBRARY_PATH opengeode-simulator
# In case model has nested states, flatten everything
Helper
.
flatten
(
process
,
sep
=
SEPARATOR
)
# Pre-processing of aliases: we must rename all references to the aliases
# when they point to a structure that contain a CHOICE field (we cannot
# use a rename clause in that case, since the field depends on a
# discriminant.
no_renames
=
[]
for
(
alias
,
(
sort
,
alias_expr
))
in
process
.
aliases
.
items
():
def
rec_detect_choice
(
expr
:
ogAST
.
Expression
)
->
bool
:
if
not
isinstance
(
expr
,
ogAST
.
PrimSelector
):
return
False
receiver
=
expr
.
value
[
0
]
bty
=
find_basic_type
(
receiver
.
exprType
)
if
bty
.
kind
==
'ChoiceType'
:
return
True
return
rec_detect_choice
(
receiver
)
is_choice
=
rec_detect_choice
(
alias_expr
)
if
is_choice
:
LOG
.
debug
(
f
"alias:
{
alias_expr
.
inputString
}
will replace
{
alias
}
"
)
Helper
.
rename_everything
(
process
.
content
,
alias
,
alias_expr
.
inputString
)
no_renames
.
append
(
alias
)
# Process State aggregations (Parallel states) XXX Add to C backend
# Find recursively in the AST all state aggregations
...
...
@@ -331,6 +354,8 @@ LD_LIBRARY_PATH=./lib:.:$LD_LIBRARY_PATH opengeode-simulator
for
(
var_name
,
content
)
in
process
.
variables
.
items
():
# filter out the aliases and put them in the local variable pool
# to avoid unwanted prefixes when using them
if
var_name
in
no_renames
:
continue
if
var_name
in
process
.
aliases
.
keys
():
LOCAL_VAR
[
var_name
]
=
content
else
:
...
...
@@ -500,6 +525,8 @@ LD_LIBRARY_PATH=./lib:.:$LD_LIBRARY_PATH opengeode-simulator
# Add aliases
for
alias_name
,
(
alias_sort
,
alias_expr
)
in
process
.
aliases
.
items
():
if
alias_name
in
no_renames
:
continue
_
,
qualified
,
_
=
expression
(
alias_expr
)
context_decl
.
append
(
f
"
{
alias_name
}
:
{
type_name
(
alias_sort
)
}
"
f
"renames
{
qualified
}
;"
)
...
...
@@ -2104,7 +2131,7 @@ def _prim_selector(prim, **kwargs):
stmts
,
ada_string
,
local_decl
=
[],
''
,
[]
ro
=
kwargs
.
get
(
"readonly"
,
0
)
receiver
=
prim
.
value
[
0
]
receiver
=
prim
.
value
[
0
]
# can be a PrimSelector
field_name
=
prim
.
value
[
1
]
receiver_stms
,
receiver_string
,
receiver_decl
=
expression
(
receiver
,
...
...
opengeode/icons.py
View file @
c84fefa3
This diff is collapsed.
Click to expand it.
opengeode/ogParser.py
View file @
c84fefa3
...
...
@@ -1657,29 +1657,38 @@ def io_expression(root, context):
direction
=
"out"
string
+=
event_kind
.
format
(
kind
=
kind
)
param_name
=
""
func
=
""
for
child
in
root
.
getChildren
():
if
child
.
type
==
lexer
.
ID
:
msg
=
child
.
text
elif
child
.
type
==
lexer
.
FROM
:
sr
c
=
child
.
getChild
(
0
).
text
fun
c
=
child
.
getChild
(
0
).
text
string
+=
target_option
.
format
(
kind
=
kind
,
target
=
"source"
,
function
=
sr
c
)
function
=
fun
c
)
elif
child
.
type
==
lexer
.
TO
:
dest
=
child
.
getChild
(
0
).
text
func
=
child
.
getChild
(
0
).
text
string
+=
target_option
.
format
(
kind
=
kind
,
target
=
"dest"
,
function
=
dest
)
function
=
func
)
elif
child
.
type
==
lexer
.
IOPARAM
:
# optional parameter
# to find the type of th parameter, the easiest is to parse the
# path to the field as an expression. That will also detect errors.
# this will be done after the parsing of other elements, when
# destination field is known.
param_name
=
child
.
getChild
(
0
).
text
else
:
raise
NotImplementedError
(
"In io_expression"
)
if
msg
:
string
+=
msg_name
.
format
(
kind
=
kind
,
function
=
dest
if
kind
==
"input"
else
sr
c
,
function
=
fun
c
,
direction
=
direction
,
msg
=
msg
)
...
...
@@ -1691,6 +1700,61 @@ def io_expression(root, context):
expr
,
errors
,
warnings
=
expression
(
tree
,
context
)
expr
.
inputString
=
inputString
# Now address the optional parameter: if set, we will create an implicit
# alias definition to the event structure where the parameter is actually
# present. If an alias of the same type already exists, raise an error
if
param_name
:
path
=
f
"event.
{
kind
}
_event.event.
{
func
}
.msg_
{
direction
}
.
{
msg
}
"
parser
=
parser_init
(
string
=
path
)
new_root
=
parser
.
expression
()
tree
=
new_root
.
tree
tree
.
token_stream
=
parser
.
getTokenStream
()
param_expr
,
errs
,
warns
=
expression
(
tree
,
context
)
errors
.
extend
(
errs
)
warnings
.
extend
(
warns
)
# We then need to find the parameter name and get its type
# this is a SEQUENCE by construction (generated by kazoo)
# and since only one parameter is supported, it has only one field
if
not
errs
:
try
:
pname
,
ptype
=
list
(
find_basic_type
(
param_expr
.
exprType
).
Children
.
items
())[
0
]
except
IndexError
:
errors
.
append
(
f
"No parameter expected for message
{
msg
}
"
)
else
:
path
+=
f
".
{
pname
}
"
# We must re-parse the expression with the field name
parser
=
parser_init
(
string
=
path
)
new_root
=
parser
.
expression
()
tree
=
new_root
.
tree
tree
.
token_stream
=
parser
.
getTokenStream
()
param_expr
,
errs
,
warns
=
expression
(
tree
,
context
)
errors
.
extend
(
errs
)
warnings
.
extend
(
warns
)
# The type of the parameter is:
ptype
=
ptype
.
type
#print(f"dcl {param_name} {type_name(ptype)} renames {path};")
for
var
,
(
sort
,
_
)
in
context
.
variables
.
items
():
if
var
.
lower
()
==
param_name
.
lower
():
# variable already defined, does it have the same type?
if
type_name
(
sort
)
!=
type_name
(
ptype
):
errors
.
append
(
f
"Duplicate/incompatible definition"
f
" of variable
{
param_name
}
"
)
elif
var
.
lower
()
in
context
.
aliases
.
keys
():
# Check if already defined variable is an alias,
# and if so, if it points to the same element
_
,
alias_expr
=
context
.
aliases
[
var
.
lower
()]
if
alias_expr
.
inputString
!=
param_expr
.
inputString
:
errors
.
append
(
f
"Parameter name
{
param_name
}
is"
" used in another context, but not "
f
"pointing to the same content"
)
else
:
#print ("param/alias already defined")
break
else
:
# not found a duplicate definition -> Add an alias
context
.
variables
[
param_name
.
lower
()]
=
(
ptype
,
None
)
context
.
aliases
[
param_name
.
lower
()]
=
(
ptype
,
param_expr
)
return
expr
,
errors
,
warnings
def
expression
(
root
,
context
,
pos
=
'right'
):
...
...
@@ -2729,7 +2793,10 @@ def variables(root, ta_ast, context, monitor=False):
if
monitor
:
errors
.
append
(
f
'
{
var
[
-
1
]
}
: aliasing on monitors is not allowed'
)
else
:
context
.
_aliases_ast
.
append
((
var
[
-
1
],
asn1_sort
,
child
.
getChild
(
0
),
ta_ast
))
context
.
_aliases_ast
.
append
((
var
[
-
1
].
lower
(),
asn1_sort
,
child
.
getChild
(
0
),
ta_ast
))
elif
child
.
type
==
lexer
.
GROUND
:
# Default value for a variable - needs to be a ground expression
def_value
,
err
,
warn
=
expression
(
child
.
getChild
(
0
),
context
)
...
...
@@ -3949,6 +4016,7 @@ def process_definition(root, parent=None, context=None):
errors
.
append
([
f
"In alias '
{
alias_name
}
': type mismatch (
{
t1
}
vs
{
t2
}
)"
,
[
ta_ast
.
pos_x
or
0
,
ta_ast
.
pos_y
or
0
],
[]])
else
:
# alias_name is already in lowercase
process
.
aliases
[
alias_name
]
=
(
alias_sort
,
expr
)
if
not
process
.
referenced
and
not
process
.
instance_of_name
\
...
...
opengeode/opengeode.py
View file @
c84fefa3
...
...
@@ -141,7 +141,7 @@ except ImportError:
__all__
=
[
'opengeode'
,
'SDL_Scene'
,
'SDL_View'
,
'parse'
]
__version__
=
'3.5.
2
'
__version__
=
'3.5.
3
'
if
hasattr
(
sys
,
'frozen'
):
# Detect if we are running on Windows (py2exe-generated)
...
...
opengeode/sdl92Lexer.py
View file @
c84fefa3
This diff is collapsed.
Click to expand it.
opengeode/sdl92Parser.py
View file @
c84fefa3
This diff is collapsed.
Click to expand it.
sdl92.g
View file @
c84fefa3
...
...
@@ -83,6 +83,7 @@ tokens {
OUTPUT;
OUTPUT_BODY;
PARAM;
IOPARAM;
PARAMNAMES;
PARAMS;
PAREN;
...
...
@@ -1113,20 +1114,22 @@ postfix_expression
// input and output expression allow observers (for model checking) to
// monitor the sending and receiving of messages with a nice syntax
// (e.g. event = output msg from foo)
// (e.g. event = output msg (p) from foo)
// the parameter is optional. It dooes not need to be declared as a variable,
// as it it implicit.
input_expression
: INPUT
-> ^(INPUT_EXPRESSION)
| INPUT (msg=ID)? (FROM src=ID)? TO dest=ID
-> ^(INPUT_EXPRESSION $msg? ^(FROM $src)? ^(TO $dest))
| INPUT (msg=ID
('(' param=ID ')')?
)? (FROM src=ID)? TO dest=ID
-> ^(INPUT_EXPRESSION $msg?
^(IOPARAM $param)?
^(FROM $src)? ^(TO $dest))
;
output_expression
: OUTPUT
-> ^(OUTPUT_EXPRESSION)
| OUTPUT (msg=ID)? (FROM src=ID) (TO dest=ID)?
-> ^(OUTPUT_EXPRESSION
$msg? ^(FROM $src) ^(TO $dest)?)
| OUTPUT (msg=ID
('(' param=ID ')')?
)? (FROM src=ID) (TO dest=ID)?
-> ^(OUTPUT_EXPRESSION $msg?
^(IOPARAM $param)?
^(FROM $src) ^(TO $dest)?)
;
primary_expression
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment