def visitAttribute(self, ctx): # attribute : cardinality? reverseFlag? attributeOperator? attributeName # ( expressionComparisonOperator expressionConstraintValue # | numericComparisonOperator numericValue # | stringComparisonOperator stringValue ) # ; # # attributeOperatorValue ::= # attrib expr⟨⟨expressionComparisonOperator × expressionConstraintValue⟩⟩ | # attrib num⟨⟨numericComparisonOperator × numericValue⟩⟩ | # attrib str⟨⟨stringComparisonOperator × stringValue⟩⟩ numericValue ::= nv decimal⟨⟨decimalValue⟩⟩ | nv integer⟨⟨N⟩⟩ v = self._child_visitor(self, ctx) card = v.getNext(lambda e: cardinality.has_member(e)) rf = v.getNext(lambda e: e == reverseFlag) # TODO: fix type checking for Seq and Set -- this is too loose attOper = v.getNext(lambda e: attributeOperator.has_member(e)) name = v.getNext() op = v.getNext() targ = v.getNext() cp = CrossProduct()(op, targ) opValue = attributeOperatorValue(attrib_expr=cp) if expressionComparisonOperator.has_member(op) else \ attributeOperatorValue(attrib_num=cp) if numericComparisonOperator.has_member(op) else \ attributeOperatorValue(attrib_str=cp) arf = Optional(reverseFlags)(rf) acard = Optional(cardinality)(card) aattrOper = Optional(attributeOperator)(attOper) return attribute(card=Optional(cardinality)(card), rf=Optional(reverseFlags)(rf), attrOper=Optional(attributeOperator)(attOper), name=name, opValue=opValue)
def visitAttributeGroup(self, ctx): # attributeGroup == cardinality [0 . . 1] × attributeSet v = self._child_visitor(self, ctx) card = v.getNext(lambda e: cardinality.has_member(e)) v.getNext() # open braces attset = v.getNext() v.getNext() # close braces return attributeGroup(Optional(cardinality)(card), attset)