Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(10)

Side by Side Diff: Lib/idlelib/HyperParser.py

Issue 21686: IDLE - Test hyperparser
Patch Set: Created 5 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | Lib/idlelib/idle_test/test_hyperparser.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 """ 1 """
2 HyperParser 2 HyperParser
3 =========== 3 ===========
4 This module defines the HyperParser class, which provides advanced parsing 4 This module defines the HyperParser class, which provides advanced parsing
5 abilities for the ParenMatch and other extensions. 5 abilities for the ParenMatch and other extensions.
6 The HyperParser uses PyParser. PyParser is intended mostly to give information 6 The HyperParser uses PyParser. PyParser is intended mostly to give information
7 on the proper indentation of code. HyperParser gives some information on the 7 on the proper indentation of code. HyperParser gives some information on the
8 structure of code, used by extensions to help the user. 8 structure of code, used by extensions to help the user.
9 """ 9 """
10 10
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 57
58 # We want what the parser has, except for the last newline and space. 58 # We want what the parser has, except for the last newline and space.
59 self.rawtext = parser.str[:-2] 59 self.rawtext = parser.str[:-2]
60 # As far as I can see, parser.str preserves the statement we are in, 60 # As far as I can see, parser.str preserves the statement we are in,
61 # so that stopatindex can be used to synchronize the string with the 61 # so that stopatindex can be used to synchronize the string with the
62 # text box indices. 62 # text box indices.
63 self.stopatindex = stopatindex 63 self.stopatindex = stopatindex
64 self.bracketing = parser.get_last_stmt_bracketing() 64 self.bracketing = parser.get_last_stmt_bracketing()
65 # find which pairs of bracketing are openers. These always correspond 65 # find which pairs of bracketing are openers. These always correspond
66 # to a character of rawtext. 66 # to a character of rawtext.
67 self.isopener = [i>0 and self.bracketing[i][1] > self.bracketing[i-1][1] 67 self.isopener = [i>0 and self.bracketing[i][1]>self.bracketing[i-1][1]
68 for i in range(len(self.bracketing))] 68 for i in range(len(self.bracketing))]
69 69
70 self.set_index(index) 70 self.set_index(index)
71 71
72 def set_index(self, index): 72 def set_index(self, index):
73 """Set the index to which the functions relate. Note that it must be 73 """Set the index to which the functions relate. Note that it must be
74 in the same statement. 74 in the same statement.
75 """ 75 """
76 indexinrawtext = \ 76 indexinrawtext = \
77 len(self.rawtext) - len(self.text.get(index, self.stopatindex)) 77 len(self.rawtext) - len(self.text.get(index, self.stopatindex))
78 if indexinrawtext < 0: 78 if indexinrawtext < 0:
79 raise ValueError("The index given is before the analyzed statement") 79 raise ValueError("The index given is before the analyzed "
80 "statement")
80 self.indexinrawtext = indexinrawtext 81 self.indexinrawtext = indexinrawtext
81 # find the rightmost bracket to which index belongs 82 # find the rightmost bracket to which index belongs
82 self.indexbracket = 0 83 self.indexbracket = 0
83 while self.indexbracket < len(self.bracketing)-1 and \ 84 while self.indexbracket < len(self.bracketing)-1 and \
84 self.bracketing[self.indexbracket+1][0] < self.indexinrawtext: 85 self.bracketing[self.indexbracket+1][0] < self.indexinrawtext:
85 self.indexbracket += 1 86 self.indexbracket += 1
86 if self.indexbracket < len(self.bracketing)-1 and \ 87 if self.indexbracket < len(self.bracketing)-1 and \
87 self.bracketing[self.indexbracket+1][0] == self.indexinrawtext and \ 88 self.bracketing[self.indexbracket+1][0] == self.indexinrawtext and \
88 not self.isopener[self.indexbracket+1]: 89 not self.isopener[self.indexbracket+1]:
89 self.indexbracket += 1 90 self.indexbracket += 1
90 91
91 def is_in_string(self): 92 def is_in_string(self):
92 """Is the index given to the HyperParser is in a string?""" 93 """Is the index given to the HyperParser is in a string?"""
93 # The bracket to which we belong should be an opener. 94 # The bracket to which we belong should be an opener.
94 # If it's an opener, it has to have a character. 95 # If it's an opener, it has to have a character.
95 return self.isopener[self.indexbracket] and \ 96 return self.isopener[self.indexbracket] and \
96 self.rawtext[self.bracketing[self.indexbracket][0]] in ('"', "'") 97 self.rawtext[self.bracketing[self.indexbracket][0]] in ('"', "'")
97 98
98 def is_in_code(self): 99 def is_in_code(self):
99 """Is the index given to the HyperParser is in a normal code?""" 100 """Is the index given to the HyperParser is in a normal code?"""
100 return not self.isopener[self.indexbracket] or \ 101 return not self.isopener[self.indexbracket] or \
101 self.rawtext[self.bracketing[self.indexbracket][0]] not in \ 102 self.rawtext[self.bracketing[self.indexbracket][0]] not in \
102 ('#', '"', "'") 103 ('#', '"', "'")
103 104
104 def get_surrounding_brackets(self, openers='([{', mustclose=False): 105 def get_surrounding_brackets(self, openers='([{', mustclose=False):
105 """If the index given to the HyperParser is surrounded by a bracket 106 """If the index given to the HyperParser is surrounded by a bracket
106 defined in openers (or at least has one before it), return the 107 defined in openers (or at least has one before it), return the
(...skipping 29 matching lines...) Expand all
136 afterindex = self.text.index("%s-%dc" % 137 afterindex = self.text.index("%s-%dc" %
137 (self.stopatindex, 138 (self.stopatindex,
138 len(self.rawtext)-(self.bracketing[after][0]-1))) 139 len(self.rawtext)-(self.bracketing[after][0]-1)))
139 140
140 return beforeindex, afterindex 141 return beforeindex, afterindex
141 142
142 # This string includes all chars that may be in a white space 143 # This string includes all chars that may be in a white space
143 _whitespace_chars = " \t\n\\" 144 _whitespace_chars = " \t\n\\"
144 # This string includes all chars that may be in an identifier 145 # This string includes all chars that may be in an identifier
145 _id_chars = string.ascii_letters + string.digits + "_" 146 _id_chars = string.ascii_letters + string.digits + "_"
146 # This string includes all chars that may be the first char of an identifier 147 # This string includes all chars that may be the 1st char of an identifier
147 _id_first_chars = string.ascii_letters + "_" 148 _id_first_chars = string.ascii_letters + "_"
148 149
149 # Given a string and pos, return the number of chars in the identifier 150 # Given a string and pos, return the number of chars in the identifier
150 # which ends at pos, or 0 if there is no such one. Saved words are not 151 # which ends at pos, or 0 if there is no such one. Saved words are not
151 # identifiers. 152 # identifiers.
152 def _eat_identifier(self, str, limit, pos): 153 def _eat_identifier(self, str, limit, pos):
153 i = pos 154 i = pos
154 while i > limit and str[i-1] in self._id_chars: 155 while i > limit and str[i-1] in self._id_chars:
155 i -= 1 156 i -= 1
156 if i < pos and (str[i] not in self._id_first_chars or \ 157 if i < pos and (str[i] not in self._id_first_chars or \
(...skipping 13 matching lines...) Expand all
170 bracketing = self.bracketing 171 bracketing = self.bracketing
171 172
172 brck_index = self.indexbracket 173 brck_index = self.indexbracket
173 brck_limit = bracketing[brck_index][0] 174 brck_limit = bracketing[brck_index][0]
174 pos = self.indexinrawtext 175 pos = self.indexinrawtext
175 176
176 last_identifier_pos = pos 177 last_identifier_pos = pos
177 postdot_phase = True 178 postdot_phase = True
178 179
179 while 1: 180 while 1:
180 # Eat whitespaces, comments, and if postdot_phase is False - one dot 181 # Eat whitespaces, comments, and if postdot_phase is False - a dot
181 while 1: 182 while 1:
182 if pos>brck_limit and rawtext[pos-1] in self._whitespace_chars: 183 if pos>brck_limit and rawtext[pos-1] in self._whitespace_chars:
183 # Eat a whitespace 184 # Eat a whitespace
184 pos -= 1 185 pos -= 1
185 elif not postdot_phase and \ 186 elif not postdot_phase and \
186 pos > brck_limit and rawtext[pos-1] == '.': 187 pos > brck_limit and rawtext[pos-1] == '.':
187 # Eat a dot 188 # Eat a dot
188 pos -= 1 189 pos -= 1
189 postdot_phase = True 190 postdot_phase = True
190 # The next line will fail if we are *inside* a comment, but we 191 # The next line will fail if we are *inside* a comment, but we
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 while pos > 0 and rawtext[pos - 1] in "rRbBuU": 238 while pos > 0 and rawtext[pos - 1] in "rRbBuU":
238 pos -= 1 239 pos -= 1
239 last_identifier_pos = pos 240 last_identifier_pos = pos
240 break 241 break
241 242
242 else: 243 else:
243 # We've found an operator or something. 244 # We've found an operator or something.
244 break 245 break
245 246
246 return rawtext[last_identifier_pos:self.indexinrawtext] 247 return rawtext[last_identifier_pos:self.indexinrawtext]
248
249 if __name__ == '__main__':
250 import unittest
251 unittest.main('idlelib.idle_test.test_hyperparser', verbosity=2)
OLDNEW
« no previous file with comments | « no previous file | Lib/idlelib/idle_test/test_hyperparser.py » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+