code: def match_abstract_str(cls):
      
      def r(s):
          if s.root:
              if s in visited or s.rule_name in ALL_TYPE_NAMES or \
                      (hasattr(s, '_tx_class') and
                       s._tx_class._tx_type is not RULE_MATCH):
                  return s.rule_name
  
          visited.add(s)
          if isinstance(s, Match):
              result = text(s)
          elif isinstance(s, OrderedChoice):
              result = "|".join([r(x) for x in s.nodes])
          elif isinstance(s, Sequence):
              result = " ".join([r(x) for x in s.nodes])
          elif isinstance(s, ZeroOrMore):
              result = "({})*".format(r(s.nodes[0]))
          elif isinstance(s, OneOrMore):
              result = "({})+".format(r(s.nodes[0]))
          elif isinstance(s, Optional):
              result = "{}?".format(r(s.nodes[0]))
          elif isinstance(s, SyntaxPredicate):
              result = ""
          return "{}{}".format(result, "-" if s.suppress else "")
  
      mstr = ""
      if cls.__name__ not in ALL_TYPE_NAMES and \
              not (cls._tx_type is RULE_ABSTRACT and
                   cls.__name__ != cls._tx_peg_rule.rule_name):
          e = cls._tx_peg_rule
          visited = set()
          if not isinstance(e, Match):
              visited.add(e)
          if isinstance(e, OrderedChoice):
              mstr = "|".join([r(x) for x in e.nodes
                               if x.rule_name in BASE_TYPE_NAMES or not x.root])
          elif isinstance(e, Sequence):
              mstr = " ".join([r(x) for x in e.nodes])
          else:
              mstr = r(e)
  
          mstr = dot_escape(mstr)
  
      return mstr
docs: For a given abstract or match rule meta-class returns a nice string
      representation for the body.