MCPcopy Create free account
hub / github.com/idank/explainshell / Matcher

Class Matcher

explainshell/matcher.py:70–958  ·  view source on GitHub ↗

parse a command line and return a list of `MatchResult`s describing each token.

Source from the content-addressed store, hash-verified

68
69
70class Matcher(bashlex.ast.nodevisitor):
71 """parse a command line and return a list of `MatchResult`s describing
72 each token.
73 """
74
75 def __init__(
76 self,
77 s,
78 store,
79 distro: str | None = None,
80 release: str | None = None,
81 distro_preference: list[tuple[str, str]] | None = None,
82 ):
83 self.s = s
84 self.store = store
85 self.distro = distro
86 self.release = release
87 self._distro_preference = distro_preference or []
88 self._anchored = False
89 self._prev_option = self._current_option = None
90 self.groups = [MatchGroup("shell")]
91
92 # a list of `match_word_exp` where expansions happened during word
93 # expansion
94 self.expansions = []
95
96 # a stack to manage nested command groups: whenever a new simple
97 # command is started, we push a tuple with:
98 # - the node that started this group. this is used to find it when
99 # a command ends (see visitnodeend)
100 # - its `MatchGroup`. new `MatchResult`s will be added to it.
101 # - a word used to end the top-most command. this is used when a flag
102 # starts a new command, e.g. find -exec.
103 self.group_stack = [(None, self.groups[-1], None)]
104
105 # keep a stack of the currently visited compound command (if/for..)
106 # to provide context when matching reserved words, since for example
107 # the keyword 'done' can appear in a for, while..
108 self.compound_stack = []
109
110 # a set of functions defined in the current input, we will try to match
111 # commands against them so if one refers to defined function, it won't
112 # show up as unknown or be taken from the db
113 self.functions = set()
114
115 def _generate_cmd_group_name(self):
116 existing = len([g for g in self.groups if g.name.startswith("command")])
117 return f"command{existing}"
118
119 @property
120 def matches(self):
121 """return the list of results from the most recently created group"""
122 return self.group_stack[-1][1].results
123
124 @property
125 def all_matches(self):
126 return list(itertools.chain.from_iterable(g.results for g in self.groups))
127

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected