Commit 2a038e00 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Parse graphical model in PR backend

parent de3bd218
......@@ -148,9 +148,9 @@ new feature:
- Update the on-the-fly parser for syntax checks in the graphical editor (ogParser.py)
- Create a graphical symbol for the new feature (in sdlSymbols.py)
- Update the renderer to draw the symbol (Renderer.py)
- Update the backend that saves the model to phrase representation (Pr.py)
- Create an icon and add the new symbol to the palette
- Update the statechart renderer (Statechart.py)
- Update the backend that saves the model to phrase representation (Pr.py)
- Update other backends that can be impacted, such as code generators (AdaGenerator.py, etc.)
5) Syntax checker in ogParser.py
......@@ -209,6 +209,14 @@ class ContinuousSignal(HorizontalSymbol):
super(ContinuousSignal, self).set_shape(width, height)
And you may need to add your new symbol to the properties of other symbols.
For example _insertable_followers gives the list of signals that the tool will
allow you to place after (or next to) the currently selected symbol.
The "state" symbol has this property:
_insertable_followers = ['Input', 'Connect', 'ContinuousSignal']
7) Update the renderer to see some first result: Renderer.py
Since the parser is ready and the symbol is defined, it is now possible to
......@@ -238,8 +246,9 @@ def _continuous_signal(ast, scene, parent, states):
states=states)
return cont
And then you must call the render function from the State renderer, since
the continuous signals are generated below states, just like Inputs:
And then you must call the render function from the State and Terminator
renderers, since the continuous signals are generated below states,
just like Inputs:
@render.register(ogAST.State)
def _state(ast, scene, states, terminators, parent=None):
......@@ -248,4 +257,24 @@ def _state(ast, scene, states, terminators, parent=None):
render(exit, scene=scene, parent=new_state, states=states)
(...)
8) Update the graphical parser backend (Pr.py)
In order to save the model or make syntax checks, we need to make sure that
the graphical model parser recognises the new symbol.
The principle is the same as for the renderer - a singledispatch visitor
pattern, but on the graphical symbols instead of the AST.
It is therefore straightforward to parse - just add a new function that
mimicks an existing one and register it to singledispatch.
@generate.register(sdlSymbols.ContinuousSignal)
def _continuous_signal(symbol, recursive=True, **kwargs):
''' "Provided" symbol or branch if recursive is set '''
result = common('PROVIDED', symbol)
if recursive:
result.extend(recursive_aligned(symbol))
return result
As in 7), also make sure that the parent symbol (here: state) can recursively
parse the new children.
......@@ -194,6 +194,15 @@ def _input(symbol, recursive=True, **kwargs):
return result
@generate.register(sdlSymbols.ContinuousSignal)
def _continuous_signal(symbol, recursive=True, **kwargs):
''' "Provided" symbol or branch if recursive is set '''
result = common('PROVIDED', symbol)
if recursive:
result.extend(recursive_aligned(symbol))
return result
@generate.register(sdlSymbols.Connect)
def _connect(symbol, recursive=True, **kwargs):
''' Connect symbol or branch if recursive is set '''
......@@ -325,7 +334,8 @@ def _state(symbol, recursive=True, nextstate=True, composite=False, cpy=False,
Indent.indent += 1
# Generate code for INPUT and CONNECT symbols
for each in (symb for symb in symbol.childSymbols()
if isinstance(symb, sdlSymbols.Input)):
if isinstance(symb, (sdlSymbols.Input,
sdlSymbols.ContinuousSignal))):
result.extend(generate(each))
Indent.indent -= 1
result.append(u'ENDSTATE;')
......
......@@ -2756,17 +2756,12 @@ def continuous_signal(root, parent, context):
# Keep track of the number of terminator statements in the transition
# useful if we want to render graphs from the SDL model
terminators = len(context.terminators)
i.trigger, err0, warn0 = expression(root.getChild(0), context)
i.trigger, exp_err, exp_warn = expression(root.getChild(0), context)
i.inputString = i.trigger.inputString
for child in root.children[1:]:
if child.type == lexer.CIF:
# Get symbol coordinates
i.pos_x, i.pos_y, i.width, i.height = cif(child)
# # Report errors with symbol coordinates
# errors = [[e, [i.pos_x or 0, i.pos_y or 0], []] for e in errors]
# warnings = [[w, [i.pos_x or 0, i.pos_y or 0], []]
# for w in warnings]
elif child.type == lexer.INT:
# Priority
i.priority = int(child.text)
......@@ -2788,7 +2783,10 @@ def continuous_signal(root, parent, context):
pass
else:
warnings.append('Unsupported INPUT child type: {}'
.format(child.type))
.format(child.type))
# Report errors in the expression with symbol coordinates
errors.extend([[e, [i.pos_x or 0, i.pos_y or 0], []] for e in exp_err])
warnings.extend([[w, [i.pos_x or 0, i.pos_y or 0], []] for w in exp_warn])
# At the end of the input parsing, get the the list of terminators that
# follow the input transition by making a diff with the list at process
# level (we counted the number of terminators before parsing the input)
......@@ -2796,8 +2794,6 @@ def continuous_signal(root, parent, context):
return i, errors, warnings
def input_part(root, parent, context):
''' Parse an INPUT - set of TASTE provided interfaces '''
i = ogAST.Input()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment