Best Python code snippet using avocado_python
first_and_follow.py
Source:first_and_follow.py  
...21        def __compute_first__(nt: Nonterminal):22            if nt in computed_already:23                return24            nt_first = set()25            for pr in self.__grammar.get_production_rules_by_lhs_nonterminal(nt):26                for symbol in pr.rhs:27                    if isinstance(symbol, Epsilon) or isinstance(symbol, Terminal):28                        nt_first.add(symbol)29                        break30                    elif isinstance(symbol, Nonterminal) and symbol != nt:31                        if symbol not in computed_already:32                            __compute_first__(symbol)33                        s_first = self.get_first_of_nonterminal(symbol).copy()34                        if epsilon not in s_first:35                            nt_first = nt_first.union(s_first)36                            break37                        else:38                            s_first.remove(epsilon)39                            nt_first = nt_first.union(s_first)40                            if symbol == pr.rhs[-1]:41                                if pr.lhs not in computed_already and pr.lhs != nt:42                                    __compute_first__(pr.lhs)43                                lhs_first = self.get_first_of_nonterminal(pr.lhs).copy()44                                if len(lhs_first) == 0:45                                    nt_first.add(Epsilon())46                                else:47                                    nt_first = nt_first.union(lhs_first)48            computed_already.add(nt)49            self.__first[nt] = nt_first50        epsilon = Epsilon()51        computed_already = set()52        for nonterminal in self.__grammar.nonterminals:53            __compute_first__(nonterminal)54    def __compute_follow(self):55        def __split_rhs_by_duplicate_nonterminal__(pr: ProductionRule, nt: Nonterminal):56            counter = 057            for s in pr.rhs:58                if s == nt:59                    counter += 160            if counter == 1:61                return [pr]62            prs = []63            rhs = []64            for i in range(len(pr.rhs) - 1, -1, -1):65                rhs.insert(0, pr.rhs[i])66                if pr.rhs[i] == nt:67                    prs.append(ProductionRule(pr.lhs, rhs[:]))68            return prs69        def __compute_follow__(nt: Nonterminal):70            if nt in computed_already:71                return72            nt_follow = self.get_follow_of_nonterminal(nt)  # $ is added beforehand73            for pr in self.__grammar.get_production_rules_by_rhs_nonterminal(nt):74                for __pr__ in __split_rhs_by_duplicate_nonterminal__(pr, nt):75                    found_nt = False76                    rhs = []77                    for symbol in __pr__.rhs:78                        if found_nt:79                            rhs.append(symbol)80                        if symbol == nt:81                            found_nt = True82                    check_lhs = True83                    for symbol in rhs:84                        if isinstance(symbol, Terminal):85                            nt_follow.add(symbol)86                            check_lhs = False87                            break88                        elif isinstance(symbol, Nonterminal):89                            s_first = self.get_first_of_nonterminal(symbol).copy()90                            if epsilon not in s_first:91                                nt_follow = nt_follow.union(s_first)92                                if symbol != rhs[-1]:93                                    check_lhs = False94                                    break95                            else:96                                s_first.remove(epsilon)97                                nt_follow = nt_follow.union(s_first)98                                check_lhs = True99                    if check_lhs:100                        if __pr__.lhs not in computed_already and __pr__.lhs != nt:101                            __compute_follow__(__pr__.lhs)102                        lhs_follow = self.get_follow_of_nonterminal(__pr__.lhs).copy()103                        nt_follow = nt_follow.union(lhs_follow)104            computed_already.add(nt)105            self.__follow[nt] = nt_follow106        epsilon = Epsilon()107        computed_already = set()108        self.__follow[self.__grammar.start_symbol] = {Dollar()}109        for nonterminal in self.__grammar.nonterminals:110            __compute_follow__(nonterminal)111    # region Getters112    @property113    def first(self) -> Dict[Nonterminal, Set[Symbol]]:114        return self.__first115    @property116    def follow(self) -> Dict[Nonterminal, Set[Symbol]]:117        return self.__follow118    # endregion119    def __repr__(self):120        newline = '\n'121        return f"=== First ===\n{newline.join([repr(entry) for entry in self.__first.items()])}\n\n" \122               f"=== Follow ===\n{newline.join([repr(entry) for entry in self.__follow.items()])} "123    def __str__(self):124        return repr(self)125    def get_first_of_nonterminal(self, nonterminal: Nonterminal) -> Set[Symbol]:126        if nonterminal in self.__first:127            return self.__first[nonterminal]128        return set()129    def get_follow_of_nonterminal(self, nonterminal: Nonterminal) -> Set[Symbol]:130        if nonterminal in self.__follow:131            return self.__follow[nonterminal]132        return set()133@pytest.mark.parametrize(134    "grammar,first,follow",135    [136        (137                Grammar(138                    [139                        Nonterminal('S'),140                        Nonterminal('B'),141                        Nonterminal('D'),142                        Nonterminal('C'),143                        Nonterminal('E'),...generator.py
Source:generator.py  
1# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.2# Licensed to PSF under a Contributor Agreement.3# Modifications:4# Copyright David Halter and Contributors5# Modifications are dual-licensed: MIT and PSF.6"""7This module defines the data structures used to represent a grammar.8Specifying grammars in pgen is possible with this grammar::9    grammar: (NEWLINE | rule)* ENDMARKER10    rule: NAME ':' rhs NEWLINE11    rhs: items ('|' items)*12    items: item+13    item: '[' rhs ']' | atom ['+' | '*']14    atom: '(' rhs ')' | NAME | STRING15This grammar is self-referencing.16This parser generator (pgen2) was created by Guido Rossum and used for lib2to3.17Most of the code has been refactored to make it more Pythonic. Since this was a18"copy" of the CPython Parser parser "pgen", there was some work needed to make19it more readable. It should also be slightly faster than the original pgen2,20because we made some optimizations.21"""22from ast import literal_eval23from typing import TypeVar, Generic, Mapping, Sequence, Set, Union24from parso.pgen2.grammar_parser import GrammarParser, NFAState25_TokenTypeT = TypeVar("_TokenTypeT")26class Grammar(Generic[_TokenTypeT]):27    """28    Once initialized, this class supplies the grammar tables for the29    parsing engine implemented by parse.py.  The parsing engine30    accesses the instance variables directly.31    The only important part in this parsers are dfas and transitions between32    dfas.33    """34    def __init__(self,35                 start_nonterminal: str,36                 rule_to_dfas: Mapping[str, Sequence['DFAState[_TokenTypeT]']],37                 reserved_syntax_strings: Mapping[str, 'ReservedString']):38        self.nonterminal_to_dfas = rule_to_dfas39        self.reserved_syntax_strings = reserved_syntax_strings40        self.start_nonterminal = start_nonterminal41class DFAPlan:42    """43    Plans are used for the parser to create stack nodes and do the proper44    DFA state transitions.45    """46    def __init__(self, next_dfa: 'DFAState', dfa_pushes: Sequence['DFAState'] = []):47        self.next_dfa = next_dfa48        self.dfa_pushes = dfa_pushes49    def __repr__(self):50        return '%s(%s, %s)' % (self.__class__.__name__, self.next_dfa, self.dfa_pushes)51class DFAState(Generic[_TokenTypeT]):52    """53    The DFAState object is the core class for pretty much anything. DFAState54    are the vertices of an ordered graph while arcs and transitions are the55    edges.56    Arcs are the initial edges, where most DFAStates are not connected and57    transitions are then calculated to connect the DFA state machines that have58    different nonterminals.59    """60    def __init__(self, from_rule: str, nfa_set: Set[NFAState], final: NFAState):61        assert isinstance(nfa_set, set)62        assert isinstance(next(iter(nfa_set)), NFAState)63        assert isinstance(final, NFAState)64        self.from_rule = from_rule65        self.nfa_set = nfa_set66        # map from terminals/nonterminals to DFAState67        self.arcs: Mapping[str, DFAState] = {}68        # In an intermediary step we set these nonterminal arcs (which has the69        # same structure as arcs). These don't contain terminals anymore.70        self.nonterminal_arcs: Mapping[str, DFAState] = {}71        # Transitions are basically the only thing that  the parser is using72        # with is_final. Everyting else is purely here to create a parser.73        self.transitions: Mapping[Union[_TokenTypeT, ReservedString], DFAPlan] = {}74        self.is_final = final in nfa_set75    def add_arc(self, next_, label):76        assert isinstance(label, str)77        assert label not in self.arcs78        assert isinstance(next_, DFAState)79        self.arcs[label] = next_80    def unifystate(self, old, new):81        for label, next_ in self.arcs.items():82            if next_ is old:83                self.arcs[label] = new84    def __eq__(self, other):85        # Equality test -- ignore the nfa_set instance variable86        assert isinstance(other, DFAState)87        if self.is_final != other.is_final:88            return False89        # Can't just return self.arcs == other.arcs, because that90        # would invoke this method recursively, with cycles...91        if len(self.arcs) != len(other.arcs):92            return False93        for label, next_ in self.arcs.items():94            if next_ is not other.arcs.get(label):95                return False96        return True97    def __repr__(self):98        return '<%s: %s is_final=%s>' % (99            self.__class__.__name__, self.from_rule, self.is_final100        )101class ReservedString:102    """103    Most grammars will have certain keywords and operators that are mentioned104    in the grammar as strings (e.g. "if") and not token types (e.g. NUMBER).105    This class basically is the former.106    """107    def __init__(self, value: str):108        self.value = value109    def __repr__(self):110        return '%s(%s)' % (self.__class__.__name__, self.value)111def _simplify_dfas(dfas):112    """113    This is not theoretically optimal, but works well enough.114    Algorithm: repeatedly look for two states that have the same115    set of arcs (same labels pointing to the same nodes) and116    unify them, until things stop changing.117    dfas is a list of DFAState instances118    """119    changes = True120    while changes:121        changes = False122        for i, state_i in enumerate(dfas):123            for j in range(i + 1, len(dfas)):124                state_j = dfas[j]125                if state_i == state_j:126                    del dfas[j]127                    for state in dfas:128                        state.unifystate(state_j, state_i)129                    changes = True130                    break131def _make_dfas(start, finish):132    """133    Uses the powerset construction algorithm to create DFA states from sets of134    NFA states.135    Also does state reduction if some states are not needed.136    """137    # To turn an NFA into a DFA, we define the states of the DFA138    # to correspond to *sets* of states of the NFA.  Then do some139    # state reduction.140    assert isinstance(start, NFAState)141    assert isinstance(finish, NFAState)142    def addclosure(nfa_state, base_nfa_set):143        assert isinstance(nfa_state, NFAState)144        if nfa_state in base_nfa_set:145            return146        base_nfa_set.add(nfa_state)147        for nfa_arc in nfa_state.arcs:148            if nfa_arc.nonterminal_or_string is None:149                addclosure(nfa_arc.next, base_nfa_set)150    base_nfa_set = set()151    addclosure(start, base_nfa_set)152    states = [DFAState(start.from_rule, base_nfa_set, finish)]153    for state in states:  # NB states grows while we're iterating154        arcs = {}155        # Find state transitions and store them in arcs.156        for nfa_state in state.nfa_set:157            for nfa_arc in nfa_state.arcs:158                if nfa_arc.nonterminal_or_string is not None:159                    nfa_set = arcs.setdefault(nfa_arc.nonterminal_or_string, set())160                    addclosure(nfa_arc.next, nfa_set)161        # Now create the dfa's with no None's in arcs anymore. All Nones have162        # been eliminated and state transitions (arcs) are properly defined, we163        # just need to create the dfa's.164        for nonterminal_or_string, nfa_set in arcs.items():165            for nested_state in states:166                if nested_state.nfa_set == nfa_set:167                    # The DFA state already exists for this rule.168                    break169            else:170                nested_state = DFAState(start.from_rule, nfa_set, finish)171                states.append(nested_state)172            state.add_arc(nested_state, nonterminal_or_string)173    return states  # List of DFAState instances; first one is start174def _dump_nfa(start, finish):175    print("Dump of NFA for", start.from_rule)176    todo = [start]177    for i, state in enumerate(todo):178        print("  State", i, state is finish and "(final)" or "")179        for arc in state.arcs:180            label, next_ = arc.nonterminal_or_string, arc.next181            if next_ in todo:182                j = todo.index(next_)183            else:184                j = len(todo)185                todo.append(next_)186            if label is None:187                print("    -> %d" % j)188            else:189                print("    %s -> %d" % (label, j))190def _dump_dfas(dfas):191    print("Dump of DFA for", dfas[0].from_rule)192    for i, state in enumerate(dfas):193        print("  State", i, state.is_final and "(final)" or "")194        for nonterminal, next_ in state.arcs.items():195            print("    %s -> %d" % (nonterminal, dfas.index(next_)))196def generate_grammar(bnf_grammar: str, token_namespace) -> Grammar:197    """198    ``bnf_text`` is a grammar in extended BNF (using * for repetition, + for199    at-least-once repetition, [] for optional parts, | for alternatives and ()200    for grouping).201    It's not EBNF according to ISO/IEC 14977. It's a dialect Python uses in its202    own parser.203    """204    rule_to_dfas = {}205    start_nonterminal = None206    for nfa_a, nfa_z in GrammarParser(bnf_grammar).parse():207        # _dump_nfa(nfa_a, nfa_z)208        dfas = _make_dfas(nfa_a, nfa_z)209        # _dump_dfas(dfas)210        # oldlen = len(dfas)211        _simplify_dfas(dfas)212        # newlen = len(dfas)213        rule_to_dfas[nfa_a.from_rule] = dfas214        # print(nfa_a.from_rule, oldlen, newlen)215        if start_nonterminal is None:216            start_nonterminal = nfa_a.from_rule217    reserved_strings: Mapping[str, ReservedString] = {}218    for nonterminal, dfas in rule_to_dfas.items():219        for dfa_state in dfas:220            for terminal_or_nonterminal, next_dfa in dfa_state.arcs.items():221                if terminal_or_nonterminal in rule_to_dfas:222                    dfa_state.nonterminal_arcs[terminal_or_nonterminal] = next_dfa223                else:224                    transition = _make_transition(225                        token_namespace,226                        reserved_strings,227                        terminal_or_nonterminal228                    )229                    dfa_state.transitions[transition] = DFAPlan(next_dfa)230    _calculate_tree_traversal(rule_to_dfas)231    return Grammar(start_nonterminal, rule_to_dfas, reserved_strings)  # type: ignore232def _make_transition(token_namespace, reserved_syntax_strings, label):233    """234    Creates a reserved string ("if", "for", "*", ...) or returns the token type235    (NUMBER, STRING, ...) for a given grammar terminal.236    """237    if label[0].isalpha():238        # A named token (e.g. NAME, NUMBER, STRING)239        return getattr(token_namespace, label)240    else:241        # Either a keyword or an operator242        assert label[0] in ('"', "'"), label243        assert not label.startswith('"""') and not label.startswith("'''")244        value = literal_eval(label)245        try:246            return reserved_syntax_strings[value]247        except KeyError:248            r = reserved_syntax_strings[value] = ReservedString(value)249            return r250def _calculate_tree_traversal(nonterminal_to_dfas):251    """252    By this point we know how dfas can move around within a stack node, but we253    don't know how we can add a new stack node (nonterminal transitions).254    """255    # Map from grammar rule (nonterminal) name to a set of tokens.256    first_plans = {}257    nonterminals = list(nonterminal_to_dfas.keys())258    nonterminals.sort()259    for nonterminal in nonterminals:260        if nonterminal not in first_plans:261            _calculate_first_plans(nonterminal_to_dfas, first_plans, nonterminal)262    # Now that we have calculated the first terminals, we are sure that263    # there is no left recursion.264    for dfas in nonterminal_to_dfas.values():265        for dfa_state in dfas:266            transitions = dfa_state.transitions267            for nonterminal, next_dfa in dfa_state.nonterminal_arcs.items():268                for transition, pushes in first_plans[nonterminal].items():269                    if transition in transitions:270                        prev_plan = transitions[transition]271                        # Make sure these are sorted so that error messages are272                        # at least deterministic273                        choices = sorted([274                            (275                                prev_plan.dfa_pushes[0].from_rule276                                if prev_plan.dfa_pushes277                                else prev_plan.next_dfa.from_rule278                            ),279                            (280                                pushes[0].from_rule281                                if pushes else next_dfa.from_rule282                            ),283                        ])284                        raise ValueError(285                            "Rule %s is ambiguous; given a %s token, we "286                            "can't determine if we should evaluate %s or %s."287                            % (288                                (289                                    dfa_state.from_rule,290                                    transition,291                                ) + tuple(choices)292                            )293                        )294                    transitions[transition] = DFAPlan(next_dfa, pushes)295def _calculate_first_plans(nonterminal_to_dfas, first_plans, nonterminal):296    """297    Calculates the first plan in the first_plans dictionary for every given298    nonterminal. This is going to be used to know when to create stack nodes.299    """300    dfas = nonterminal_to_dfas[nonterminal]301    new_first_plans = {}302    first_plans[nonterminal] = None  # dummy to detect left recursion303    # We only need to check the first dfa. All the following ones are not304    # interesting to find first terminals.305    state = dfas[0]306    for transition, next_ in state.transitions.items():307        # It's a string. We have finally found a possible first token.308        new_first_plans[transition] = [next_.next_dfa]309    for nonterminal2, next_ in state.nonterminal_arcs.items():310        # It's a nonterminal and we have either a left recursion issue311        # in the grammar or we have to recurse.312        try:313            first_plans2 = first_plans[nonterminal2]314        except KeyError:315            first_plans2 = _calculate_first_plans(nonterminal_to_dfas, first_plans, nonterminal2)316        else:317            if first_plans2 is None:318                raise ValueError("left recursion for rule %r" % nonterminal)319        for t, pushes in first_plans2.items():320            new_first_plans[t] = [next_] + pushes321    first_plans[nonterminal] = new_first_plans...tests.py
Source:tests.py  
...81        self.test_gram = PCFG()82        self.nonterminal = NonterminalSymbol('a')83        self.markup_class = MarkupSet('TEST_MARKUP')84        self.markup = Markup("MARKUP", self.markup_class)85    def test_add_nonterminal(self):86        """87        test adding a nonterminal to a PCFG88        """89        nonterminal = NonterminalSymbol('a')90        self.test_gram.add_nonterminal(nonterminal)91        test_nonterminals = {'a': NonterminalSymbol('a')}92        self.assertEqual(self.test_gram.nonterminals, test_nonterminals)93    def test_add_rule(self):94        """95        test adding a rule to an existing nonterminal in PCFG96        """97        self.test_gram.add_nonterminal(self.nonterminal)98        test_derivation = [NonterminalSymbol('b'), "aaaaade"]99        self.test_gram.add_rule(self.nonterminal, test_derivation)100        test_rules = [Rule(self.nonterminal, test_derivation)]101        self.assertEqual(self.test_gram.nonterminals.get(str(self.nonterminal.tag)).rules, test_rules)102    def test_remove_rule(self):103        """104        test that it successfully removes an implemented rule105        """106        self.test_gram.add_nonterminal(self.nonterminal)107        test_derivation = [NonterminalSymbol('b'), "aaaaade"]108        self.test_gram.remove_rule(self.nonterminal, test_derivation)109        self.assertEqual(self.test_gram.nonterminals.get(str(self.nonterminal.tag)).rules, [])110    def test_expansion(self):111        """112        test expansions of our grammar113        """114        self.test_gram.add_nonterminal(self.nonterminal)115        a_prod = parse_rule("[[b]], this is a test of expansion")116        self.test_gram.add_rule(self.nonterminal, a_prod)117        self.test_gram.add_nonterminal(a_prod[0])118        b_prod = parse_rule("Wow")119        self.test_gram.add_rule(a_prod[0], b_prod)120        test_string = "Wow, this is a test of expansion"121        test_deriv = IntermediateDeriv(set(), TerminalSymbol("Wow, this is a test of expansion"))122        self.assertEqual(self.test_gram.expand(NonterminalSymbol('a')), test_deriv)123    def test_recursive_nt_addition(self):124        """125        add_rule should add all nonterminals present in derivation126        that are not in the grammar to the grammar127        """128        self.test_gram.add_nonterminal(self.nonterminal)129        a_prod = parse_rule("[[b]], this is a test of expansion")130        self.test_gram.add_rule(self.nonterminal, a_prod)131        self.assertEqual(2, len(self.test_gram.nonterminals))132    def test_markup_class_addition(self):133        """134        tests to ensure that if we add a markup to a nonterminal, and that markup class does not already135        exist within our PCFG markup class list, we add it to the markup class list136        """137        self.nonterminal.add_markup(self.markup)138        self.test_gram.add_nonterminal(self.nonterminal)139        test = set()140        test.add(self.markup)141        self.assertEqual(self.test_gram.markup_class[self.markup.tagset.__str__()], test)142    def test_expansion_returns_markup(self):143        """make sure our expansions return markup correctly"""144        self.nonterminal.add_markup(self.markup)145        self.test_gram.add_nonterminal(self.nonterminal)146    def test_empty_expansion(self):147        """148        test that expansions of nonterminals with no productions works correctly149        """150        self.test_gram.add_nonterminal(self.nonterminal)151        a_prod = parse_rule("[[b]], this is a test of expansion")152        self.test_gram.add_rule(self.nonterminal, a_prod)153        self.test_gram.add_nonterminal(a_prod[0])154        test_string = IntermediateDeriv(set(), "[[b]], this is a test of expansion")155        self.assertEqual(self.test_gram.expand(NonterminalSymbol('a')), test_string)156    def test_modify_app_rate(self):157        """158        test that application rates are correctly modified159        """160        self.test_gram.add_nonterminal(self.nonterminal)161        a_prob = parse_rule("test of application_rate")162        self.test_gram.add_rule(self.nonterminal, a_prob)163        old_app = self.test_gram.nonterminals.get(str(self.nonterminal.tag)).rules[0].application_rate164        self.test_gram.modify_application_rate(self.nonterminal, 0, 5)165        new_app = self.test_gram.nonterminals.get(str(self.nonterminal.tag)).rules[0].application_rate166        self.assertNotEqual(old_app, new_app)167        self.assertEqual(new_app, 5)168    def test_returns_system_vars(self):169        """170        test that our function correctly returns the list of system variables171        defined by the user within the program172        """173        self.test_gram.add_nonterminal(self.nonterminal)174        system_var_prod = parse_rule("[[affimative]], [name], [[I think]] his hair is[hair_color]")175        self.test_gram.add_rule(self.nonterminal, system_var_prod)176        self.assertEqual(2, len(self.test_gram.system_vars))177        system_var_prod_2 = parse_rule("Ah yes, [player_name]")178        self.test_gram.add_rule(system_var_prod[0], system_var_prod_2)179        self.assertEqual(3, len(self.test_gram.system_vars))180        test_system_vars = []181        test_system_vars.append(SystemVar("name"))182        test_system_vars.append(SystemVar("hair_color"))183        test_system_vars.append(SystemVar("player_name"))184        self.assertEqual(test_system_vars, self.test_gram.system_vars)185if __name__ == '__main__':...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
