Beispiel #1
0
    def __init__(
        self,
        *args,
        allow_gaps=True,
        optional=False,
        ephemeral_name=None,
    ):
        """Deal with kwargs common to all grammars.

        Args:
            *args: Any number of elements which because the subjects
                of this grammar.
            allow_gaps (:obj:`bool`, optional): Does this instance of the
                grammar allow gaps between the elements it matches? This
                may be exhibited slightly differently in each grammar. See
                that grammar for details. Defaults `True`.
            optional (:obj:`bool`, optional): In the context of a sequence,
                is this grammar *optional*, i.e. can it be skipped if no
                match is found. Outside of a Sequence, this option does nothing.
                Defaults `False`.
            ephemeral_name (:obj:`str`, optional): If specified this allows
                the grammar to match anything, and create an EphemeralSegment
                with the given name in its place. The content of this grammar
                is passed to the segment, and will become the parse grammar
                for it. If used widely this is an excellent way of breaking
                up the parse process and also signposting the name of a given
                chunk of code that might be parsed separately.
        """
        # We provide a common interface for any grammar that allows positional elements.
        # If *any* for the elements are a string and not a grammar, then this is a shortcut
        # to the Ref.keyword grammar by default.
        if self.allow_keyword_string_refs:
            self._elements = []
            for elem in args:
                self._elements.append(self._resolve_ref(elem))
        else:
            self._elements = list(args)

        # Now we deal with the standard kwargs
        self.allow_gaps = allow_gaps
        self.optional = optional
        self.ephemeral_segment = None
        # Set up the ephemeral_segment if name is specified.
        if ephemeral_name:
            # Make the EphemeralSegment class. This is effectively syntactic sugar
            # to allow us to avoid specifying a EphemeralSegment directly in a dialect.

            # Copy self (*before* making the EphemeralSegment, but with everything else in place)
            parse_grammar = copy.copy(self)
            # Add the EphemeralSegment to self.
            self.ephemeral_segment = EphemeralSegment.make(
                match_grammar=None,
                # Pass in the copy without the EphemeralSegment
                parse_grammar=parse_grammar,
                name=ephemeral_name,
            )
def test__parser__core_ephemeral_segment(raw_seg_list):
    """Test the Mystical KeywordSegment."""
    # First make a keyword
    BarKeyword = StringParser("bar", KeywordSegment)

    ephemeral_segment = EphemeralSegment(
        segments=raw_seg_list[:1],
        pos_marker=None,
        parse_grammar=BarKeyword,
        name="foobar",
    )

    with RootParseContext(dialect=None) as ctx:
        # Parse it and make sure we don't get an EphemeralSegment back
        res = ephemeral_segment.parse(ctx)
        assert isinstance(res, tuple)
        elem = res[0]
        assert not isinstance(elem, EphemeralSegment)
        assert isinstance(elem, KeywordSegment)
def test__parser__core_ephemeral_segment(raw_seg_list):
    """Test the Mystical KeywordSegment."""
    # First make a keyword
    BarKeyword = StringParser("bar", KeywordSegment)

    ephemeral_segment = EphemeralSegment.make(match_grammar=BarKeyword,
                                              parse_grammar=BarKeyword,
                                              name="foobar")

    with RootParseContext(dialect=None) as ctx:
        # Test on a slice containing only the first element
        m = ephemeral_segment.match(raw_seg_list[:1], parse_context=ctx)
        assert m
        # Make sure that it matches as an instance of EphemeralSegment
        elem = m.matched_segments[0]
        assert isinstance(elem, ephemeral_segment)
        # Parse it and make sure we don't get an EphemeralSegment back
        res = elem.parse(ctx)
        assert isinstance(res, tuple)
        elem = res[0]
        assert not isinstance(elem, ephemeral_segment)
        assert isinstance(elem, KeywordSegment)