@@ -213,10 +213,7 @@ def find_character_literal_candidates(lQuotes, lChars):
213213
214214def is_character_literal_candidate (iIndex , lQuotes , lChars ):
215215 iQuote = lQuotes [iIndex ]
216- if (
217- there_is_a_single_token_between_quotes (iIndex , lQuotes )
218- and token_between_quotes_is_a_single_character (iQuote , lChars )
219- ):
216+ if there_is_a_single_token_between_quotes (iIndex , lQuotes ) and token_between_quotes_is_a_single_character (iQuote , lChars ):
220217 return True
221218 return False
222219
@@ -233,38 +230,39 @@ def token_between_quotes_is_a_single_character(iQuote, lChars):
233230 return False
234231
235232
236- def filter_character_literal_candidates (lLiterals ):
233+ def filter_character_literal_candidates (lCandidates ):
237234 lReturn = []
238235 lSequentialCandidates = []
239- for iIndex , lLiteral in enumerate (lLiterals ):
240-
236+ for iIndex , lCandidate in enumerate (lCandidates ):
241237 # The algorithm is a bit more complex than one might expect because it needs to be able to handle sequences of
242238 # character literals separated by a single character, e.g. `'1','0','a'`, as well as character literals inside
243239 # qualified expressions, e.g. std_logic'('1'), both of which include "red herring" candidates.
244240 # First, build up a sequence of sequential candidates, i.e. candidates that are separated by one character. Most
245241 # of the time, this sequence will be one long.
246- lSequentialCandidates .append (lLiteral )
247-
248- bCandidateIsLast = iIndex != len (lLiterals ) - 1
249- if not bCandidateIsLast :
250- lNextLiteral = lLiterals [iIndex + 1 ]
251- bNextCandidateOverlapsWithCurrent = lLiteral [1 ] == lNextLiteral [0 ]
252- if not bNextCandidateOverlapsWithCurrent :
253-
254- # At the end of a sequence, filter the candidates to find the character literals. Sequential candidates
255- # will alternate between valid and invalid candidates. For example, in `'1','0'`, the first candidate
256- # ('1') is valid, the second (',') is invalid, and the third ('0') is valid. The first in the sequence
257- # will always be valid unless a qualified expression is present. For example, in `std_logic'('1')`, the
258- # first candidate ('(') is invalid and the second candidate ('1') is valid. If there is a qualified
259- # expression, the number of candidates will be even; otherwise the number will be odd.
260- # Therefore, filter by selecting every second candidate, starting with 0 if the number of candidates is
261- # odd and starting with 1 if the number of candidates is even.
262- iSequenceStart = (len (lSequentialCandidates ) + 1 ) % 2
263- lFilteredLiterals = [lSequentialCandidates [x ] for x in range (iSequenceStart , len (lSequentialCandidates ), 2 )]
264- lReturn .extend (lFilteredLiterals )
265-
266- # Clear the sequential candidates for the next sequence.
267- lSequentialCandidates = []
242+ lSequentialCandidates .append (lCandidate )
243+
244+ bCandidateIsLast = iIndex == len (lCandidates ) - 1
245+ if bCandidateIsLast :
246+ bCandidateIsLastInSequence = True
247+ else :
248+ lNextLiteral = lCandidates [iIndex + 1 ]
249+ bCandidateIsLastInSequence = lCandidate [1 ] != lNextLiteral [0 ]
250+
251+ if bCandidateIsLastInSequence :
252+ # At the end of a sequence, filter the candidates to find the character literals. Sequential candidates will
253+ # alternate between valid and invalid candidates. For example, in `'1','0'`, the first candidate ('1') is
254+ # valid, the second (',') is invalid, and the third ('0') is valid. The first in the sequence will always be
255+ # valid unless a qualified expression is present. For example, in `std_logic'('1')`, the first candidate
256+ # ('(') is invalid and the second candidate ('1') is valid. If there is a qualified expression, the number
257+ # of candidates will be even; otherwise the number will be odd.
258+ # Therefore, filter by selecting every second candidate, starting with 0 if the number of candidates is odd
259+ # and starting with 1 if the number of candidates is even.
260+ iSequenceStart = (len (lSequentialCandidates ) + 1 ) % 2
261+ lFilteredLiterals = [lSequentialCandidates [x ] for x in range (iSequenceStart , len (lSequentialCandidates ), 2 )]
262+ lReturn .extend (lFilteredLiterals )
263+
264+ # Clear the sequential candidates for the next sequence.
265+ lSequentialCandidates = []
268266
269267 return lReturn
270268
0 commit comments