Class: Antlr4::Runtime::DefaultErrorStrategy
- Inherits:
-
ANTLRErrorStrategy
- Object
- ANTLRErrorStrategy
- Antlr4::Runtime::DefaultErrorStrategy
- Defined in:
- lib/antlr4/runtime/default_error_strategy.rb
Direct Known Subclasses
Instance Method Summary collapse
- #begin_error_condition(_recognizer) ⇒ Object
- #consume_until(recognizer, set) ⇒ Object
- #end_error_condition(_recognizer) ⇒ Object
- #error_recovery_mode?(_recognizer) ⇒ Boolean
- #error_recovery_set(recognizer) ⇒ Object
-
#escape_ws_and_quote(s) ⇒ Object
if ( s==nil ) return s.
- #expected_tokens(recognizer) ⇒ Object
- #get_missing_symbol(recognizer) ⇒ Object
-
#initialize ⇒ DefaultErrorStrategy
constructor
A new instance of DefaultErrorStrategy.
- #recover(recognizer, _e) ⇒ Object
- #recover_in_line(recognizer) ⇒ Object
- #report_error(recognizer, e) ⇒ Object
- #report_failed_predicate(recognizer, e) ⇒ Object
- #report_input_mismatch(recognizer, e) ⇒ Object
- #report_match(recognizer) ⇒ Object
- #report_missing_token(recognizer) ⇒ Object
- #report_no_viable_alternative(recognizer, e) ⇒ Object
- #report_unwanted_token(recognizer) ⇒ Object
- #reset(recognizer) ⇒ Object
- #single_token_deletion(recognizer) ⇒ Object
- #single_token_insertion(recognizer) ⇒ Object
- #symbol_text(symbol) ⇒ Object
- #symbol_type(symbol) ⇒ Object
- #sync(recognizer) ⇒ Object
- #token_error_display(t) ⇒ Object
Methods inherited from ANTLRErrorStrategy
Constructor Details
#initialize ⇒ DefaultErrorStrategy
Returns a new instance of DefaultErrorStrategy.
4 5 6 7 8 9 10 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 4 def initialize @error_recovery_mode = false @last_error_index = -1 @last_error_states = nil @next_tokens_context = nil @next_tokens_state = nil end |
Instance Method Details
#begin_error_condition(_recognizer) ⇒ Object
16 17 18 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 16 def begin_error_condition(_recognizer) @error_recovery_mode = true end |
#consume_until(recognizer, set) ⇒ Object
302 303 304 305 306 307 308 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 302 def consume_until(recognizer, set) ttype = recognizer._input.la(1) while ttype != Token::EOF && !set.contains(ttype) recognizer.consume ttype = recognizer._input.la(1) end end |
#end_error_condition(_recognizer) ⇒ Object
24 25 26 27 28 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 24 def end_error_condition(_recognizer) @error_recovery_mode = false @last_error_states = nil @last_error_index = -1 end |
#error_recovery_mode?(_recognizer) ⇒ Boolean
20 21 22 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 20 def error_recovery_mode?(_recognizer) @error_recovery_mode end |
#error_recovery_set(recognizer) ⇒ Object
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 286 def error_recovery_set(recognizer) atn = recognizer._interp.atn ctx = recognizer._ctx recover_set = IntervalSet.new while !ctx.nil? && ctx.invoking_state >= 0 # compute what follows who invoked us invoking_state = atn.states[ctx.invoking_state] rt = invoking_state.transition(0) follow = atn.next_tokens(rt.follow_state) recover_set.add_all(follow) ctx = ctx.parent end recover_set.remove(Token::EPSILON) recover_set end |
#escape_ws_and_quote(s) ⇒ Object
if ( s==nil ) return s
279 280 281 282 283 284 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 279 def escape_ws_and_quote(s) # if ( s==nil ) return s s = s.sub("\n", '\\n') s = s.sub("\r", '\\r') s = s.sub("\t", '\\t') "'" + s + "'" end |
#expected_tokens(recognizer) ⇒ Object
251 252 253 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 251 def expected_tokens(recognizer) recognizer.expected_tokens end |
#get_missing_symbol(recognizer) ⇒ Object
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 229 def get_missing_symbol(recognizer) current_symbol = recognizer.current_token expecting = expected_tokens(recognizer) expected_token_type = Token::INVALID_TYPE unless expecting.is_nil expected_token_type = expecting.min_element # get any element end if expected_token_type == Token::EOF token_text = '<missing EOF>' else token_text = '<missing ' + recognizer.get_vocabulary.display_name(expected_token_type) + '>' end current = current_symbol look_back = recognizer._input.lt(-1) current = look_back if current.type == Token::EOF && !look_back.nil? pair = OpenStruct.new pair.a = current.source pair.b = current.source._input recognizer.token_factory.create(pair, expected_token_type, token_text, Token::DEFAULT_CHANNEL, -1, -1, current.line, current.char_position_in_line) end |
#recover(recognizer, _e) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 55 def recover(recognizer, _e) if @last_error_index == recognizer._input.index && !@last_error_states.nil? && @last_error_states.contains(recognizer._state_number) # uh oh, another error at same token index and previously-visited # state in ATN must be a case where lt(1) is in the recovery # token set so nothing got consumed. Consume a single token # at least to prevent an infinite loop this is a failsafe. # System.err.println("seen error condition before index="+ # lastErrorIndex+", states="+last_error_states) # System.err.println("FAILSAFE consumes "+recognizer.getTokenNames()[recognizer.getInputStream().la(1)]) recognizer.consume end @last_error_index = recognizer._input.index @last_error_states = IntervalSet.new if @last_error_states.nil? @last_error_states.add(recognizer._state_number) followSet = error_recovery_set(recognizer) consume_until(recognizer, followSet) end |
#recover_in_line(recognizer) ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 171 def recover_in_line(recognizer) # SINGLE TOKEN DELETION matched_symbol = single_token_deletion(recognizer) unless matched_symbol.nil? # we have deleted the extra token. # now, move past ttype token as if all were ok recognizer.consume return matched_symbol end # SINGLE TOKEN INSERTION return get_missing_symbol(recognizer) if single_token_insertion(recognizer) # even that didn't work must throw the exception exc = InputMismatchException.new exc.recognizer = recognizer if @next_tokens_context.nil? raise exc else exc.offending_token = recognizer._input.lt(1) exc.offending_state = @next_tokens_state exc.context = @next_tokens_context raise exc end end |
#report_error(recognizer, e) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 34 def report_error(recognizer, e) # if we've already reported an error and have not matched a token # yet successfully, don't report any errors. if error_recovery_mode?(recognizer) # System.err.print("[SPURIOUS] ") return # don't report spurious errors end begin_error_condition(recognizer) if e.is_a? NoViableAltException report_no_viable_alternative(recognizer, e) elsif e.is_a? InputMismatchException report_input_mismatch(recognizer, e) elsif e.is_a? FailedPredicateException report_failed_predicate(recognizer, e) else STDERR.puts 'unknown recognition error type: ' + e.getClass.getName recognizer.notify_error_listeners(e.getOffendingToken, e.getMessage, e) end end |
#report_failed_predicate(recognizer, e) ⇒ Object
141 142 143 144 145 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 141 def report_failed_predicate(recognizer, e) rule_name = recognizer.rule_names[recognizer._ctx.rule_index] msg = 'rule ' + rule_name + ' ' + e.getMessage recognizer.notify_error_listeners(e.getOffendingToken, msg, e) end |
#report_input_mismatch(recognizer, e) ⇒ Object
136 137 138 139 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 136 def report_input_mismatch(recognizer, e) msg = 'mismatched input ' + token_error_display(e.offending_token) + ' expecting ' + e.expected_tokens.to_string_from_vocabulary(recognizer.get_vocabulary) recognizer.notify_error_listeners(e.offending_token, msg, e) end |
#report_match(recognizer) ⇒ Object
30 31 32 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 30 def report_match(recognizer) end_error_condition(recognizer) end |
#report_missing_token(recognizer) ⇒ Object
159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 159 def report_missing_token(recognizer) return if error_recovery_mode?(recognizer) begin_error_condition(recognizer) t = recognizer.current_token expecting = expected_tokens(recognizer) msg = 'missing ' + expecting.to_string_from_vocabulary(recognizer.get_vocabulary) + ' at ' + token_error_display(t) recognizer.notify_error_listeners(t, msg, nil) end |
#report_no_viable_alternative(recognizer, e) ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 121 def report_no_viable_alternative(recognizer, e) tokens = recognizer._input input = if !tokens.nil? if e.start_token.type == Token::EOF '<EOF>' else tokens.text4(e.start_token, e.offending_token) end else '<unknown input>' end msg = 'no viable alternative at input ' + escape_ws_and_quote(input) recognizer.notify_error_listeners(e.offending_token, msg, e) end |
#report_unwanted_token(recognizer) ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 147 def report_unwanted_token(recognizer) return if error_recovery_mode?(recognizer) begin_error_condition(recognizer) t = recognizer.current_token token_name = token_error_display(t) expecting = expected_tokens(recognizer) msg = 'extraneous input ' + token_name + ' expecting ' + expecting.to_string_from_vocabulary(recognizer.get_vocabulary) recognizer.notify_error_listeners(t, msg, nil) end |
#reset(recognizer) ⇒ Object
12 13 14 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 12 def reset(recognizer) end_error_condition(recognizer) end |
#single_token_deletion(recognizer) ⇒ Object
214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 214 def single_token_deletion(recognizer) next_token_type = recognizer._input.la(2) expecting = expected_tokens(recognizer) if expecting.contains(next_token_type) report_unwanted_token(recognizer) recognizer.consume # simply delete extra token # we want to return the token we're actually matching matched_symbol = recognizer.current_token report_match(recognizer) # we know current token is correct return matched_symbol end nil end |
#single_token_insertion(recognizer) ⇒ Object
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 197 def single_token_insertion(recognizer) current_symbol_type = recognizer._input.la(1) # if current token is consistent with what could come after current # ATN state, then we know we're missing a token error recovery # is free to conjure up and insert the missing token current_state = recognizer._interp.atn.states[recognizer._state_number] next_t = current_state.transition(0).target atn = recognizer._interp.atn expecting_at_ll2 = atn.next_tokens_ctx(next_t, recognizer._ctx) # System.out.println("lt(2) set="+expecting_at_ll2.to_s(recognizer.getTokenNames())) if expecting_at_ll2.contains(current_symbol_type) report_missing_token(recognizer) return true end false end |
#symbol_text(symbol) ⇒ Object
270 271 272 273 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 270 def symbol_text(symbol) return symbol.text if symbol.respond_to? :text symbol.to_s end |
#symbol_type(symbol) ⇒ Object
275 276 277 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 275 def symbol_type(symbol) symbol.type end |
#sync(recognizer) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 73 def sync(recognizer) s = recognizer._interp.atn.states[recognizer._state_number] # System.err.println("sync @ "+s.stateNumber+"="+s.getClass().getSimpleName()) # If already recovering, don't try to sync return if error_recovery_mode?(recognizer) tokens = recognizer._input la = tokens.la(1) # try cheaper subset first might get lucky. seems to shave a wee bit off next_tokens = recognizer.atn.next_tokens(s) if next_tokens.contains(la) # We are sure the token matches @next_tokens_context = nil @next_tokens_state = ATNState.invalid_state_number return end if next_tokens.contains(Token::EPSILON) if @next_tokens_context.nil? # It's possible the next token won't match information tracked # by sync is restricted for performance. @next_tokens_context = recognizer._ctx @next_tokens_state = recognizer._state_number end return end case s.state_type when ATNState::BLOCK_START, ATNState::STAR_BLOCK_START, ATNState::PLUS_BLOCK_START, ATNState::STAR_LOOP_ENTRY # report error and recover if possible return unless single_token_deletion(recognizer).nil? exc = InputMismatchException.create(recognizer) raise exc when ATNState::PLUS_LOOP_BACK, ATNState::STAR_LOOP_BACK # System.err.println("at loop back: "+s.getClass().getSimpleName()) report_unwanted_token(recognizer) expecting = recognizer.expected_tokens what_follows_loop_iteration_or_rule = expecting.or(error_recovery_set(recognizer)) consume_until(recognizer, what_follows_loop_iteration_or_rule) else # do nothing if we can't identify the exact kind of ATN state end end end |
#token_error_display(t) ⇒ Object
255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
# File 'lib/antlr4/runtime/default_error_strategy.rb', line 255 def token_error_display(t) return '<no token>' if t.nil? s = symbol_text(t) if s.nil? s = if symbol_type(t) == Token::EOF '<EOF>' else '<' << symbol_type(t).to_s << '>' end end escape_ws_and_quote(s) end |