def term(): return Optional(["+", "-"]), OrderedChoice([(ZeroOrMore([gennum]), Optional(['*']), varname), gennum])
def condition() -> GrammarType: return if_condition, ZeroOrMore(elif_condition), Optional(else_condition)
def control_structure_body_stub_braces() -> GrammarType: return ZeroOrMore(RegExMatch('[^{}]*{[^{}]*'), ZeroOrMore(control_structure_body_stub_inner, Optional(RegExMatch('[^{}]*'))), close_brace, control_structure_potential_closing_brace)
def array_element() -> GrammarType: return '[', Optional(expression), ']'
def local_variable_declaration() -> GrammarType: return Optional('static'), variable_declaration_assignable
def factor(): return Optional(["+", "-"]), [number, ("(", expression, ")")]
def expression() -> GrammarType: return [operator_sequence, value, parenthesised_expression], Optional(operator, expression)
def decl(): return identifier, Optional("=", expr)
def assignment_rhs(): return [simple_match, reference], Optional(repeat_modifiers)
def if_expression(): return expr, brace_block, Optional("else", brace_block)
def integer(): return Optional('-'), [RegExMatch('\d*\.\d'), RegExMatch('\d+')]
def reference_stm(): return ('reference', language_name, Optional(language_alias))
def obj_ref(): return '[', class_name, Optional('|', obj_ref_rule, Optional('|', rrel_expression)), ']'
def constr(): return varname, ':', expr, compare, expr, Optional(compare, expr), ';'
def grammar(): return OneOrMore((Optional(until_block_maybe), [(block_start, [ (block_freeform, block_freeform_interior, block_freeform_end), (block_tabular, block_interior, block_end) ]), (ref_insert_start, ref_insert_middle, ref_insert_end)], anyws))
def obj_ref(): return '[', class_name, Optional('|', obj_ref_rule), ']'
def sufix(): return expression, Optional(OPTIONAL)
def textx_rule(): return rule_name, Optional(rule_params), ":", textx_rule_body, ";"
def heap_alloc() -> GrammarType: return 'new', compound_identifier, Optional(function_args)
def rule_param(): return param_name, Optional('=', string_value)
def operation_assignment() -> GrammarType: return Optional([mathematical_operator, bitwise_operator]), assignment
def repeatable_expr(): return expression, Optional(repeat_operator), Optional('-')
def variable_declaration_assignable() -> GrammarType: return variable_declaration, Optional([assignment, function_args])
def expression(): return [ assignment, (Optional(syntactic_predicate), [simple_match, rule_ref, bracketed_choice]) ]
def variable_assignment() -> GrammarType: return [referenced_value, compound_identifier], Optional(array_access), operation_assignment
def visit_assignment(self, node, children): """ Create parser rule for assignments and register attribute types on metaclass. """ attr_name = children[0] op = children[1] rhs_rule, modifiers = children[2] cls = self._current_cls target_cls = None if self.debug: self.dprint("Processing assignment {}{}...".format(attr_name, op)) if self.debug: self.dprint("Creating attribute {}:{}".format( cls.__name__, attr_name)) self.dprint("Assignment operation = {}".format(op)) if attr_name in cls._tx_attrs: # If attribute already exists in the metamodel it is # multiple assignment to the same attribute. # Cannot use operator ?= on multiple assignments if op == '?=': line, col = self.grammar_parser.pos_to_linecol(node.position) raise TextXSemanticError( 'Cannot use "?=" operator on multiple' ' assignments for attribute "{}" at {}'.format( attr_name, (line, col)), line, col) cls_attr = cls._tx_attrs[attr_name] else: cls_attr = self.metamodel._new_cls_attr(cls, name=attr_name, position=node.position) # Keep track of metaclass references and containments if type(rhs_rule) is tuple and rhs_rule[0] == "obj_ref": cls_attr.cont = False cls_attr.ref = True # Override rhs by its PEG rule for further processing rhs_rule = rhs_rule[1] # Target class is not the same as target rule target_cls = rhs_rule.cls base_rule_name = rhs_rule.rule_name if op == '+=': assignment_rule = OneOrMore(nodes=[rhs_rule], rule_name='__asgn_oneormore', root=True) cls_attr.mult = MULT_ONEORMORE elif op == '*=': assignment_rule = ZeroOrMore(nodes=[rhs_rule], rule_name='__asgn_zeroormore', root=True) if cls_attr.mult is not MULT_ONEORMORE: cls_attr.mult = MULT_ZEROORMORE elif op == '?=': assignment_rule = Optional(nodes=[rhs_rule], rule_name='__asgn_optional', root=True) cls_attr.mult = MULT_OPTIONAL base_rule_name = 'BOOL' # ?= assigment should have default value of False. # so we shall mark it as such. cls_attr.bool_assignment = True else: assignment_rule = Sequence(nodes=[rhs_rule], rule_name='__asgn_plain', root=True) # Modifiers if modifiers: modifiers, position = modifiers # Sanity check. Modifiers do not make # sense for ?= and = operator at the moment. if op == '?=' or op == '=': line, col = self.grammar_parser.pos_to_linecol(position) raise TextXSyntaxError( 'Modifiers are not allowed for "{}" operator at {}'.format( op, text((line, col))), line, col) # Separator modifier assignment_rule.sep = modifiers.get('sep', None) # End of line termination modifier if 'eolterm' in modifiers: assignment_rule.eolterm = True if target_cls: attr_type = target_cls else: # Use STRING as default attr class attr_type = base_rule_name if base_rule_name else 'STRING' if not cls_attr.cls: cls_attr.cls = ClassCrossRef(cls_name=attr_type, position=node.position) else: # cls cross ref might already be set in case of multiple assignment # to the same attribute. If types are not the same we shall use # OBJECT as generic type. if cls_attr.cls.cls_name != attr_type: cls_attr.cls.cls_name = 'OBJECT' if self.debug: self.dprint("Created attribute {}:{}[cls={}, cont={}, " "ref={}, mult={}, pos={}]".format( cls.__name__, attr_name, cls_attr.cls.cls_name, cls_attr.cont, cls_attr.ref, cls_attr.mult, cls_attr.position)) assignment_rule._attr_name = attr_name assignment_rule._exp_str = attr_name # For nice error reporting return assignment_rule
def switch_case_body() -> GrammarType: return OneOrMore(instruction), Optional('fallthrough')
def repeat_operator(): return ['*', '?', '+', '#'], Optional(repeat_modifiers)
def trailing_comma() -> GrammarType: return Optional(',')
def mknorange(): return [ (mkclass, spacer, '(', numeric, ')'), (mkclass, Optional(spacer, numeric))]