1- """
2- HyperParser
3- ===========
4- This module defines the HyperParser class, which provides advanced parsing
5- abilities for the ParenMatch and other extensions.
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
8- structure of code, used by extensions to help the user.
1+ """Provide advanced parsing abilities for the ParenMatch and other extensions.
2+
3+ HyperParser uses PyParser. PyParser mostly gives information on the
4+ proper indentation of code. HyperParser gives additional information on
5+ the structure of code.
96"""
107
118import string
1512class HyperParser :
1613
1714 def __init__ (self , editwin , index ):
18- """Initialize the HyperParser to analyze the surroundings of the given
19- index.
20- """
15+ "To initialize, analyze the surroundings of the given index."
2116
2217 self .editwin = editwin
2318 self .text = text = editwin .text
@@ -33,9 +28,10 @@ def index2line(index):
3328 startat = max (lno - context , 1 )
3429 startatindex = repr (startat ) + ".0"
3530 stopatindex = "%d.end" % lno
36- # We add the newline because PyParse requires a newline at end.
37- # We add a space so that index won't be at end of line, so that
38- # its status will be the same as the char before it, if should.
31+ # We add the newline because PyParse requires a newline
32+ # at end. We add a space so that index won't be at end
33+ # of line, so that its status will be the same as the
34+ # char before it, if should.
3935 parser .set_str (text .get (startatindex , stopatindex )+ ' \n ' )
4036 bod = parser .find_good_parse_start (
4137 editwin ._build_char_in_string_func (startatindex ))
@@ -49,122 +45,130 @@ def index2line(index):
4945 else :
5046 startatindex = "1.0"
5147 stopatindex = "%d.end" % lno
52- # We add the newline because PyParse requires a newline at end.
53- # We add a space so that index won't be at end of line, so that
54- # its status will be the same as the char before it, if should.
48+ # We add the newline because PyParse requires it. We add a
49+ # space so that index won't be at end of line, so that its
50+ # status will be the same as the char before it, if should.
5551 parser .set_str (text .get (startatindex , stopatindex )+ ' \n ' )
5652 parser .set_lo (0 )
5753
58- # We want what the parser has, except for the last newline and space.
54+ # We want what the parser has, minus the last newline and space.
5955 self .rawtext = parser .str [:- 2 ]
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
62- # text box indices.
56+ # Parser .str apparently preserves the statement we are in, so
57+ # that stopatindex can be used to synchronize the string with
58+ # the text box indices.
6359 self .stopatindex = stopatindex
6460 self .bracketing = parser .get_last_stmt_bracketing ()
65- # find which pairs of bracketing are openers. These always correspond
66- # to a character of rawtext.
67- self .isopener = [i > 0 and self .bracketing [i ][1 ] > self .bracketing [i - 1 ][1 ]
61+ # find which pairs of bracketing are openers. These always
62+ # correspond to a character of rawtext.
63+ self .isopener = [i > 0 and self .bracketing [i ][1 ] >
64+ self .bracketing [i - 1 ][1 ]
6865 for i in range (len (self .bracketing ))]
6966
7067 self .set_index (index )
7168
7269 def set_index (self , index ):
73- """Set the index to which the functions relate. Note that it must be
74- in the same statement.
70+ """Set the index to which the functions relate.
71+
72+ The index must be in the same statement.
7573 """
76- indexinrawtext = \
77- len ( self . rawtext ) - len (self .text .get (index , self .stopatindex ))
74+ indexinrawtext = ( len ( self . rawtext ) -
75+ len (self .text .get (index , self .stopatindex ) ))
7876 if indexinrawtext < 0 :
79- raise ValueError ("The index given is before the analyzed statement" )
77+ raise ValueError ("Index %s precedes the analyzed statement"
78+ % index )
8079 self .indexinrawtext = indexinrawtext
8180 # find the rightmost bracket to which index belongs
8281 self .indexbracket = 0
83- while self .indexbracket < len (self .bracketing )- 1 and \
84- self .bracketing [self .indexbracket + 1 ][0 ] < self .indexinrawtext :
82+ while ( self .indexbracket < len (self .bracketing )- 1 and
83+ self .bracketing [self .indexbracket + 1 ][0 ] < self .indexinrawtext ) :
8584 self .indexbracket += 1
86- if self .indexbracket < len (self .bracketing )- 1 and \
87- self .bracketing [self .indexbracket + 1 ][0 ] == self .indexinrawtext and \
88- not self .isopener [self .indexbracket + 1 ]:
85+ if ( self .indexbracket < len (self .bracketing )- 1 and
86+ self .bracketing [self .indexbracket + 1 ][0 ] == self .indexinrawtext and
87+ not self .isopener [self .indexbracket + 1 ]) :
8988 self .indexbracket += 1
9089
9190 def is_in_string (self ):
9291 """Is the index given to the HyperParser is in a string?"""
9392 # The bracket to which we belong should be an opener.
9493 # If it's an opener, it has to have a character.
95- return self .isopener [self .indexbracket ] and \
96- self .rawtext [self .bracketing [self .indexbracket ][0 ]] in ('"' , "'" )
94+ return (self .isopener [self .indexbracket ] and
95+ self .rawtext [self .bracketing [self .indexbracket ][0 ]]
96+ in ('"' , "'" ))
9797
9898 def is_in_code (self ):
9999 """Is the index given to the HyperParser is in a normal code?"""
100- return not self .isopener [self .indexbracket ] or \
101- self .rawtext [self .bracketing [self .indexbracket ][0 ]] not in \
102- ('#' , '"' , "'" )
100+ return ( not self .isopener [self .indexbracket ] or
101+ self .rawtext [self .bracketing [self .indexbracket ][0 ]]
102+ not in ('#' , '"' , "'" ) )
103103
104104 def get_surrounding_brackets (self , openers = '([{' , mustclose = False ):
105- """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- indices of the opening bracket and the closing bracket (or the
108- end of line, whichever comes first).
109- If it is not surrounded by brackets, or the end of line comes before
110- the closing bracket and mustclose is True, returns None.
105+ """Return bracket indexes or None.
106+
107+ If the index given to the HyperParser is surrounded by a
108+ bracket defined in openers (or at least has one before it),
109+ return the indices of the opening bracket and the closing
110+ bracket (or the end of line, whichever comes first).
111+
112+ If it is not surrounded by brackets, or the end of line comes
113+ before the closing bracket and mustclose is True, returns None.
111114 """
115+
112116 bracketinglevel = self .bracketing [self .indexbracket ][1 ]
113117 before = self .indexbracket
114- while not self .isopener [before ] or \
115- self .rawtext [self .bracketing [before ][0 ]] not in openers or \
116- self .bracketing [before ][1 ] > bracketinglevel :
118+ while ( not self .isopener [before ] or
119+ self .rawtext [self .bracketing [before ][0 ]] not in openers or
120+ self .bracketing [before ][1 ] > bracketinglevel ) :
117121 before -= 1
118122 if before < 0 :
119123 return None
120124 bracketinglevel = min (bracketinglevel , self .bracketing [before ][1 ])
121125 after = self .indexbracket + 1
122- while after < len (self .bracketing ) and \
123- self .bracketing [after ][1 ] >= bracketinglevel :
126+ while ( after < len (self .bracketing ) and
127+ self .bracketing [after ][1 ] >= bracketinglevel ) :
124128 after += 1
125129
126130 beforeindex = self .text .index ("%s-%dc" %
127131 (self .stopatindex , len (self .rawtext )- self .bracketing [before ][0 ]))
128- if after >= len (self .bracketing ) or \
129- self .bracketing [after ][0 ] > len (self .rawtext ):
132+ if ( after >= len (self .bracketing ) or
133+ self .bracketing [after ][0 ] > len (self .rawtext )) :
130134 if mustclose :
131135 return None
132136 afterindex = self .stopatindex
133137 else :
134- # We are after a real char, so it is a ')' and we give the index
135- # before it.
136- afterindex = self .text .index ("%s-%dc" %
137- (self .stopatindex ,
138+ # We are after a real char, so it is a ')' and we give the
139+ # index before it.
140+ afterindex = self .text .index (
141+ "%s-%dc" % (self .stopatindex ,
138142 len (self .rawtext )- (self .bracketing [after ][0 ]- 1 )))
139143
140144 return beforeindex , afterindex
141145
142- # This string includes all chars that may be in a white space
146+ # Ascii chars that may be in a white space
143147 _whitespace_chars = " \t \n \\ "
144- # This string includes all chars that may be in an identifier
148+ # Ascii chars that may be in an identifier
145149 _id_chars = string .ascii_letters + string .digits + "_"
146- # This string includes all chars that may be the first char of an identifier
150+ # Ascii chars that may be the first char of an identifier
147151 _id_first_chars = string .ascii_letters + "_"
148152
149- # 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- # identifiers.
153+ # Given a string and pos, return the number of chars in the
154+ # identifier which ends at pos, or 0 if there is no such one. Saved
155+ # words are not identifiers.
152156 def _eat_identifier (self , str , limit , pos ):
153157 i = pos
154158 while i > limit and str [i - 1 ] in self ._id_chars :
155159 i -= 1
156- if i < pos and (str [i ] not in self ._id_first_chars or \
157- keyword .iskeyword (str [i :pos ])):
160+ if ( i < pos and (str [i ] not in self ._id_first_chars or
161+ keyword .iskeyword (str [i :pos ]) )):
158162 i = pos
159163 return pos - i
160164
161165 def get_expression (self ):
162- """Return a string with the Python expression which ends at the given
163- index, which is empty if there is no real one.
166+ """Return a string with the Python expression which ends at the
167+ given index, which is empty if there is no real one.
164168 """
165169 if not self .is_in_code ():
166- raise ValueError ("get_expression should only be called if index " \
167- "is inside a code." )
170+ raise ValueError ("get_expression should only be called"
171+ "if index is inside a code." )
168172
169173 rawtext = self .rawtext
170174 bracketing = self .bracketing
@@ -177,20 +181,20 @@ def get_expression(self):
177181 postdot_phase = True
178182
179183 while 1 :
180- # Eat whitespaces, comments, and if postdot_phase is False - one dot
184+ # Eat whitespaces, comments, and if postdot_phase is False - a dot
181185 while 1 :
182186 if pos > brck_limit and rawtext [pos - 1 ] in self ._whitespace_chars :
183187 # Eat a whitespace
184188 pos -= 1
185- elif not postdot_phase and \
186- pos > brck_limit and rawtext [pos - 1 ] == '.' :
189+ elif ( not postdot_phase and
190+ pos > brck_limit and rawtext [pos - 1 ] == '.' ) :
187191 # Eat a dot
188192 pos -= 1
189193 postdot_phase = True
190- # The next line will fail if we are *inside* a comment, but we
191- # shouldn't be.
192- elif pos == brck_limit and brck_index > 0 and \
193- rawtext [bracketing [brck_index - 1 ][0 ]] == '#' :
194+ # The next line will fail if we are *inside* a comment,
195+ # but we shouldn't be.
196+ elif ( pos == brck_limit and brck_index > 0 and
197+ rawtext [bracketing [brck_index - 1 ][0 ]] == '#' ) :
194198 # Eat a comment
195199 brck_index -= 2
196200 brck_limit = bracketing [brck_index ][0 ]
@@ -200,22 +204,22 @@ def get_expression(self):
200204 break
201205
202206 if not postdot_phase :
203- # We didn't find a dot, so the expression end at the last
204- # identifier pos.
207+ # We didn't find a dot, so the expression end at the
208+ # last identifier pos.
205209 break
206210
207211 ret = self ._eat_identifier (rawtext , brck_limit , pos )
208212 if ret :
209213 # There is an identifier to eat
210214 pos = pos - ret
211215 last_identifier_pos = pos
212- # Now, in order to continue the search, we must find a dot.
216+ # Now, to continue the search, we must find a dot.
213217 postdot_phase = False
214218 # (the loop continues now)
215219
216220 elif pos == brck_limit :
217- # We are at a bracketing limit. If it is a closing bracket,
218- # eat the bracket, otherwise, stop the search.
221+ # We are at a bracketing limit. If it is a closing
222+ # bracket, eat the bracket, otherwise, stop the search.
219223 level = bracketing [brck_index ][1 ]
220224 while brck_index > 0 and bracketing [brck_index - 1 ][1 ] > level :
221225 brck_index -= 1
0 commit comments