123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- from lark import Lark, logger
- from concrete_syntax.common import _Code, TBase
- from uuid import UUID
- from services.scd import SCD
- from services.od import OD
- grammar = r"""
- %import common.WS
- %ignore WS
- %ignore COMMENT
- ?start: (class_ | association | global_constraint)*
- IDENTIFIER: /[A-Za-z_][A-Za-z_0-9]*/
- COMMENT: /#[^\n]*\n/
- literal: INT
- | STR
- | BOOL
- | CODE
- | INDENTED_CODE
- INT: /[0-9]+/
- STR: /"[^"]*"/
- | /'[^']*'/
- BOOL: "True" | "False"
- CODE: /`[^`]*`/
- INDENTED_CODE: /```[^`]*```/
- INT_OR_INF: INT | "*"
- multiplicity: "[" INT ".." INT_OR_INF "]"
- ABSTRACT: "abstract"
- superclasses: IDENTIFIER ("," IDENTIFIER)*
- attrs: attr*
- constraint: CODE | INDENTED_CODE
- class_: [ABSTRACT] "class" IDENTIFIER [multiplicity] ["(" superclasses ")"] ["{" attrs [constraint] "}"]
- association: "association" IDENTIFIER [multiplicity] IDENTIFIER "->" IDENTIFIER [multiplicity] ["{" attrs [constraint] "}"]
- OPTIONAL: "optional"
- attr: [OPTIONAL] IDENTIFIER IDENTIFIER [constraint] ";"
- global_constraint: "global" IDENTIFIER constraint
- """
- parser = Lark(grammar, parser='lalr')
- def _handle_missing_multiplicity(multiplicity):
- if multiplicity != None:
- return multiplicity
- else:
- return (None, None)
- def parse_cd(state, m_text):
- type_model_id = state.read_dict(state.read_root(), "SCD")
- scd_mmm = UUID(state.read_value(type_model_id))
- m = state.create_node()
- cd = SCD(m, state)
- od = OD(scd_mmm, m, state)
- def _add_constraint_to_obj(obj_name, constraint):
- constraint_name = f"{obj_name}.constraint"
- od.create_actioncode_value(constraint_name, constraint.code)
- od.create_slot("constraint", obj_name, constraint_name)
- primitive_types = {
- type_name : UUID(state.read_value(state.read_dict(state.read_root(), type_name)))
- for type_name in ["Integer", "String", "Boolean"]
- }
- class T(TBase):
- def __init__(self, visit_tokens):
- super().__init__(visit_tokens)
- self.obj_counter = 0
- def ABSTRACT(self, el):
- return True
- def INT_OR_INF(self, el):
- # infinity only used for upper cardinality,
- # where the default value (None) represents infinity
- # cannot use `float('inf')` because then it violates the constraint of type 'Integer'
- return None if el == "*" else int(el)
- def multiplicity(self, el):
- [lower, upper] = el
- return (lower, upper)
- def superclasses(self, el):
- return list(el)
- def attrs(self, el):
- return list(el)
- def constraint(self, el):
- return el[0]
- def attr(self, el):
- [optional, attr_type, attr_name, constraint] = el
- return (optional == "optional", attr_type, attr_name, constraint)
- def global_constraint(self, el):
- [name, constraint] = el
- od.create_object(name, "GlobalConstraint")
- _add_constraint_to_obj(name, constraint)
- def process_attrs(self, attrs, class_name):
- if attrs != None:
- for attr in attrs:
- (optional, attr_type, attr_name, constraint) = attr
- if state.read_dict(m, attr_type) == None:
- cd.create_model_ref(attr_type, primitive_types[attr_type])
- cd.create_attribute_link(class_name, attr_type, attr_name, optional)
- if constraint != None:
- _add_constraint_to_obj(f"{class_name}_{attr_name}", constraint)
- def class_(self, el):
- [abstract, class_name, multiplicity, super_classes, attrs, constraint] = el
- (lower, upper) = _handle_missing_multiplicity(multiplicity)
- cd.create_class(class_name, abstract, lower, upper)
- if super_classes != None:
- for super_class in super_classes:
- cd.create_inheritance(class_name, super_class)
- if constraint != None:
- _add_constraint_to_obj(class_name, constraint)
- self.process_attrs(attrs, class_name)
- def association(self, el):
- [assoc_name, src_multiplicity, src_name, tgt_name, tgt_multiplicity, attrs, constraint] = el
- (src_lower, src_upper) = _handle_missing_multiplicity(src_multiplicity)
- (tgt_lower, tgt_upper) = _handle_missing_multiplicity(tgt_multiplicity)
- cd.create_association(assoc_name, src_name, tgt_name, src_lower, src_upper, tgt_lower, tgt_upper)
- if constraint != None:
- _add_constraint_to_obj(assoc_name, constraint)
- self.process_attrs(attrs, assoc_name)
- tree = parser.parse(m_text)
- t = T(visit_tokens=True).transform(tree)
- return m
|