556 Checks whether the content in reader matches the given 557 type of block statement (e.g. DO..END DO, IF...END IF etc.) 559 :param type startcls: the class marking the beginning of the block 560 :param list subclasses: list of classes that can be children of \ 562 :param type endcls: the class marking the end of the block. 563 :param reader: content to check for match. 564 :type reader: str or instance of :py:class:`FortranReaderBase` 565 :param bool match_labels: whether or not the statement terminating \ 566 the block must have a label that matches the opening statement. \ 568 :param bool match_names: TBD 569 :param tuple match_name_classes: TBD 570 :param bool enable_do_label_construct_hook: TBD 571 :param bool enable_if_construct_hook: TBD 572 :param bool enable_where_construct_hook: TBD 573 :param bool strict_order: whether to enforce the order of the \ 575 :param bool strict_match_names: if start name present, end name \ 576 must exist and match. 578 :return: instance of startcls or None if no match is found 587 assert isinstance(reader, FortranReaderBase), repr(reader)
590 if startcls
is not None:
592 DynamicImport.add_comments_includes_directives(content, reader)
595 obj = startcls(reader)
602 for obj
in reversed(content):
603 obj.restore_reader(reader)
605 if startcls
in SYMBOL_TABLES.scoping_unit_classes:
610 table_name = str(obj.children[1])
611 SYMBOL_TABLES.enter_scope(table_name)
614 start_idx = len(content)
617 if hasattr(obj,
"get_start_label")
and enable_do_label_construct_hook:
618 start_label = obj.get_start_label()
620 start_name = obj.get_start_name()
623 classes = subclasses + [di.Comment, di.Include_Stmt]
626 getattr(di.C99Preprocessor, cls_name)
627 for cls_name
in di.C99Preprocessor.CPP_CLASS_NAMES
629 classes += cpp_classes
630 if endcls
is not None:
632 endcls_all = tuple([endcls] + endcls.subclasses[endcls.__name__])
640 while i < len(classes):
641 if enable_do_label_construct_hook:
644 obj = startcls(reader)
645 if obj
is not None and hasattr(obj,
"get_start_label"):
646 if start_label == obj.get_start_label():
649 obj.restore_reader(reader)
666 if match_names
and isinstance(obj, match_name_classes):
667 end_name = obj.get_end_name()
668 if end_name
and not start_name:
669 raise FortranSyntaxError(
671 f
"Name '{end_name}' has no corresponding starting name",
676 and end_name.lower() != start_name.lower()
678 raise FortranSyntaxError(
679 reader, f
"Expecting name '{start_name}', got '{end_name}'" 682 if endcls
is not None and isinstance(obj, endcls_all):
684 start_label, end_label = (
685 content[start_idx].get_start_label(),
686 content[-1].get_end_label(),
688 if start_label != end_label:
691 start_name, end_name = (
692 content[start_idx].get_start_name(),
693 content[-1].get_end_name(),
696 if end_name
and not start_name:
697 raise FortranSyntaxError(
699 f
"Name '{end_name}' has no corresponding starting name",
701 elif strict_match_names
and start_name
and not end_name:
702 raise FortranSyntaxError(
703 reader, f
"Expecting name '{start_name}' but none given" 708 and (start_name.lower() != end_name.lower())
710 raise FortranSyntaxError(
712 f
"Expecting name '{start_name}', got '{end_name}'",
720 if enable_if_construct_hook:
721 if isinstance(obj, di.Else_If_Stmt):
725 if isinstance(obj, (di.Else_Stmt, di.End_If_Stmt)):
727 enable_if_construct_hook =
False 728 if enable_where_construct_hook:
729 if isinstance(obj, di.Masked_Elsewhere_Stmt):
731 if isinstance(obj, (di.Elsewhere_Stmt, di.End_Where_Stmt)):
732 enable_where_construct_hook =
False 735 except FortranSyntaxError
as err:
737 if startcls
in SYMBOL_TABLES.scoping_unit_classes:
738 SYMBOL_TABLES.exit_scope()
740 SYMBOL_TABLES.remove(table_name)
743 if startcls
in SYMBOL_TABLES.scoping_unit_classes:
744 SYMBOL_TABLES.exit_scope()
746 if not had_match
or endcls
and not found_end:
749 if endcls
is not None:
750 if startcls
in SYMBOL_TABLES.scoping_unit_classes:
752 SYMBOL_TABLES.remove(table_name)
753 for obj
in reversed(content):
754 obj.restore_reader(reader)
765 if startcls
is not None and endcls
is not None:
767 start_stmt = content[start_idx]
768 end_stmt = content[-1]
770 isinstance(end_stmt, endcls_all)
771 and hasattr(end_stmt,
"get_name")
772 and hasattr(start_stmt,
"get_name")
774 if end_stmt.get_name()
is not None:
776 start_stmt.get_name().string.lower()
777 != end_stmt.get_name().string.lower()
779 end_stmt.item.reader.error(
780 "expected <%s-name> is %s but got %s. Ignoring." 782 end_stmt.get_type().lower(),
783 start_stmt.get_name(),