Skip to content

Commit d567959

Browse files
committed
Improvements in the aggregates support and Part21 importer as well
1 parent 117ba39 commit d567959

7 files changed

Lines changed: 137 additions & 142 deletions

File tree

src/fedex_python/python/SCL/AggregationDataTypes.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ def __init__( self , bound_1 , bound_2 , base_type , UNIQUE = False, OPTIONAL=F
9595
list_size = bound_2 - bound_1 + 1
9696
self._container = list_size*[None]
9797

98+
def bound_1(self):
99+
return self._bound_1
100+
101+
def bound_2(self):
102+
return self._bound_2
103+
98104
def __getitem__(self, index):
99105
if index<self._bound_1:
100106
raise IndexError("ARRAY index out of bound (lower bound is %i, passed %i)"%(self._bound_1,index))
@@ -122,7 +128,7 @@ def __setitem__(self, index, value):
122128

123129
class LIST(list, BaseAggregate):
124130
"""A list data type has as its domain sequences of like elements. The optional lower and upper
125-
bounds, which are integer-valued expressions, dfine the minimum and maximum number of
131+
bounds, which are integer-valued expressions, define the minimum and maximum number of
126132
elements that can be held in the collection defined by a list data type.
127133
A list data type
128134
definition may optionally specify that a list value cannot contain duplicate elements.

src/fedex_python/python/SCL/Part21.py

Lines changed: 14 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3131

3232
import re
33+
import Utils
3334

3435
INSTANCE_DEFINITION_RE = re.compile("#(\d+)[^\S\n]?=[^\S\n]?(.*?)\((.*)\)[^\S\n]?;[\\r]?$")
3536

@@ -119,32 +120,6 @@ def get_schema_name(self):
119120
def get_number_of_instances(self):
120121
return len(self._instances_definition.keys())
121122

122-
def parse_attributes(self, attr_str):
123-
"""
124-
This method takes a string an returns a list of attributes (but without any mapping).
125-
For instance:
126-
input = "'',(#11,#15,#19,#23,#27),#31"
127-
output = ['',(#11,#15,#19,#23,#27),'#31']
128-
"""
129-
aggr_scope_level = 0
130-
attrs = []
131-
current_attr = ''
132-
previous_ch = ''
133-
for ch in attr_str:
134-
if ch == ',' and aggr_scope_level == 0:
135-
attrs.append(current_attr)
136-
current_attr = ''
137-
else:
138-
if ch == '(':
139-
aggr_scope_level +=1
140-
elif ch == ')':
141-
aggr_scope_level -= 1
142-
current_attr += ch
143-
previous_ch = ch
144-
# finally add the last attr when exiting loop
145-
attrs.append(current_attr)
146-
return attrs
147-
148123
def parse_file(self):
149124
init_time = time.time()
150125
print "Parsing file %s..."%self._filename,
@@ -155,8 +130,8 @@ def parse_file(self):
155130
break
156131
# there may be a multline definition. In this case, we read lines untill we found
157132
# a ;
158-
while (not line.endswith(";\r\n")): #its a multiline
159-
line = line.replace("\r\n","") + fp.readline()
133+
#while (not line.endswith(";\r\n")): #its a multiline
134+
# line = line.replace("\r\n","") + fp.readline()
160135
# parse line
161136
match_instance_definition = INSTANCE_DEFINITION_RE.search(line) # id,name,attrs
162137
if match_instance_definition:
@@ -167,7 +142,7 @@ def parse_file(self):
167142
# fill number of ancestors dict
168143
self._number_of_ancestors[number_of_ancestors].append(instance_int_id)
169144
# parse attributes string
170-
entity_attrs_list = self.parse_attributes(entity_attrs)
145+
entity_attrs_list, str_len = Utils.process_nested_parent_str(entity_attrs)
171146
# then finally append this instance to the disct instance
172147
self._instances_definition[instance_int_id] = (entity_name,entity_attrs_list)
173148
else: #does not match with entity instance definition, parse the header
@@ -185,21 +160,23 @@ class EntityInstancesFactory(object):
185160
20: ('CARTESIAN_POINT', ["''", '(5.,125.,20.)'])
186161
will result in:
187162
p = ARRAY(1,3,REAL)
188-
p.[1]=REAL(5)
163+
p.[1] = REAL(5)
189164
p.[2] = REAL(125)
190165
p.[3] = REAL(20)
191166
new_instance = cartesian_point(STRING(''),p)
192167
'''
193168
def __init__(self, schema_name, instance_definition):
194169
# First try to import the schema module
195170
pass
171+
196172
class Part21Population(object):
197173
def __init__(self, part21_loader):
198174
""" Take a part21_loader a tries to create entities
199175
"""
200176
self._part21_loader = part21_loader
201177
self._aggregate_scope = []
202178
self._aggr_scope = False
179+
self.create_entity_instances()
203180

204181
def create_entity_instances(self):
205182
""" Starts entity instances creation
@@ -210,63 +187,21 @@ def create_entity_instances(self):
210187

211188
def create_entity_instance(self, instance_id):
212189
instance_definition = self._part21_loader._instances_definition[instance_id]
190+
print "Instance definition to process",instance_definition
213191
# first find class name
214192
class_name = instance_definition[0].lower()
193+
print "Class name:%s"%class_name
215194
object_ = globals()[class_name]
216195
# then attributes
217196
#print object_.__doc__
218197
instance_attributes = instance_definition[1]
219-
#print instance_attributes
220-
# find attributes
221-
attributes = instance_attributes.split(",")
222-
instance_attributes = []
223-
#print attributes
224-
for attr in attributes:
225-
if attr[0]=="(":#new aggregate_scope
226-
#print "new aggregate scope"
227-
self._aggr_scope = True
228-
at = self.map_express_to_python(attr[1:])
229-
#self._aggregate_scope.append(at)
230-
elif attr[-1]==")":
231-
#print "end aggregate scope"
232-
at = self.map_express_to_python(attr[:-1])
233-
self._aggregate_scope.append(at)
234-
self._aggr_scope = False
235-
else:
236-
at = self.map_express_to_python(attr)
237-
if self._aggr_scope:
238-
self._aggregate_scope.append(at)
239-
if len(self._aggregate_scope)>0 and not self._aggr_scope:
240-
instance_attributes.append(self._aggregate_scope)
241-
self._aggregate_scope = []
242-
elif len(self._aggregate_scope)>0 and self._aggr_scope:
243-
pass
244-
else:
245-
instance_attributes.append(at)
198+
print "instance_attributes:",instance_attributes
246199
a = object_(*instance_attributes)
247200

248-
249-
def map_express_to_python(self,attr):
250-
""" Map EXPRESS to python"""
251-
if attr in ["$","''"]: #optional argument
252-
return None
253-
elif attr.startswith('#'): #entity_id
254-
return attr[1:]
255-
else:
256-
return map_string_to_num(attr)
257-
258201
if __name__ == "__main__":
259202
import time
260203
import sys
261-
#sys.path.append("..")
262-
#from config_control_design import *
263-
#p21loader = Part21Loader("as1-oc-214.stp")
264-
#file = Part21Loader("as1-tu-203.stp")
265-
#file = Part21Loader("HAYON.stp")
266-
p21loader = Part21Parser("as1.stp")
267-
print p21loader._instances_definition
268-
#print "Creating instances"
269-
#p21population = Part21Population(p21loader)
270-
#p21population.create_entity_instances()
271-
#t2 = time.time()
272-
#print "Creating instances took: %s s \n" % ((t2-t1))
204+
from config_control_design import *
205+
p21loader = Part21Parser("gasket1.p21")
206+
print "Creating instances"
207+
p21population = Part21Population(p21loader)

src/fedex_python/python/SCL/TypeChecker.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@
3131

3232
from ConstructedDataTypes import ENUMERATION, SELECT
3333

34+
RAISE_EXCEPTION_IF_TYPE_DOES_NOT_MATCH = False
35+
36+
def cast_python_list_to_aggregate(lst, aggregate):
37+
""" This function casts a python list to an aggregate type. For instance:
38+
[1.,2.,3.]-> ARRAY(1,3,REAL)"""
39+
aggregate_lower_bound = aggregate.bound_1()
40+
aggregate_upper_bound = aggregate.bound_2()
41+
for idx in range(aggregate_lower_bound,aggregate_upper_bound+1):
42+
aggregate[idx] = lst[idx-aggregate_lower_bound]
43+
return aggregate
44+
3445
def check_type(instance, expected_type):
3546
""" This function checks wether an object is an instance of a given class
3647
returns False or True
@@ -46,8 +57,10 @@ def check_type(instance, expected_type):
4657
else:
4758
type_match = isinstance(instance,expected_type)
4859
if not type_match:
49-
raise TypeError('Type of argument number_of_sides must be %s (you passed %s)'%(expected_type,type(instance)))
60+
if RAISE_EXCEPTION_IF_TYPE_DOES_NOT_MATCH:
61+
raise TypeError('Type of argument number_of_sides must be %s (you passed %s)'%(expected_type,type(instance)))
62+
else:
63+
print "WARNING: expected '%s' but passed a '%s', casting from python value to EXPRESS type"%(expected_type, type(instance))
64+
return False
5065
else:
5166
return True
52-
53-

src/fedex_python/python/SCL/as1.stp

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/fedex_python/python/SCL/essa_par.py

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,36 +19,56 @@ def process_nested_parent_str(attr_str):
1919
current_param += ch
2020
return params
2121

22-
idx = 0
23-
def process_nested_parent_str2(attr_str):
22+
def process_nested_parent_str2(attr_str,idx=0):
2423
'''
2524
The first letter should be a parenthesis
2625
input string: "(1,4,(5,6),7)"
2726
output: ['1','4',['5','6'],'7']
2827
'''
29-
global idx
30-
acc=0
31-
print 'Entering function with string %s and index %i'%(attr_str,idx)
28+
#print 'Entering function with string %s'%(attr_str)
3229
params = []
3330
current_param = ''
34-
for i,ch in enumerate(attr_str):
35-
idx += 1
36-
acc +=1
31+
k = 0
32+
while (k<len(attr_str)):
33+
#print 'k in this function:%i'%k
34+
ch = attr_str[k]
35+
k += 1
3736
if ch==',':
37+
#print "Add param:",current_param
3838
params.append(current_param)
3939
current_param = ''
4040
elif ch=='(':
41-
nv = attr_str[idx:]
42-
print "params",params
43-
print "Str passed to the function:%s (idx=%i)"%(nv,idx)
44-
current_param = process_nested_parent_str2(nv)
41+
nv = attr_str[k:]
42+
#print "Up one level parenthesis:%s"%(nv)
43+
current_param, progress = process_nested_parent_str2(nv)
44+
#print "Adding the list returned from nested",current_param
45+
params.append(current_param)
46+
current_param = ''
47+
k += progress+1
4548
elif ch==')':
49+
#print "Down one level parenthesis: %i caracters parsed"%k
4650
params.append(current_param)
47-
idx -= acc+1
48-
return params
51+
#print "Current params:",params#k -= acc-2
52+
return params,k
4953
else:
5054
current_param += ch
55+
#print "Ch:",ch
56+
#print "k:",k
57+
58+
#raw_input("")
59+
#idx += 1
60+
5161
params.append(current_param)
52-
return params
62+
return params,k
5363
#print process_nested_parent_str2('1,2,3,4,5,6')
54-
print process_nested_parent_str2("'A','B',('C','D'),'E'")
64+
#idx=0
65+
#print process_nested_parent_str2("'A','B','C'")
66+
print process_nested_parent_str2("'A'")[0]
67+
print process_nested_parent_str2("30.0,0.0,5.0")[0]
68+
print process_nested_parent_str2("(Thomas)")[0]
69+
print process_nested_parent_str2("Thomas, Paviot, ouais")[0]
70+
print process_nested_parent_str2("1,2,(3,4,5),6,7,8")[0]
71+
print process_nested_parent_str2("(#9149,#9166),#9142,.T.")[0]
72+
73+
74+

src/fedex_python/python/SCL_unittest.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,14 @@ class P:
243243

244244
def test_check_enum_type(self):
245245
enum = ENUMERATION(["my","string"])
246-
246+
247+
#
248+
# Cast from list to aggregates
249+
#
250+
class CastTypeChecker(unittest.TestCase):
251+
def test_cast_list_to_array(self):
252+
a = [1.,2.,3.]
253+
b = cast_python_list_to_aggregate(a,ARRAY(1,3,REAL))
254+
247255
unittest.main()
248256

0 commit comments

Comments
 (0)