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
1127e866
Commit
1127e866
authored
Apr 08, 2014
by
Maxime Perrotin
Browse files
Improved support of nested states
parent
a21c962a
Changes
7
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
1127e866
...
...
@@ -11,6 +11,29 @@ SDL is the Specification and Description Language (Z100 standard from ITU-T).
This is NOT related to the graphical Simple DirectMedia Layer libraries!
Visit http://sdl-forum.org for more information about SDL.
Visit http://www.pragmadev.com to get a full-featured commercial SDL tool and support

Features
--------
-
Graphical editor of SDL processes and procedures.
-
SDL2010 features: FOR loops in task symbols, hierarchical states
-
Works on pure PR+CIF files (textual SDL notation) - no fancy proprietary save format
-
Supports ASN.1 data types, including the Value notation - check this page to know more about our ASN.1 compiler and tools
-
Generates Ada code with ASN.1 types using TASTE ASN.1 "space-certified" (SPARK) compiler
-
Extensive syntax and semantic checks
-
Automatic conversion to Statechart diagrams
-
Save the complete or parts of the model to PNG/SVG/PDF files
-
Hyperlinks (link a symbol content to any external document or web page)
-
Zoom in, zoom-out
-
Context-dependent text auto-completion
-
Syntax highlighting
-
Undo/Redo, Copy-Paste
-
(Limited) VIM mode - You can use :wq or :%s,search,replace,g, and /search pattern
Installation
============
...
...
@@ -18,11 +41,11 @@ Installation
Pre-requisites
--------------
There are three major
s
dependencies for OpenGEODE:
There are three major dependencies for OpenGEODE:
-
Pyside (the Qt bindings for Python)
and the ANTLR runtime to be
-
Pyside (the Qt bindings for Python)
-
Python ANTLR Runtime
-
PyGraphviz
-
PyGraphviz
(Linux only - not available on Windows)
If you use pip to install OpenGEODE, these dependencies should be installed
automatically. However, note that installing PySide from pip requires some
...
...
@@ -32,16 +55,16 @@ If you are using a Linux Debian-based distribution (including Ubuntu),
I would recommended to install PySide using your package manager:
You should also install pygraphviz using the same method, for convenience.
$ sudo apt-get install python-pyside pyside-tools python-pygraphviz
And to install pip:
$ sudo apt-get install pip
```
bash
$
sudo
apt-get
install
python-pyside pyside-tools python-pygraphviz pip
```
The Python 2.7 ANTLR 3.1.3 runtime is not part of Debian packages. Install
it with pip (or download and install manually the package):
$ pip install antlr_python_runtime
```
bash
$
pip
install
antlr_python_runtime singledispatch
```
On Windows:
...
...
@@ -57,8 +80,11 @@ Use pip to install the ANTLR runtime (see above)
Automatic installation (recommended)
------------------------------------
$ pip install singledispatch
$ pip install opengeode
To install the application on your machine:
```
bash
$
pip
install
--upgrade
opengeode
```
This is sufficient to get opengeode running
...
...
@@ -79,11 +105,20 @@ Installation from source
You can get the source from the TASTE repositories or from GitHub
```
bash
$
svn co https://tecsw.estec.esa.int/svn/taste/trunk/misc/opengeode opengeode
```
Or
```
bash
$
git clone https://github.com/maxime-esa/opengeode.git opengeode
```
Then as root, type:
Then
enter the opengeode directory and
as root, type:
```
bash
$
make
install
```
Information and contact
=======================
...
...
@@ -110,17 +145,21 @@ The fonts are the fonts from Ubuntu, check licence in file FONT-LICENSE.TXT
Changelog
=========
0.
99 (
28/02
/2014)
0.
99 (
04
/2014)
-
Refactoring of the backend engine, now using singledispatch
-
Support of hierachical states
-
Minor bugfixes
0.
98 (08/07/2014)
0.
98
-
Added support for FOR loops
In a task, use "for x in range([start], stop, [range]): ... endfor"
or "for x in sequenceOfvariable: ... endfor"
-
Default symbol size is smaller
-
Various minor bugfixes
0.
97 (07/12/2013)
0.
97
-
added support for default value when declaring a variable
e.g. DCL myVar myType ::= { x 5, y 2 };
default value must be a ground expression
...
...
Renderer.py
View file @
1127e866
...
...
@@ -101,11 +101,18 @@ def _automaton(ast, scene):
top_level_symbols
.
append
(
render
(
label
,
scene
,
ast
.
states
))
# Render floating states
nested_states
=
{}
for
state
in
ast
.
states
:
# Create only floating states
try
:
new_state
=
render
(
state
,
scene
=
scene
,
states
=
ast
.
states
,
terminators
=
ast
.
parent
.
terminators
)
if
new_state
.
nested_scene
:
if
str
(
new_state
).
lower
()
in
nested_states
.
viewkeys
():
new_state
.
nested_scene
=
None
else
:
nested_states
[
str
(
new_state
).
lower
()]
=
\
new_state
.
nested_scene
except
TypeError
:
# Discard terminators (see _state function for explanation)
pass
...
...
Statechart.py
View file @
1127e866
...
...
@@ -104,6 +104,8 @@ class Point(genericSymbols.HorizontalSymbol, object):
self
.
set_shape
(
node
[
'width'
],
node
[
'height'
])
self
.
setBrush
(
QtGui
.
QBrush
(
QtCore
.
Qt
.
black
))
self
.
graph
=
graph
# Text is read only
self
.
text
.
setTextInteractionFlags
(
QtCore
.
Qt
.
TextBrowserInteraction
)
def
set_shape
(
self
,
width
,
height
):
''' Define the polygon shape from width and height '''
...
...
genericSymbols.py
View file @
1127e866
...
...
@@ -560,7 +560,8 @@ class Symbol(QObject, QGraphicsPathItem, object):
needs_parent
=
True
# nested_scene : a symbol may have content that can be visible on demand
# (e.g. a subscene that appears when double-clicking on the item)
nested_scene
=
None
_allow_nesting
=
False
_nested_scene
=
None
# keywords for the syntax highlighter
blackbold
=
()
redbold
=
()
...
...
@@ -623,7 +624,8 @@ class Symbol(QObject, QGraphicsPathItem, object):
def
is_composite
(
self
):
''' Return True if nested scene has something in it '''
try
:
return
any
(
item
.
isVisible
()
for
item
in
self
.
nested_scene
.
items
())
return
self
.
allow_nesting
and
any
(
item
.
isVisible
()
for
item
in
self
.
_nested_scene
.
items
())
except
AttributeError
:
return
False
...
...
@@ -644,6 +646,23 @@ class Symbol(QObject, QGraphicsPathItem, object):
#LOG.debug(str(followers))
return
followers
@
property
def
allow_nesting
(
self
):
''' Dynamically check if the scene can have a nested subscene
May be redefined in subclasses and checked on double-click
'''
return
self
.
_allow_nesting
@
property
def
nested_scene
(
self
):
''' Return the nested scene. Can be redefined '''
return
self
.
_nested_scene
@
nested_scene
.
setter
def
nested_scene
(
self
,
value
):
''' Set the value of the nested scene '''
self
.
_nested_scene
=
value
def
closest_connection_point
(
self
,
coord
):
'''
Given a position (QPointF), expected in this symbol's
...
...
opengeode.py
View file @
1127e866
...
...
@@ -356,7 +356,8 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
for
top_level
in
Renderer
.
render
(
process
,
scene
=
self
):
G_SYMBOLS
.
add
(
top_level
)
# Render optional sub-scenes (procedures)
if
top_level
.
nested_scene
:
if
top_level
.
nested_scene
and
not
isinstance
(
top_level
.
nested_scene
,
SDL_Scene
):
subscene
=
SDL_Scene
(
context
=
top_level
.
__class__
.
__name__
.
lower
())
subscene
.
messages_window
=
self
.
messages_window
...
...
@@ -1162,8 +1163,7 @@ class SDL_View(QtGui.QGraphicsView, object):
def
go_up
(
self
):
'''
When Up button is clicked, go up one scene level
For example to get out of a procedure definition
When Up button is clicked, go up one nested scene level
'''
LOG
.
debug
(
'GO_UP'
)
self
.
scene
().
clear_focus
()
...
...
@@ -1175,6 +1175,16 @@ class SDL_View(QtGui.QGraphicsView, object):
self
.
up_button
.
setEnabled
(
False
)
self
.
refresh
()
def
go_down
(
self
,
scene
):
''' Enter a nested diagram (procedure, composite state) '''
self
.
parent_scene
.
append
(
self
.
scene
())
self
.
scene
().
clear_focus
()
self
.
setScene
(
scene
)
self
.
up_button
.
setEnabled
(
True
)
self
.
set_toolbar
()
self
.
scene
().
scene_left
.
emit
()
self
.
refresh
()
# pylint: disable=C0103
def
mouseDoubleClickEvent
(
self
,
evt
):
''' Catch a double click - possibly change the scene '''
...
...
@@ -1182,22 +1192,17 @@ class SDL_View(QtGui.QGraphicsView, object):
if
evt
.
button
()
==
Qt
.
LeftButton
:
item
=
self
.
scene
().
symbol_near
(
self
.
mapToScene
(
evt
.
pos
()))
try
:
if
item
.
nested_scene
:
if
item
.
allow_nesting
:
if
not
isinstance
(
item
.
nested_scene
,
SDL_Scene
):
subscene
=
SDL_Scene
(
context
=
item
.
__class__
.
__name__
.
lower
())
subscene
.
messages_window
=
self
.
messages_window
for
top_level
in
Renderer
.
render_process
(
if
item
.
nested_scene
:
for
top_level
in
Renderer
.
render_process
(
subscene
,
item
.
nested_scene
):
G_SYMBOLS
.
add
(
top_level
)
G_SYMBOLS
.
add
(
top_level
)
item
.
nested_scene
=
subscene
self
.
parent_scene
.
append
(
self
.
scene
())
self
.
scene
().
clear_focus
()
self
.
setScene
(
item
.
nested_scene
)
self
.
up_button
.
setEnabled
(
True
)
self
.
set_toolbar
()
# Refresh to make sure the resizeEvent is emitted
self
.
refresh
()
self
.
go_down
(
item
.
nested_scene
)
else
:
# Otherwise, double-click edits the item text
item
.
edit_text
(
self
.
mapToScene
(
evt
.
pos
()))
...
...
sdlSymbols.py
View file @
1127e866
...
...
@@ -869,6 +869,31 @@ class State(VerticalSymbol):
if
ast
.
comment
:
Comment
(
parent
=
self
,
ast
=
ast
.
comment
)
@
property
def
allow_nesting
(
self
):
''' Redefinition - must be checked according to context '''
result
=
not
any
(
elem
in
str
(
self
).
lower
().
strip
()
for
elem
in
(
'-'
,
','
,
'*'
,
' '
))
return
result
@
property
def
nested_scene
(
self
):
''' Redefined - nested scene per state must be unique '''
if
not
self
.
_nested_scene
:
# Check that the nested scene is not already rendered
try
:
for
each
in
self
.
scene
().
composite_states
:
if
str
(
each
).
lower
().
strip
()
==
str
(
self
).
lower
().
strip
():
return
each
.
_nested_scene
except
AttributeError
:
pass
return
self
.
_nested_scene
@
nested_scene
.
setter
def
nested_scene
(
self
,
value
):
''' Set the value of the nested scene '''
self
.
_nested_scene
=
value
def
update_completion_list
(
self
):
''' When text was entered, update state completion list '''
# Get AST for the symbol
...
...
@@ -982,6 +1007,7 @@ class State(VerticalSymbol):
class
Procedure
(
HorizontalSymbol
):
''' Procedure declaration symbol '''
_unique_followers
=
[
'Comment'
]
_allow_nesting
=
True
common_name
=
'procedure'
needs_parent
=
False
# Define reserved keywords for the syntax highlighter
...
...
tests/regression/test10/challenge.pr
View file @
1127e866
PROCESS challenge;
STATE
ON
;
STATE
on
;
SUBSTRUCTURE
in (via_toto);
out (ret0);
...
...
@@ -60,43 +60,51 @@ START;
NEXTSTATE OFF;
/* CIF STATE (-443, 238), (73, 35) */
STATE Safe;
/* CIF INPUT (-487, 293), (70, 35) */
INPUT *;
/* CIF NEXTSTATE (-487, 343), (70, 35) */
NEXTSTATE Off;
/* CIF INPUT (-406, 293), (88, 35) */
INPUT any_one;
/* CIF NEXTSTATE (-397, 343), (70, 35) */
NEXTSTATE on;
ENDSTATE;
/* CIF STATE (-1
76
, 32), (65, 35) */
/* CIF STATE (-1
41
, 32), (65, 35) */
STATE ON;
/* CIF INPUT (1
6
, 87), (88, 35) */
/* CIF INPUT (
5
1, 87), (88, 35) */
INPUT any_one;
/* CIF NEXTSTATE (3, 137), (113, 35) */
NEXTSTATE
ON
;
/* CIF INPUT (1
2
6, 87), (78, 35) */
/* CIF NEXTSTATE (3
8
, 137), (113, 35) */
NEXTSTATE
-
;
/* CIF INPUT (16
1
, 87), (78, 35) */
INPUT go_off;
/* CIF NEXTSTATE (1
30
, 137), (
70
, 35) */
/* CIF NEXTSTATE (1
69
, 137), (
62
, 35) */
NEXTSTATE OFF;
/* CIF CONNECT (-1
43
, 87), (0, 35) */
/* CIF CONNECT (-1
08
, 87), (0, 35) */
CONNECT ret0;
/* CIF PROCEDURECALL (-2
79
, 137), (272, 35) */
/* CIF PROCEDURECALL (-2
44
, 137), (272, 35) */
CALL writeln('Received ret0, going to Safe');
/* CIF NEXTSTATE (-1
76
, 187), (67, 35) */
/* CIF NEXTSTATE (-1
41
, 187), (67, 35) */
NEXTSTATE Safe;
/* CIF CONNECT (-4
59
, 87), (0, 35) */
/* CIF CONNECT (-4
24
, 87), (0, 35) */
CONNECT ;
/* CIF PROCEDURECALL (-
629
, 137), (340, 35) */
/* CIF PROCEDURECALL (-
594
, 137), (340, 35) */
CALL writeln('Exit from nested state (no return value)');
/* CIF NEXTSTATE (-49
4
, 187), (70, 35) */
/* CIF NEXTSTATE (-4
5
9, 187), (70, 35) */
NEXTSTATE off;
ENDSTATE;
/* CIF STATE (-443, 238), (73, 35) */
STATE Safe;
/* CIF INPUT (-487, 293), (70, 35) */
/* CIF STATE (-674, 38), (70, 35) */
STATE on;
/* CIF INPUT (-674, 93), (70, 35) */
INPUT *;
/* CIF NEXTSTATE (-487, 343), (70, 35) */
NEXTSTATE Off;
/* CIF INPUT (-406, 293), (88, 35) */
INPUT any_one;
/* CIF NEXTSTATE (-397, 343), (70, 35) */
NEXTSTATE on;
/* CIF NEXTSTATE (-674, 143), (70, 35) */
NEXTSTATE -;
ENDSTATE;
/* CIF STATE (-843, 111), (70, 35) */
...
...
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