recover seeks forward in the token stream until it finds TokenType "end", then returns with the peeker pointed at the following token. If the given token type is a bracketer, this function will additionally count nested instances of the brackets to try to leave the peeker at the end of the _current
(end TokenType)
| 2082 | // nested instances. This is a best-effort operation and may have |
| 2083 | // unpredictable results on input with bad bracketer nesting. |
| 2084 | func (p *parser) recover(end TokenType) Token { |
| 2085 | start := p.oppositeBracket(end) |
| 2086 | p.recovery = true |
| 2087 | |
| 2088 | nest := 0 |
| 2089 | for { |
| 2090 | tok := p.Read() |
| 2091 | ty := tok.Type |
| 2092 | if end == TokenTemplateSeqEnd && ty == TokenTemplateControl { |
| 2093 | // normalize so that our matching behavior can work, since |
| 2094 | // TokenTemplateControl/TokenTemplateInterp are asymmetrical |
| 2095 | // with TokenTemplateSeqEnd and thus we need to count both |
| 2096 | // openers if that's the closer we're looking for. |
| 2097 | ty = TokenTemplateInterp |
| 2098 | } |
| 2099 | |
| 2100 | switch ty { |
| 2101 | case start: |
| 2102 | nest++ |
| 2103 | case end: |
| 2104 | if nest < 1 { |
| 2105 | return tok |
| 2106 | } |
| 2107 | |
| 2108 | nest-- |
| 2109 | case TokenEOF: |
| 2110 | return tok |
| 2111 | } |
| 2112 | } |
| 2113 | } |
| 2114 | |
| 2115 | // recoverOver seeks forward in the token stream until it finds a block |
| 2116 | // starting with TokenType "start", then finds the corresponding end token, |
no test coverage detected