Pre-conditions: * On the first call to this function, @leaf MUST be the leaf that was directly after the string leaf in question (e.g. if our target string is `line.leaves[i]` then the first call to this method must be `line.leaves[i + 1
(self, leaf: Leaf)
| 2439 | return idx |
| 2440 | |
| 2441 | def _next_state(self, leaf: Leaf) -> bool: |
| 2442 | """ |
| 2443 | Pre-conditions: |
| 2444 | * On the first call to this function, @leaf MUST be the leaf that |
| 2445 | was directly after the string leaf in question (e.g. if our target |
| 2446 | string is `line.leaves[i]` then the first call to this method must |
| 2447 | be `line.leaves[i + 1]`). |
| 2448 | * On the next call to this function, the leaf parameter passed in |
| 2449 | MUST be the leaf directly following @leaf. |
| 2450 | |
| 2451 | Returns: |
| 2452 | True iff @leaf is a part of the string's trailer. |
| 2453 | """ |
| 2454 | # We ignore empty LPAR or RPAR leaves. |
| 2455 | if is_empty_par(leaf): |
| 2456 | return True |
| 2457 | |
| 2458 | next_token = leaf.type |
| 2459 | if next_token == token.LPAR: |
| 2460 | self._unmatched_lpars += 1 |
| 2461 | |
| 2462 | current_state = self._state |
| 2463 | |
| 2464 | # The LPAR parser state is a special case. We will return True until we |
| 2465 | # find the matching RPAR token. |
| 2466 | if current_state == self.LPAR: |
| 2467 | if next_token == token.RPAR: |
| 2468 | self._unmatched_lpars -= 1 |
| 2469 | if self._unmatched_lpars == 0: |
| 2470 | self._state = self.RPAR |
| 2471 | # Otherwise, we use a lookup table to determine the next state. |
| 2472 | else: |
| 2473 | # If the lookup table matches the current state to the next |
| 2474 | # token, we use the lookup table. |
| 2475 | if (current_state, next_token) in self._goto: |
| 2476 | self._state = self._goto[current_state, next_token] |
| 2477 | else: |
| 2478 | # Otherwise, we check if a the current state was assigned a |
| 2479 | # default. |
| 2480 | if (current_state, self.DEFAULT_TOKEN) in self._goto: |
| 2481 | self._state = self._goto[current_state, self.DEFAULT_TOKEN] |
| 2482 | # If no default has been assigned, then this parser has a logic |
| 2483 | # error. |
| 2484 | else: |
| 2485 | raise RuntimeError(f"{self.__class__.__name__} LOGIC ERROR!") |
| 2486 | |
| 2487 | if self._state == self.DONE: |
| 2488 | return False |
| 2489 | |
| 2490 | return True |
| 2491 | |
| 2492 | |
| 2493 | def insert_str_child_factory(string_leaf: Leaf) -> Callable[[LN], None]: |