scrall 0.9.0__tar.gz → 0.12.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of scrall might be problematic. Click here for more details.
- {scrall-0.9.0/src/scrall.egg-info → scrall-0.12.2}/PKG-INFO +1 -1
- {scrall-0.9.0 → scrall-0.12.2}/pyproject.toml +1 -1
- scrall-0.12.2/src/scrall/__init__.py +1 -0
- {scrall-0.9.0 → scrall-0.12.2}/src/scrall/parse/scrall.peg +9 -8
- {scrall-0.9.0 → scrall-0.12.2}/src/scrall/parse/visitor.py +66 -35
- {scrall-0.9.0 → scrall-0.12.2/src/scrall.egg-info}/PKG-INFO +1 -1
- {scrall-0.9.0 → scrall-0.12.2}/src/scrall.egg-info/SOURCES.txt +4 -0
- scrall-0.12.2/tests/test_calls.py +78 -0
- scrall-0.12.2/tests/test_decision_scalar_expr.py +66 -0
- scrall-0.12.2/tests/test_decision_wrap.py +39 -0
- scrall-0.12.2/tests/test_decision_wrap_false.py +47 -0
- scrall-0.12.2/tests/test_operation.py +30 -0
- {scrall-0.9.0 → scrall-0.12.2}/tests/test_ping_actions.py +4 -3
- {scrall-0.9.0 → scrall-0.12.2}/tests/test_signals.py +23 -3
- {scrall-0.9.0 → scrall-0.12.2}/tests/test_state_actions.py +2 -2
- scrall-0.9.0/src/scrall/__init__.py +0 -1
- scrall-0.9.0/tests/test_calls.py +0 -39
- {scrall-0.9.0 → scrall-0.12.2}/LICENSE +0 -0
- {scrall-0.9.0 → scrall-0.12.2}/MANIFEST.in +0 -0
- {scrall-0.9.0 → scrall-0.12.2}/README.md +0 -0
- {scrall-0.9.0 → scrall-0.12.2}/setup.cfg +0 -0
- {scrall-0.9.0 → scrall-0.12.2}/src/scrall/__main__.py +0 -0
- {scrall-0.9.0 → scrall-0.12.2}/src/scrall/exceptions.py +0 -0
- {scrall-0.9.0 → scrall-0.12.2}/src/scrall/log.conf +0 -0
- {scrall-0.9.0 → scrall-0.12.2}/src/scrall/parse/__init__.py +0 -0
- {scrall-0.9.0 → scrall-0.12.2}/src/scrall/parse/parser.py +0 -0
- {scrall-0.9.0 → scrall-0.12.2}/src/scrall.egg-info/dependency_links.txt +0 -0
- {scrall-0.9.0 → scrall-0.12.2}/src/scrall.egg-info/entry_points.txt +0 -0
- {scrall-0.9.0 → scrall-0.12.2}/src/scrall.egg-info/requires.txt +0 -0
- {scrall-0.9.0 → scrall-0.12.2}/src/scrall.egg-info/top_level.txt +0 -0
- {scrall-0.9.0 → scrall-0.12.2}/tests/test_delete.py +0 -0
- {scrall-0.9.0 → scrall-0.12.2}/tests/test_selection.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "scrall"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.12.2"
|
|
8
8
|
description = "Starr's Concise Relational Action Language - For Shlaer-Mellor Executable UML"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "Leon Starr", email = "leon_starr@modelint.com" }]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "0.12.2"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
activity = LINEWRAP* execution_unit* EOF
|
|
2
|
-
execution_unit = LINEWRAP* statement_set sequence_token? LINEWRAP
|
|
2
|
+
execution_unit = LINEWRAP* statement_set sequence_token? (SP+ / LINEWRAP*)
|
|
3
3
|
statement_set = SP* sequenced_statement_set / component_statement_set
|
|
4
4
|
sequenced_statement_set = sequence_token* (block / statement)
|
|
5
5
|
component_statement_set = block / LINEWRAP* statement
|
|
@@ -44,15 +44,15 @@ RENAME = '>>'
|
|
|
44
44
|
|
|
45
45
|
// Decision action
|
|
46
46
|
decision = scalar_expr true_result false_result?
|
|
47
|
-
true_result = DECISION_OP LINEWRAP? SP? component_statement_set
|
|
48
|
-
false_result =
|
|
47
|
+
true_result = DECISION_OP LINEWRAP? SP? component_statement_set SP*
|
|
48
|
+
false_result = FALSE_RESULT_OP LINEWRAP? SP? component_statement_set // Else
|
|
49
49
|
FALSE_RESULT_OP = ':'
|
|
50
50
|
|
|
51
51
|
// Switch action
|
|
52
52
|
switch = switch_input DECISION_OP SP* case_block // Boolean expr triggers case_block
|
|
53
53
|
switch_input = rnum / scalar_expr
|
|
54
54
|
case_block = '{' LINEWRAP* case+ LINEWRAP*'}'
|
|
55
|
-
case = LINEWRAP* trigger_set? ':' LINEWRAP* component_statement_set
|
|
55
|
+
case = LINEWRAP* trigger_set? ':' (SP+ / LINEWRAP*) component_statement_set
|
|
56
56
|
trigger_set = enum_value (',' SP+ enum_value)* SP*
|
|
57
57
|
enum_value = '_' name // Scalar switch has enum value cases
|
|
58
58
|
DECISION_OP = '?'
|
|
@@ -74,9 +74,9 @@ inst_assignment = flow_output SP+ INST_ASSIGN SP+ instance_set
|
|
|
74
74
|
INST_ASSIGN = '.=' / '..='
|
|
75
75
|
|
|
76
76
|
// Synchronous call action (method or ee operation or type operation)
|
|
77
|
-
call =
|
|
77
|
+
call = instance_set op_chain? // Post-parse verify that last element is an operation, otherwise invalid call
|
|
78
78
|
operation = owner? '.' name supplied_params
|
|
79
|
-
owner = name
|
|
79
|
+
owner = '~' / name
|
|
80
80
|
supplied_params = '(' SP* (param (',' SP+ param)*)? SP* ')'
|
|
81
81
|
param = (name SP* ':' SP*)? scalar_expr // Comma above keeps scalar_expr from grabbing next param
|
|
82
82
|
|
|
@@ -105,7 +105,8 @@ ITS = 'ITS'
|
|
|
105
105
|
// Creation, deletion and references
|
|
106
106
|
new_instance = '*' new_inst_init // create an instance of a class as an action
|
|
107
107
|
new_lineage = '*[' SP* new_inst_init (';' SP+ new_inst_init)+ SP* ']' // create all instances of a lineage
|
|
108
|
-
new_inst_init = name attr_init? (SP+ to_ref)* // specify class, attr inits, and any required references
|
|
108
|
+
new_inst_init = name attr_init? (SP+ to_ref)* (SP+ to_state)? // specify class, attr inits, and any required references
|
|
109
|
+
to_state = '>' SP* name
|
|
109
110
|
attr_init = '(' SP* (attr_value_init (',' SP+ attr_value_init)* SP*)? ')' // all attrs to init for a new instance
|
|
110
111
|
attr_value_init = (name SP? ':' SP+ scalar_expr )*
|
|
111
112
|
update_ref = (instance_set SP+)? to_ref // relate or unrelated to me or explicit instance_set
|
|
@@ -118,7 +119,7 @@ delete = '!*' SP* instance_set (',' SP+ instance_set)* // supports multi-delete
|
|
|
118
119
|
// Scalar assignment
|
|
119
120
|
scalar_assignment = scalar_output_set SP* SCALAR_ASSIGN SP* scalar_expr projection? (',' SP* scalar_expr projection?)*
|
|
120
121
|
scalar_output_set = qualified_name / flow_output (',' SP+ flow_output)*
|
|
121
|
-
qualified_name = name '.' name
|
|
122
|
+
qualified_name = (name / instance_set) '.' name
|
|
122
123
|
flow_output = name (TYPE_ASSIGN name)?
|
|
123
124
|
projection = '.' (name / '(' ( (ALL / (name (',' SP+ name)*) )? ')')) // TODO: Why is empty () ok in projection?
|
|
124
125
|
ALL = '*'
|
|
@@ -42,11 +42,11 @@ BOOL_a = namedtuple('BOOL_a', 'op operands')
|
|
|
42
42
|
Scalar_Assignment_a = namedtuple('Scalar_Assignment_a', 'lhs rhs')
|
|
43
43
|
Table_Assignment_a = namedtuple('Table_Assignment_a', 'type assign_tuple lhs rhs X')
|
|
44
44
|
Scalar_RHS_a = namedtuple('Scalar_RHS_a', 'expr attrs')
|
|
45
|
-
Qualified_Name_a = namedtuple('Qualified_Name_a', 'cname aname')
|
|
45
|
+
Qualified_Name_a = namedtuple('Qualified_Name_a', 'iset cname aname')
|
|
46
46
|
Flow_Output_a = namedtuple('Flow_Output_a', 'name exp_type')
|
|
47
47
|
PATH_a = namedtuple('PATH_a', 'hops')
|
|
48
48
|
INST_a = namedtuple('INST_a', 'components')
|
|
49
|
-
INST_PROJ_a = namedtuple('INST_PROJ_a', 'iset projection')
|
|
49
|
+
INST_PROJ_a = namedtuple('INST_PROJ_a', 'iset projection op_chain')
|
|
50
50
|
TEXPR_a = namedtuple('TEXPR_a', 'table hexpr selection projection')
|
|
51
51
|
R_a = namedtuple('R_a', 'rnum')
|
|
52
52
|
IN_a = namedtuple('IN_a', 'name')
|
|
@@ -60,7 +60,7 @@ Type_expr_a = namedtuple('Type_expr_a', 'type selector')
|
|
|
60
60
|
Attr_value_init_a = namedtuple('Attr_value_init_a', 'attr scalar_expr')
|
|
61
61
|
To_ref_a = namedtuple('To_ref_a', 'rnum iset1 iset2')
|
|
62
62
|
Update_ref_a = namedtuple('Update_ref_a', 'iset to_ref')
|
|
63
|
-
New_inst_a = namedtuple('New_inst_a', 'cname attrs rels')
|
|
63
|
+
New_inst_a = namedtuple('New_inst_a', 'cname attrs rels state')
|
|
64
64
|
New_lineage_a = namedtuple('New_lineage_a', 'inits')
|
|
65
65
|
Output_Flow_a = namedtuple('Output_Flow_a', 'output')
|
|
66
66
|
Projection_a = namedtuple('Projection_a', 'expand attrs')
|
|
@@ -157,7 +157,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
157
157
|
_logger.info(f' :: {node.value}')
|
|
158
158
|
|
|
159
159
|
_logger.info(f"< {children}")
|
|
160
|
-
result = [
|
|
160
|
+
result = children[:]
|
|
161
161
|
_logger.info(f" -> {result}")
|
|
162
162
|
return result
|
|
163
163
|
|
|
@@ -239,7 +239,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
239
239
|
|
|
240
240
|
_logger.info(f" < {children}")
|
|
241
241
|
_logger.info(f" > pass")
|
|
242
|
-
return children
|
|
242
|
+
return children[:] # Removes the result component
|
|
243
243
|
|
|
244
244
|
@classmethod
|
|
245
245
|
def visit_statement(cls, node, children):
|
|
@@ -333,7 +333,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
333
333
|
|
|
334
334
|
_logger.info(f" < {children}")
|
|
335
335
|
_logger.info(" > pass")
|
|
336
|
-
return children
|
|
336
|
+
return children[:]
|
|
337
337
|
|
|
338
338
|
@classmethod
|
|
339
339
|
def visit_attr_type_def(cls, node, children):
|
|
@@ -354,7 +354,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
354
354
|
|
|
355
355
|
_logger.info(f" < {children}")
|
|
356
356
|
_logger.info(f" > pass")
|
|
357
|
-
return children
|
|
357
|
+
return children[:]
|
|
358
358
|
|
|
359
359
|
@classmethod
|
|
360
360
|
def visit_row(cls, node, children):
|
|
@@ -376,7 +376,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
376
376
|
|
|
377
377
|
_logger.info(f" < {children}")
|
|
378
378
|
_logger.info(f" > pass")
|
|
379
|
-
return children
|
|
379
|
+
return children[:]
|
|
380
380
|
|
|
381
381
|
# Implicit table assignment
|
|
382
382
|
@classmethod
|
|
@@ -483,7 +483,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
483
483
|
|
|
484
484
|
_logger.info(f" < {children}")
|
|
485
485
|
_logger.info(f" > pass")
|
|
486
|
-
return children
|
|
486
|
+
return children[:]
|
|
487
487
|
|
|
488
488
|
@classmethod
|
|
489
489
|
def visit_column_op(cls, node, children):
|
|
@@ -592,7 +592,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
592
592
|
_logger.info(f' :: {node.value}')
|
|
593
593
|
|
|
594
594
|
_logger.info(f" < {children}")
|
|
595
|
-
result = children
|
|
595
|
+
result = children[:]
|
|
596
596
|
_logger.info(f" > {result}")
|
|
597
597
|
return result
|
|
598
598
|
|
|
@@ -635,14 +635,6 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
635
635
|
_logger.info(f" > {result}")
|
|
636
636
|
return result
|
|
637
637
|
|
|
638
|
-
# # Asynch service
|
|
639
|
-
# @classmethod
|
|
640
|
-
# def visit_asynch_service(cls, node, children):
|
|
641
|
-
# """
|
|
642
|
-
# name '.' signal_spec ASYNCH ee
|
|
643
|
-
# """
|
|
644
|
-
# result = Asynch_a(*children)
|
|
645
|
-
|
|
646
638
|
@classmethod
|
|
647
639
|
def visit_signal_action(cls, node, children):
|
|
648
640
|
"""
|
|
@@ -685,7 +677,8 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
685
677
|
_logger.info(f' :: {node.value}')
|
|
686
678
|
|
|
687
679
|
_logger.info(f" < {children}")
|
|
688
|
-
params = children.results.get('supplied_params'
|
|
680
|
+
params = children.results.get('supplied_params')
|
|
681
|
+
params = params[0] if params else []
|
|
689
682
|
result = {'name': children[0].name, 'params': params}
|
|
690
683
|
_logger.info(f" > {result}")
|
|
691
684
|
return result
|
|
@@ -789,7 +782,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
789
782
|
_logger.info(f' :: {node.value}')
|
|
790
783
|
|
|
791
784
|
_logger.info(f" < {children}")
|
|
792
|
-
result = children
|
|
785
|
+
result = children[:]
|
|
793
786
|
_logger.info(f" > {result}")
|
|
794
787
|
return result
|
|
795
788
|
|
|
@@ -840,13 +833,23 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
840
833
|
owner = children.results.get('owner')
|
|
841
834
|
p = children.results.get('supplied_params')
|
|
842
835
|
result = Op_a(
|
|
843
|
-
owner='
|
|
836
|
+
owner='_implicit' if not owner else owner[0],
|
|
844
837
|
op_name=children.results['name'][0].name,
|
|
845
838
|
supplied_params=[] if not p else p[0]
|
|
846
839
|
)
|
|
847
840
|
_logger.info(f" > {result}")
|
|
848
841
|
return result
|
|
849
842
|
|
|
843
|
+
@classmethod
|
|
844
|
+
def visit_owner(cls, node, children):
|
|
845
|
+
"""
|
|
846
|
+
'~' / name
|
|
847
|
+
"""
|
|
848
|
+
name = children.results.get('name')
|
|
849
|
+
# This is either ~ signifying an external service or a single instance flow (instance set)
|
|
850
|
+
result = name[0].name if name else '_external'
|
|
851
|
+
return result
|
|
852
|
+
|
|
850
853
|
@classmethod
|
|
851
854
|
def visit_supplied_params(cls, node, children):
|
|
852
855
|
"""
|
|
@@ -856,7 +859,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
856
859
|
_logger.info(f' :: {node.value}')
|
|
857
860
|
|
|
858
861
|
_logger.info(f" < {children}")
|
|
859
|
-
result = children
|
|
862
|
+
result = children[:]
|
|
860
863
|
_logger.info(f" > {result}")
|
|
861
864
|
return result
|
|
862
865
|
|
|
@@ -906,7 +909,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
906
909
|
_logger.info(f' :: {node.value}')
|
|
907
910
|
|
|
908
911
|
_logger.info(f" < {children}")
|
|
909
|
-
result = Iteration_a(*children)
|
|
912
|
+
result = Iteration_a(*children) # TODO: Check this for inclusion of results member
|
|
910
913
|
_logger.info(f" > {result}")
|
|
911
914
|
return result
|
|
912
915
|
|
|
@@ -947,7 +950,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
947
950
|
# Just like above case, but returning an IN_a (parameter name)
|
|
948
951
|
result = p[0]
|
|
949
952
|
else:
|
|
950
|
-
result = INST_a(children)
|
|
953
|
+
result = INST_a(children[:])
|
|
951
954
|
_logger.info(f" > {result}")
|
|
952
955
|
return result
|
|
953
956
|
|
|
@@ -1015,7 +1018,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
1015
1018
|
_logger.info(f' :: {node.value}')
|
|
1016
1019
|
|
|
1017
1020
|
_logger.info(f" < {children}")
|
|
1018
|
-
result = New_lineage_a(children)
|
|
1021
|
+
result = New_lineage_a(children[:])
|
|
1019
1022
|
_logger.info(f" > {result}")
|
|
1020
1023
|
return result
|
|
1021
1024
|
|
|
@@ -1030,10 +1033,25 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
1030
1033
|
_logger.info(f" < {children}")
|
|
1031
1034
|
a = children.results.get('attr_init')
|
|
1032
1035
|
r = children.results.get('to_ref')
|
|
1033
|
-
|
|
1036
|
+
s = children.results.get('to_state')
|
|
1037
|
+
result = New_inst_a(cname=children[0], attrs=a[0] if a else [], rels=None if not r else r,
|
|
1038
|
+
state=s[0].name if s else None)
|
|
1034
1039
|
_logger.info(f" > {result}")
|
|
1035
1040
|
return result
|
|
1036
1041
|
|
|
1042
|
+
@classmethod
|
|
1043
|
+
def visit_to_state(cls, node, children):
|
|
1044
|
+
"""
|
|
1045
|
+
'>' SP* name
|
|
1046
|
+
"""
|
|
1047
|
+
_logger.info("to_state = '>' SP* name")
|
|
1048
|
+
_logger.info(f' :: {node.value}')
|
|
1049
|
+
|
|
1050
|
+
_logger.info(f" < {children}")
|
|
1051
|
+
result = children[0]
|
|
1052
|
+
return result
|
|
1053
|
+
|
|
1054
|
+
|
|
1037
1055
|
@classmethod
|
|
1038
1056
|
def visit_attr_init(cls, node, children):
|
|
1039
1057
|
"""
|
|
@@ -1112,7 +1130,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
1112
1130
|
_logger.info(f' :: {node.value}')
|
|
1113
1131
|
|
|
1114
1132
|
_logger.info(f" < {children}")
|
|
1115
|
-
result = Scalar_Call_a(children)
|
|
1133
|
+
result = Scalar_Call_a(children[:])
|
|
1116
1134
|
_logger.info(f" > {result}")
|
|
1117
1135
|
return result
|
|
1118
1136
|
|
|
@@ -1136,10 +1154,21 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
1136
1154
|
@classmethod
|
|
1137
1155
|
def visit_qualified_name(cls, node, children):
|
|
1138
1156
|
"""
|
|
1157
|
+
(name / instance_set) '.' name
|
|
1139
1158
|
"""
|
|
1140
1159
|
_logger.info("qualified_name = name '.' name")
|
|
1141
1160
|
_logger.info(f' :: {node.value}')
|
|
1142
|
-
|
|
1161
|
+
iset = children.results.get('instance_set')
|
|
1162
|
+
names = children.results.get('name')
|
|
1163
|
+
if iset:
|
|
1164
|
+
# iset takes the place of cname
|
|
1165
|
+
# iset.attribute -- /R4/Door.Lock request
|
|
1166
|
+
aname = names[0].name
|
|
1167
|
+
cname = None
|
|
1168
|
+
else:
|
|
1169
|
+
# class.attribute -- Door.Lock request
|
|
1170
|
+
cname, aname = names[0].name, names[1].name
|
|
1171
|
+
return Qualified_Name_a(iset=iset, cname=cname, aname=aname)
|
|
1143
1172
|
|
|
1144
1173
|
@classmethod
|
|
1145
1174
|
def visit_scalar_output_set(cls, node, children):
|
|
@@ -1149,7 +1178,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
1149
1178
|
_logger.info(f' :: {node.value}')
|
|
1150
1179
|
|
|
1151
1180
|
_logger.info(f" < {children}")
|
|
1152
|
-
result = children
|
|
1181
|
+
result = children[:]
|
|
1153
1182
|
_logger.info(f" > {result}")
|
|
1154
1183
|
return result
|
|
1155
1184
|
|
|
@@ -1417,7 +1446,8 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
1417
1446
|
_logger.info(f" > {result}")
|
|
1418
1447
|
return result
|
|
1419
1448
|
|
|
1420
|
-
if len(children) == 1 and (isinstance(children[0], N_a) or (isinstance(children[0], IN_a))
|
|
1449
|
+
if len(children) == 1 and (isinstance(children[0], N_a) or (isinstance(children[0], IN_a)) or
|
|
1450
|
+
isinstance(children[0], Type_expr_a)):
|
|
1421
1451
|
result = children[0]
|
|
1422
1452
|
_logger.info(f" > {result}")
|
|
1423
1453
|
return result
|
|
@@ -1426,12 +1456,13 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
1426
1456
|
iset = children.results.get('instance_set')
|
|
1427
1457
|
if iset:
|
|
1428
1458
|
p = children.results.get('projection')
|
|
1429
|
-
|
|
1459
|
+
o = children.results.get('op_chain')
|
|
1460
|
+
op_chain = None if not o else o[0]
|
|
1461
|
+
result = INST_PROJ_a(iset=iset[0], projection=None if not p else p[0], op_chain=op_chain)
|
|
1430
1462
|
_logger.info(f" > {result}")
|
|
1431
1463
|
return result
|
|
1432
|
-
# TODO: include opchain if supplied
|
|
1433
1464
|
|
|
1434
|
-
result = children
|
|
1465
|
+
result = children[:]
|
|
1435
1466
|
_logger.info(f" > {result}")
|
|
1436
1467
|
return result
|
|
1437
1468
|
|
|
@@ -1462,7 +1493,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
1462
1493
|
_logger.info(f' :: {node.value}')
|
|
1463
1494
|
|
|
1464
1495
|
_logger.info(f" < {children}")
|
|
1465
|
-
result = Op_chain_a(children)
|
|
1496
|
+
result = Op_chain_a(children[:])
|
|
1466
1497
|
_logger.info(f" > {result}")
|
|
1467
1498
|
return result
|
|
1468
1499
|
|
|
@@ -1571,7 +1602,7 @@ class ScrallVisitor(PTNodeVisitor):
|
|
|
1571
1602
|
_logger.info(f' :: {node.value}')
|
|
1572
1603
|
|
|
1573
1604
|
_logger.info(f" < {children}")
|
|
1574
|
-
result = PATH_a(children)
|
|
1605
|
+
result = PATH_a(children[:])
|
|
1575
1606
|
_logger.info(f" > {result}")
|
|
1576
1607
|
return result
|
|
1577
1608
|
|
|
@@ -17,7 +17,11 @@ src/scrall/parse/parser.py
|
|
|
17
17
|
src/scrall/parse/scrall.peg
|
|
18
18
|
src/scrall/parse/visitor.py
|
|
19
19
|
tests/test_calls.py
|
|
20
|
+
tests/test_decision_scalar_expr.py
|
|
21
|
+
tests/test_decision_wrap.py
|
|
22
|
+
tests/test_decision_wrap_false.py
|
|
20
23
|
tests/test_delete.py
|
|
24
|
+
tests/test_operation.py
|
|
21
25
|
tests/test_ping_actions.py
|
|
22
26
|
tests/test_selection.py
|
|
23
27
|
tests/test_signals.py
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
""" test_calls.py - Test method calls and calls to an external service """
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from scrall.parse.parser import ScrallParser
|
|
5
|
+
from scrall.parse.visitor import *
|
|
6
|
+
|
|
7
|
+
actions = [
|
|
8
|
+
("~.Goto floor( Dest floor: ^new dest )",
|
|
9
|
+
Execution_Unit_a(
|
|
10
|
+
statement_set=Seq_Statement_Set_a(
|
|
11
|
+
input_tokens=[],
|
|
12
|
+
statement=Call_a(
|
|
13
|
+
call=INST_a(
|
|
14
|
+
components=[
|
|
15
|
+
Op_a(owner='_external', op_name='Goto floor',
|
|
16
|
+
supplied_params=[
|
|
17
|
+
Supplied_Parameter_a(
|
|
18
|
+
pname='Dest floor', sval=IN_a(name='new dest')
|
|
19
|
+
)
|
|
20
|
+
])]), op_chain=None), block=None), output_token=None)
|
|
21
|
+
),
|
|
22
|
+
# Execution_Unit_a(
|
|
23
|
+
# statement_set=Seq_Statement_Set_a(
|
|
24
|
+
# input_tokens=[],
|
|
25
|
+
# statement=Call_a(
|
|
26
|
+
# call=None,
|
|
27
|
+
# op_chain=Op_chain_a(
|
|
28
|
+
# components=[
|
|
29
|
+
# Scalar_op_a(
|
|
30
|
+
# name=N_a(name='Goto floor'),
|
|
31
|
+
# supplied_params=[
|
|
32
|
+
# Supplied_Parameter_a(
|
|
33
|
+
# pname='Dest floor',
|
|
34
|
+
# sval=IN_a(name='new dest')
|
|
35
|
+
# )
|
|
36
|
+
# ]
|
|
37
|
+
# )
|
|
38
|
+
# ]
|
|
39
|
+
# )
|
|
40
|
+
# ), block=None),
|
|
41
|
+
# output_token=None)
|
|
42
|
+
# ),
|
|
43
|
+
(".Ping( dir: Travel direction.opposite )",
|
|
44
|
+
Execution_Unit_a(
|
|
45
|
+
statement_set=Seq_Statement_Set_a(
|
|
46
|
+
input_tokens=[],
|
|
47
|
+
statement=Call_a(
|
|
48
|
+
call=INST_a(
|
|
49
|
+
components=[
|
|
50
|
+
Op_a(
|
|
51
|
+
owner='_implicit',
|
|
52
|
+
op_name='Ping',
|
|
53
|
+
supplied_params=[
|
|
54
|
+
Supplied_Parameter_a(
|
|
55
|
+
pname='dir',
|
|
56
|
+
sval=INST_PROJ_a(
|
|
57
|
+
iset=N_a(name='Travel direction'),
|
|
58
|
+
projection=Projection_a(
|
|
59
|
+
expand=None, attrs=[N_a(name='opposite')]
|
|
60
|
+
),
|
|
61
|
+
op_chain=None
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
]
|
|
65
|
+
)
|
|
66
|
+
]
|
|
67
|
+
),
|
|
68
|
+
op_chain=None),
|
|
69
|
+
block=None),
|
|
70
|
+
output_token=None)
|
|
71
|
+
),
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
@pytest.mark.parametrize("text, expected", actions)
|
|
75
|
+
def test_call_action(text, expected):
|
|
76
|
+
parse = ScrallParser.parse_text(scrall_text=text, debug=False)[0]
|
|
77
|
+
print(parse)
|
|
78
|
+
assert parse[0] == expected
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
""" test_decision_scalar_expr.py -- Ensure scalar expression works as true result in a decision"""
|
|
2
|
+
|
|
3
|
+
# This verifies that we don't have a regression on a bug fix where scalar_expr true results were eating the colon
|
|
4
|
+
# and failing the parse
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
from scrall.parse.parser import ScrallParser
|
|
8
|
+
from scrall.parse.visitor import *
|
|
9
|
+
|
|
10
|
+
actions = [
|
|
11
|
+
("fwd dest? =>> fwd dest : {\n"
|
|
12
|
+
" rev dest .= Ping( dir: Travel direction.opposite )\n"
|
|
13
|
+
" !rev dest? Travel direction.toggle : =>> rev dest\n"
|
|
14
|
+
"}",
|
|
15
|
+
Execution_Unit_a(
|
|
16
|
+
statement_set=Seq_Statement_Set_a(
|
|
17
|
+
input_tokens=[],
|
|
18
|
+
statement=Decision_a(
|
|
19
|
+
input=N_a(name='fwd dest'),
|
|
20
|
+
true_result=Comp_Statement_Set_a(
|
|
21
|
+
statement=Output_Flow_a(output=N_a(name='fwd dest')), block=None),
|
|
22
|
+
false_result=Comp_Statement_Set_a(
|
|
23
|
+
statement=None, block=[
|
|
24
|
+
Execution_Unit_a(
|
|
25
|
+
statement_set=Seq_Statement_Set_a(
|
|
26
|
+
input_tokens=[],
|
|
27
|
+
statement=Inst_Assignment_a(
|
|
28
|
+
lhs=Flow_Output_a(name=N_a(name='rev dest'), exp_type=None), card='1',
|
|
29
|
+
rhs=INST_a(components=
|
|
30
|
+
[N_a(name='Ping'),
|
|
31
|
+
Criteria_Selection_a(
|
|
32
|
+
card='ALL',
|
|
33
|
+
criteria=BOOL_a(op='==',
|
|
34
|
+
operands=[N_a(name='dir'),
|
|
35
|
+
INST_PROJ_a(
|
|
36
|
+
iset=N_a(name='Travel direction'),
|
|
37
|
+
projection=Projection_a(
|
|
38
|
+
expand=None,
|
|
39
|
+
attrs=[N_a(name='opposite')]), op_chain=None)
|
|
40
|
+
]))]), X=(31, 81)), block=None),
|
|
41
|
+
output_token=None),
|
|
42
|
+
Execution_Unit_a(
|
|
43
|
+
statement_set=Seq_Statement_Set_a(
|
|
44
|
+
input_tokens=[],
|
|
45
|
+
statement=Decision_a(
|
|
46
|
+
input=BOOL_a(op='NOT', operands=N_a(name='rev dest')),
|
|
47
|
+
true_result=Comp_Statement_Set_a(
|
|
48
|
+
statement=Call_a(
|
|
49
|
+
call=N_a(name='Travel direction'),
|
|
50
|
+
op_chain=Op_chain_a(components=[N_a(name='toggle')])), block=None),
|
|
51
|
+
false_result=Comp_Statement_Set_a(
|
|
52
|
+
statement=Output_Flow_a(
|
|
53
|
+
output=N_a(name='rev dest')), block=None)), block=None),
|
|
54
|
+
output_token=None)
|
|
55
|
+
]
|
|
56
|
+
)
|
|
57
|
+
), block=None
|
|
58
|
+
), output_token=None),
|
|
59
|
+
)
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
@pytest.mark.parametrize("text, expected", actions)
|
|
63
|
+
def test_decision_scalar_true_result(text, expected):
|
|
64
|
+
parse = ScrallParser.parse_text(scrall_text=text, debug=False)[0]
|
|
65
|
+
print(parse)
|
|
66
|
+
assert parse[0] == expected
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
""" test_decision_wrap.py -- Test line wrapping """
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from scrall.parse.parser import ScrallParser
|
|
5
|
+
from scrall.parse.visitor import *
|
|
6
|
+
|
|
7
|
+
# The expected result is teh same for each input case
|
|
8
|
+
expected_parse = Execution_Unit_a(
|
|
9
|
+
statement_set=Seq_Statement_Set_a(
|
|
10
|
+
input_tokens=[],
|
|
11
|
+
statement=Decision_a(
|
|
12
|
+
input=N_a(name='choice'),
|
|
13
|
+
true_result=Comp_Statement_Set_a(
|
|
14
|
+
statement=None,
|
|
15
|
+
block=[
|
|
16
|
+
Execution_Unit_a(
|
|
17
|
+
statement_set=Seq_Statement_Set_a(
|
|
18
|
+
input_tokens=[],
|
|
19
|
+
statement=New_inst_a(
|
|
20
|
+
cname=N_a(name='cat'), attrs=[], rels=None, state=None),
|
|
21
|
+
block=None
|
|
22
|
+
),
|
|
23
|
+
output_token=None
|
|
24
|
+
)
|
|
25
|
+
]), false_result=None), block=None
|
|
26
|
+
), output_token=None
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# Different line wrapping of the same content
|
|
30
|
+
@pytest.mark.parametrize("text", [
|
|
31
|
+
"choice? { *cat }",
|
|
32
|
+
"choice? {\n*cat }",
|
|
33
|
+
"choice? {\n *cat\n}",
|
|
34
|
+
"choice?\n { *cat }",
|
|
35
|
+
])
|
|
36
|
+
def test_decision_wrap(text):
|
|
37
|
+
parse = ScrallParser.parse_text(scrall_text=text, debug=False)[0]
|
|
38
|
+
print(parse)
|
|
39
|
+
assert parse[0] == expected_parse
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
""" test_decision_wrap_false.py -- Test line wrapping with true false decision cases """
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from scrall.parse.parser import ScrallParser
|
|
5
|
+
from scrall.parse.visitor import *
|
|
6
|
+
|
|
7
|
+
# The expected result is teh same for each input case
|
|
8
|
+
expected_parse = Execution_Unit_a(
|
|
9
|
+
statement_set=Seq_Statement_Set_a(
|
|
10
|
+
input_tokens=[],
|
|
11
|
+
statement=Decision_a(
|
|
12
|
+
input=N_a(name='choice'),
|
|
13
|
+
true_result=Comp_Statement_Set_a(
|
|
14
|
+
statement=None,
|
|
15
|
+
block=[
|
|
16
|
+
Execution_Unit_a(
|
|
17
|
+
statement_set=Seq_Statement_Set_a(
|
|
18
|
+
input_tokens=[],
|
|
19
|
+
statement=New_inst_a(
|
|
20
|
+
cname=N_a(name='cat'), attrs=[], rels=None, state=None),
|
|
21
|
+
block=None), output_token=None
|
|
22
|
+
)
|
|
23
|
+
]),
|
|
24
|
+
false_result=Comp_Statement_Set_a(
|
|
25
|
+
statement=None,
|
|
26
|
+
block=[
|
|
27
|
+
Execution_Unit_a(
|
|
28
|
+
statement_set=Seq_Statement_Set_a(
|
|
29
|
+
input_tokens=[],
|
|
30
|
+
statement=New_inst_a(
|
|
31
|
+
cname=N_a(name='dog'), attrs=[], rels=None, state=None),
|
|
32
|
+
block=None), output_token=None
|
|
33
|
+
)
|
|
34
|
+
])
|
|
35
|
+
), block=None), output_token=None)
|
|
36
|
+
|
|
37
|
+
# Different line wrapping of the same content
|
|
38
|
+
@pytest.mark.parametrize("text", [
|
|
39
|
+
"choice? { *cat } : { *dog }",
|
|
40
|
+
"choice? { *cat } : {\n *dog\n }",
|
|
41
|
+
"choice? { *cat } : {\n *dog }",
|
|
42
|
+
"choice? { *cat } :\n {\n *dog\n }",
|
|
43
|
+
])
|
|
44
|
+
def test_signal_action(text):
|
|
45
|
+
parse = ScrallParser.parse_text(scrall_text=text, debug=False)[0]
|
|
46
|
+
print(parse)
|
|
47
|
+
assert parse[0] == expected_parse
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
""" test_operation.py - Test the invocation of an operation"""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from scrall.parse.parser import ScrallParser
|
|
5
|
+
from scrall.parse.visitor import *
|
|
6
|
+
|
|
7
|
+
actions = [
|
|
8
|
+
("dest aslev .= cabin in shaft.Ping both ways()",
|
|
9
|
+
Execution_Unit_a(statement_set=Seq_Statement_Set_a(
|
|
10
|
+
input_tokens=[],
|
|
11
|
+
statement=Inst_Assignment_a(
|
|
12
|
+
lhs=Flow_Output_a(name=N_a(name='dest aslev'), exp_type=None), card='1',
|
|
13
|
+
rhs=INST_a(
|
|
14
|
+
components=[
|
|
15
|
+
Op_a(
|
|
16
|
+
owner='cabin in shaft',
|
|
17
|
+
op_name='Ping both ways',
|
|
18
|
+
supplied_params=[])]
|
|
19
|
+
), X=(0, 45)
|
|
20
|
+
),
|
|
21
|
+
block=None), output_token=None)
|
|
22
|
+
),
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@pytest.mark.parametrize("text, expected", actions)
|
|
27
|
+
def test_operation(text, expected):
|
|
28
|
+
parse = ScrallParser.parse_text(scrall_text=text, debug=False)[0]
|
|
29
|
+
print(parse)
|
|
30
|
+
assert parse[0] == expected
|
|
@@ -49,7 +49,7 @@ actions = [
|
|
|
49
49
|
input_tokens=[],
|
|
50
50
|
statement=Signal_a(
|
|
51
51
|
event='Try redirect', supplied_params=[
|
|
52
|
-
|
|
52
|
+
Supplied_Parameter_a(pname='new dest', sval=IN_a(name='new dest'))],
|
|
53
53
|
dest=Signal_Dest_a(
|
|
54
54
|
target_iset=INST_a(
|
|
55
55
|
components=[PATH_a(hops=[R_a(rnum='R53'), N_a(name='Cabin')])]),
|
|
@@ -99,8 +99,9 @@ actions = [
|
|
|
99
99
|
Criteria_Selection_a(card='ALL', criteria=BOOL_a(op='AND', operands=[
|
|
100
100
|
BOOL_a(op='==', operands=[N_a(name='Floor'),
|
|
101
101
|
INST_PROJ_a(iset=N_a(name='nearest dest'),
|
|
102
|
-
projection=Projection_a(expand=None, attrs=[N_a(name='Floor')]))]),
|
|
103
|
-
N_a(name='Shaft')]))]), projection=None)), block=None),
|
|
102
|
+
projection=Projection_a(expand=None, attrs=[N_a(name='Floor')]), op_chain=None)]),
|
|
103
|
+
N_a(name='Shaft')]))]), projection=None, op_chain=None)), block=None),
|
|
104
|
+
output_token=None
|
|
104
105
|
)
|
|
105
106
|
),
|
|
106
107
|
]
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import pytest
|
|
4
4
|
from scrall.parse.parser import ScrallParser
|
|
5
|
-
from scrall.parse.visitor import Execution_Unit_a, Signal_a, Signal_Dest_a, N_a, INST_a, PATH_a, R_a,
|
|
6
|
-
Seq_Statement_Set_a, Supplied_Parameter_a, External_Signal_a
|
|
5
|
+
from scrall.parse.visitor import (Execution_Unit_a, Signal_a, Signal_Dest_a, N_a, INST_a, PATH_a, R_a,
|
|
6
|
+
Seq_Statement_Set_a, Supplied_Parameter_a, External_Signal_a, Decision_a, Comp_Statement_Set_a)
|
|
7
7
|
|
|
8
8
|
actions = [
|
|
9
9
|
("Time to close ->* me",
|
|
@@ -24,7 +24,7 @@ actions = [
|
|
|
24
24
|
statement=External_Signal_a(
|
|
25
25
|
event='Goto floor',
|
|
26
26
|
supplied_params=[
|
|
27
|
-
|
|
27
|
+
Supplied_Parameter_a(pname='Dest floor', sval=N_a(name='my level'))
|
|
28
28
|
]), block=None),
|
|
29
29
|
output_token=None)
|
|
30
30
|
),
|
|
@@ -53,6 +53,26 @@ actions = [
|
|
|
53
53
|
block=None),
|
|
54
54
|
output_token=None)
|
|
55
55
|
),
|
|
56
|
+
("destination aslev?\n"
|
|
57
|
+
" Transfer created -> : No destination -> me",
|
|
58
|
+
Execution_Unit_a(
|
|
59
|
+
statement_set=Seq_Statement_Set_a(
|
|
60
|
+
input_tokens=[],
|
|
61
|
+
statement=Decision_a(
|
|
62
|
+
input=N_a(name='destination aslev'),
|
|
63
|
+
true_result=Comp_Statement_Set_a(
|
|
64
|
+
statement=Signal_a(
|
|
65
|
+
event='Transfer created',
|
|
66
|
+
supplied_params=[], dest=None), block=None),
|
|
67
|
+
false_result=Comp_Statement_Set_a(
|
|
68
|
+
statement=Signal_a(
|
|
69
|
+
event='No destination',
|
|
70
|
+
supplied_params=[],
|
|
71
|
+
dest=Signal_Dest_a(
|
|
72
|
+
target_iset=N_a(name='me'), assigner_dest=None, delay=0, cancel=False
|
|
73
|
+
)), block=None
|
|
74
|
+
)), block=None), output_token=None)
|
|
75
|
+
),
|
|
56
76
|
]
|
|
57
77
|
|
|
58
78
|
|
|
@@ -19,7 +19,7 @@ actions = [
|
|
|
19
19
|
statement=Decision_a(input=BOOL_a(
|
|
20
20
|
op='NOT', operands=INST_PROJ_a(iset=INST_a(
|
|
21
21
|
components=[PATH_a(hops=[R_a(rnum='R2'), N_a(name='Shaft')])]),
|
|
22
|
-
projection=Projection_a(expand=None, attrs=[N_a(name='In service')]))),
|
|
22
|
+
projection=Projection_a(expand=None, attrs=[N_a(name='In service')]), op_chain=None)),
|
|
23
23
|
true_result=Comp_Statement_Set_a(statement=
|
|
24
24
|
Signal_a(event='Take out of service', supplied_params=[],
|
|
25
25
|
dest=Signal_Dest_a(target_iset=N_a(name='ME'),
|
|
@@ -32,7 +32,7 @@ actions = [
|
|
|
32
32
|
statement=Decision_a(input=BOOL_a(
|
|
33
33
|
op='NOT', operands=INST_PROJ_a(iset=INST_a(
|
|
34
34
|
components=[PATH_a(hops=[R_a(rnum='R2'), N_a(name='Shaft')])]),
|
|
35
|
-
projection=Projection_a(expand=None, attrs=[N_a(name='In service')]))),
|
|
35
|
+
projection=Projection_a(expand=None, attrs=[N_a(name='In service')]), op_chain=None)),
|
|
36
36
|
true_result=Comp_Statement_Set_a(statement=
|
|
37
37
|
Signal_a(event='Take out of service', supplied_params=[],
|
|
38
38
|
dest=Signal_Dest_a(target_iset=N_a(name='ME'),
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
version = "0.9.0"
|
scrall-0.9.0/tests/test_calls.py
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
""" test_calls.py - Test method calls and calls to an external service """
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
from scrall.parse.parser import ScrallParser
|
|
5
|
-
from scrall.parse.visitor import (
|
|
6
|
-
Execution_Unit_a, Seq_Statement_Set_a, Call_a, Op_chain_a, Scalar_op_a,
|
|
7
|
-
Supplied_Parameter_a, N_a, IN_a,
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
actions = [
|
|
11
|
-
("~.Goto floor( Dest floor: ^new dest )",
|
|
12
|
-
Execution_Unit_a(
|
|
13
|
-
statement_set=Seq_Statement_Set_a(
|
|
14
|
-
input_tokens=[],
|
|
15
|
-
statement=Call_a(
|
|
16
|
-
call=None,
|
|
17
|
-
op_chain=Op_chain_a(
|
|
18
|
-
components=[
|
|
19
|
-
Scalar_op_a(
|
|
20
|
-
name=N_a(name='Goto floor'),
|
|
21
|
-
supplied_params=[
|
|
22
|
-
Supplied_Parameter_a(
|
|
23
|
-
pname='Dest floor',
|
|
24
|
-
sval=IN_a(name='new dest')
|
|
25
|
-
)
|
|
26
|
-
]
|
|
27
|
-
)
|
|
28
|
-
]
|
|
29
|
-
)
|
|
30
|
-
), block=None),
|
|
31
|
-
output_token=None)
|
|
32
|
-
),
|
|
33
|
-
]
|
|
34
|
-
|
|
35
|
-
@pytest.mark.parametrize("text, expected", actions)
|
|
36
|
-
def test_signal_action(text, expected):
|
|
37
|
-
parse = ScrallParser.parse_text(scrall_text=text, debug=False)[0]
|
|
38
|
-
print(parse)
|
|
39
|
-
assert parse[0] == expected
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|