adlint 1.14.0 → 1.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/ChangeLog +265 -0
  2. data/MANIFEST +15 -0
  3. data/NEWS +30 -4
  4. data/etc/conf.d/noarch/adlint_all_bat.erb +1 -1
  5. data/etc/mesg.d/en_US/messages.yml +3 -3
  6. data/etc/mesg.d/ja_JP/messages.yml +3 -3
  7. data/features/message_detection/W0001.feature +2 -0
  8. data/features/message_detection/W0007.feature +8 -0
  9. data/features/message_detection/W0010.feature +4 -1
  10. data/features/message_detection/W0013.feature +8 -0
  11. data/features/message_detection/W0093.feature +3 -0
  12. data/features/message_detection/W0104.feature +7 -0
  13. data/features/message_detection/W0643.feature +80 -0
  14. data/features/message_detection/W0646.feature +115 -0
  15. data/features/message_detection/W0691.feature +100 -0
  16. data/features/message_detection/W0692.feature +32 -0
  17. data/features/message_detection/W0694.feature +128 -0
  18. data/features/message_detection/W0716.feature +3 -0
  19. data/features/message_detection/W0717.feature +3 -0
  20. data/features/message_detection/W0718.feature +3 -0
  21. data/features/message_detection/W0723.feature +2 -0
  22. data/features/message_detection/W0732.feature +3 -0
  23. data/features/message_detection/W0733.feature +3 -0
  24. data/features/message_detection/W0734.feature +8 -0
  25. data/features/message_detection/W0735.feature +8 -0
  26. data/features/message_detection/W0805.feature +92 -0
  27. data/features/message_detection/W0811.feature +79 -0
  28. data/features/message_detection/W1031.feature +7 -0
  29. data/features/message_detection/W1040.feature +89 -0
  30. data/features/message_detection/W1041.feature +15 -0
  31. data/features/message_detection/W1046.feature +60 -0
  32. data/features/message_detection/W1052.feature +3 -0
  33. data/features/message_detection/W1066.feature +3 -0
  34. data/features/message_detection/W1067.feature +3 -0
  35. data/features/message_detection/W1068.feature +3 -0
  36. data/features/message_detection/W1069.feature +5 -0
  37. data/features/message_detection/W1070.feature +6 -0
  38. data/features/message_detection/W1072.feature +1 -0
  39. data/features/message_detection/W1073.feature +145 -0
  40. data/features/message_detection/W1074.feature +139 -0
  41. data/features/message_detection/W1075.feature +86 -0
  42. data/features/message_detection/W1076.feature +66 -0
  43. data/features/message_detection/W1077.feature +105 -0
  44. data/features/message_detection/W9003.feature +4 -0
  45. data/lib/adlint/c/ctrlexpr.rb +3 -0
  46. data/lib/adlint/c/interp.rb +11 -5
  47. data/lib/adlint/c/lexer.rb +14 -3
  48. data/lib/adlint/c/message.rb +192 -0
  49. data/lib/adlint/c/parser.rb +19 -3
  50. data/lib/adlint/c/parser.y +18 -2
  51. data/lib/adlint/c/phase.rb +19 -6
  52. data/lib/adlint/c/syntax.rb +6 -0
  53. data/lib/adlint/c/type.rb +5 -1
  54. data/lib/adlint/cpp/constexpr.rb +3 -3
  55. data/lib/adlint/cpp/constexpr.y +3 -3
  56. data/lib/adlint/cpp/eval.rb +60 -86
  57. data/lib/adlint/cpp/lexer.rb +82 -28
  58. data/lib/adlint/cpp/macro.rb +64 -35
  59. data/lib/adlint/cpp/message.rb +137 -4
  60. data/lib/adlint/cpp/phase.rb +8 -0
  61. data/lib/adlint/cpp/syntax.rb +25 -0
  62. data/lib/adlint/lang.rb +2 -1
  63. data/lib/adlint/version.rb +2 -2
  64. data/share/doc/developers_guide_ja.html +3 -3
  65. data/share/doc/developers_guide_ja.texi +1 -1
  66. data/share/doc/users_guide_en.html +102 -85
  67. data/share/doc/users_guide_en.texi +85 -69
  68. data/share/doc/users_guide_ja.html +102 -94
  69. data/share/doc/users_guide_ja.texi +85 -77
  70. metadata +17 -2
@@ -2022,6 +2022,8 @@ end
2022
2022
  require "adlint/error"
2023
2023
  require "adlint/symbol"
2024
2024
  require "adlint/monitor"
2025
+ require "adlint/util"
2026
+ require "adlint/c/lexer"
2025
2027
  require "adlint/c/syntax"
2026
2028
 
2027
2029
  ---- inner
@@ -2029,9 +2031,9 @@ require "adlint/c/syntax"
2029
2031
  include MonitorUtil
2030
2032
  include ReportUtil
2031
2033
 
2032
- def initialize(context, lexer)
2034
+ def initialize(context)
2033
2035
  @context = context
2034
- @lexer = lexer
2036
+ @lexer = create_lexer(context[:c_source])
2035
2037
  @symbol_table = context[:symbol_table]
2036
2038
  @token_array = []
2037
2039
  @unnamed_tag_no = 0
@@ -2043,7 +2045,21 @@ def execute
2043
2045
  do_parse
2044
2046
  end
2045
2047
 
2048
+ extend Pluggable
2049
+
2050
+ def_plugin :on_string_literals_concatenated
2051
+
2046
2052
  private
2053
+ def create_lexer(c_source)
2054
+ Lexer.new(c_source).tap { |lexer| attach_lexer_plugin(lexer) }
2055
+ end
2056
+
2057
+ def attach_lexer_plugin(lexer)
2058
+ lexer.on_string_literals_concatenated += lambda { |*args|
2059
+ on_string_literals_concatenated.invoke(*args)
2060
+ }
2061
+ end
2062
+
2047
2063
  def next_token
2048
2064
  if token = @lexer.next_token
2049
2065
  @token_array.push(token)
@@ -49,19 +49,26 @@ module C #:nodoc:
49
49
  def do_execute(context)
50
50
  monitored_region("pr3") do
51
51
  context[:c_visitor] = SyntaxTreeMulticastVisitor.new
52
+ context[:c_parser] = Parser.new(context)
53
+ context[:c_commands] = setup_message_detections(context)
52
54
  end
53
55
  end
56
+
57
+ def setup_message_detections(context)
58
+ [
59
+ W0646.new(context)
60
+ ]
61
+ end
54
62
  end
55
63
 
56
64
  class ParsePhase < Phase
57
65
  private
58
66
  def do_execute(context)
59
67
  monitored_region("prs") do
60
- parser = Parser.new(context, Lexer.new(context[:c_source]))
61
68
  begin
62
- context[:c_syntax_tree] = parser.execute
69
+ context[:c_syntax_tree] = context[:c_parser].execute
63
70
  ensure
64
- context[:c_token_array] = parser.token_array
71
+ context[:c_token_array] = context[:c_parser].token_array
65
72
  end
66
73
  end
67
74
  ensure
@@ -85,9 +92,9 @@ module C #:nodoc:
85
92
  monitored_region("pr4") do
86
93
  context[:c_interpreter] = Interpreter.new(context[:c_type_table])
87
94
 
88
- context[:c_commands] = setup_code_extractions(context) +
89
- setup_metric_measurements(context) +
90
- setup_message_detections(context)
95
+ context[:c_commands] += setup_code_extractions(context) +
96
+ setup_metric_measurements(context) +
97
+ setup_message_detections(context)
91
98
  end
92
99
  end
93
100
 
@@ -631,6 +638,7 @@ module C #:nodoc:
631
638
  W0684.new(context),
632
639
  W0685.new(context),
633
640
  W0686.new(context),
641
+ W0694.new(context),
634
642
  W0697.new(context),
635
643
  W0698.new(context),
636
644
  W0699.new(context),
@@ -754,6 +762,11 @@ module C #:nodoc:
754
762
  W1069.new(context),
755
763
  W1070.new(context),
756
764
  W1072.new(context),
765
+ W1073.new(context),
766
+ W1074.new(context),
767
+ W1075.new(context),
768
+ W1076.new(context),
769
+ W1077.new(context),
757
770
  W9001.new(context),
758
771
  W9003.new(context)
759
772
  ]
@@ -1534,6 +1534,12 @@ module C #:nodoc:
1534
1534
  # conditional operator or to access it after the next sequence point,
1535
1535
  # the behavior is undefined.
1536
1536
  @condition.append_sequence_point!
1537
+
1538
+ # NOTE: Add extra sequence points in order not to warn about side-effects
1539
+ # in both the 2nd and 3rd expressions because only one of the 2nd
1540
+ # and 3rd expressions is actually executed.
1541
+ @then_expression.append_sequence_point!
1542
+ @else_expression.append_sequence_point!
1537
1543
  end
1538
1544
 
1539
1545
  attr_reader :condition
data/lib/adlint/c/type.rb CHANGED
@@ -6863,7 +6863,11 @@ module C #:nodoc:
6863
6863
  def_delegator :@base_type, :bit_alignment
6864
6864
  def_delegator :@base_type, :real_type
6865
6865
  def_delegator :@base_type, :base_type
6866
- def_delegator :@base_type, :unqualify
6866
+
6867
+ def unqualify
6868
+ self
6869
+ end
6870
+
6867
6871
  def_delegator :@base_type, :incomplete?
6868
6872
  def_delegator :@base_type, :compatible?
6869
6873
  def_delegator :@base_type, :coercible?
@@ -82,8 +82,8 @@ def value_of(token)
82
82
  token == "$" ? "EOF" : token.value
83
83
  end
84
84
 
85
- def notify_illformed_defined_operator(location)
86
- on_illformed_defined_op_found.invoke(location)
85
+ def notify_illformed_defined_operator(location, no_args)
86
+ on_illformed_defined_op_found.invoke(location, no_args)
87
87
  end
88
88
 
89
89
  def notify_undefined_macro_referred(identifier)
@@ -484,7 +484,7 @@ module_eval(<<'.,.,', 'constexpr.y', 119)
484
484
 
485
485
  module_eval(<<'.,.,', 'constexpr.y', 129)
486
486
  def _reduce_12(val, _values, result)
487
- notify_illformed_defined_operator(location_of(val[0]))
487
+ notify_illformed_defined_operator(location_of(val[0]), val[1] == "$")
488
488
  result = ErrorExpression.new(val[1])
489
489
 
490
490
  result
@@ -127,7 +127,7 @@ unary_expression
127
127
  }
128
128
  | DEFINED error
129
129
  {
130
- notify_illformed_defined_operator(location_of(val[0]))
130
+ notify_illformed_defined_operator(location_of(val[0]), val[1] == "$")
131
131
  result = ErrorExpression.new(val[1])
132
132
  }
133
133
  ;
@@ -374,8 +374,8 @@ def value_of(token)
374
374
  token == "$" ? "EOF" : token.value
375
375
  end
376
376
 
377
- def notify_illformed_defined_operator(location)
378
- on_illformed_defined_op_found.invoke(location)
377
+ def notify_illformed_defined_operator(location, no_args)
378
+ on_illformed_defined_op_found.invoke(location, no_args)
379
379
  end
380
380
 
381
381
  def notify_undefined_macro_referred(identifier)
@@ -72,8 +72,10 @@ module Cpp #:nodoc:
72
72
  def_plugin :on_unlexable_char_found
73
73
  def_plugin :on_cr_at_eol_found
74
74
  def_plugin :on_eof_mark_at_eof_found
75
+ def_plugin :on_illformed_newline_escape_found
75
76
  def_plugin :on_illformed_defined_op_found
76
77
  def_plugin :on_undefined_macro_referred
78
+ def_plugin :on_extra_tokens_found
77
79
 
78
80
  private
79
81
  def preprocessing_file(context)
@@ -102,6 +104,8 @@ module Cpp #:nodoc:
102
104
  return asm_section(context)
103
105
  when :NULL_DIRECTIVE
104
106
  return NullDirective.new(context.next_token)
107
+ when :UNKNOWN_DIRECTIVE
108
+ return UnknownDirective.new(context.next_token)
105
109
  when :TEXT_LINE
106
110
  text_line = TextLine.new(context.next_token)
107
111
  tokens = TextLineNormalizer.normalize(text_line, context)
@@ -161,9 +165,7 @@ module Cpp #:nodoc:
161
165
  unless pp_tokens = pp_tokens(context)
162
166
  return nil
163
167
  end
164
- unless new_line = context.next_token and new_line.type == :NEW_LINE
165
- return nil
166
- end
168
+ discard_extra_tokens_until_newline(context)
167
169
  expression = ExpressionNormalizer.normalize(pp_tokens, context, self)
168
170
  if expression.value == 0
169
171
  context.skip_group
@@ -179,9 +181,7 @@ module Cpp #:nodoc:
179
181
  unless identifier = context.next_token and identifier.type == :IDENTIFIER
180
182
  return nil
181
183
  end
182
- unless new_line = context.next_token and new_line.type == :NEW_LINE
183
- return nil
184
- end
184
+ discard_extra_tokens_until_newline(context)
185
185
  if macro_defined?(context, identifier)
186
186
  group = group(context)
187
187
  context.branch_evaluated = true
@@ -196,9 +196,7 @@ module Cpp #:nodoc:
196
196
  unless identifier = context.next_token and identifier.type == :IDENTIFIER
197
197
  return nil
198
198
  end
199
- unless new_line = context.next_token and new_line.type == :NEW_LINE
200
- return nil
201
- end
199
+ discard_extra_tokens_until_newline(context)
202
200
  if macro_defined?(context, identifier)
203
201
  context.skip_group
204
202
  else
@@ -229,9 +227,7 @@ module Cpp #:nodoc:
229
227
  unless pp_tokens = pp_tokens(context)
230
228
  return nil
231
229
  end
232
- unless new_line = context.next_token and new_line.type == :NEW_LINE
233
- return nil
234
- end
230
+ discard_extra_tokens_until_newline(context)
235
231
  expression = ExpressionNormalizer.normalize(pp_tokens, context, self)
236
232
  if context.branch_evaluated? || expression.value == 0
237
233
  context.skip_group
@@ -248,9 +244,7 @@ module Cpp #:nodoc:
248
244
  def else_group(context)
249
245
  if keyword = context.next_token
250
246
  if keyword.type == :ELSE
251
- unless new_line = context.next_token and new_line.type == :NEW_LINE
252
- return nil
253
- end
247
+ discard_extra_tokens_until_newline(context)
254
248
  if context.branch_evaluated?
255
249
  context.skip_group
256
250
  else
@@ -266,9 +260,7 @@ module Cpp #:nodoc:
266
260
  def endif_line(context)
267
261
  if keyword = context.next_token
268
262
  if keyword.type == :ENDIF
269
- unless new_line = context.next_token and new_line.type == :NEW_LINE
270
- return nil
271
- end
263
+ discard_extra_tokens_until_newline(context)
272
264
  return EndifLine.new(keyword)
273
265
  end
274
266
  end
@@ -329,9 +321,7 @@ module Cpp #:nodoc:
329
321
 
330
322
  def user_include_line(context, keyword)
331
323
  header_name = context.next_token
332
- unless new_line = context.next_token and new_line.type == :NEW_LINE
333
- return nil
334
- end
324
+ discard_extra_tokens_until_newline(context)
335
325
  user_include_line =
336
326
  UserIncludeLine.new(keyword, header_name, context.include_depth)
337
327
  include_first_user_header(user_include_line, context)
@@ -340,9 +330,7 @@ module Cpp #:nodoc:
340
330
 
341
331
  def user_include_next_line(context, keyword)
342
332
  header_name = context.next_token
343
- unless new_line = context.next_token and new_line.type == :NEW_LINE
344
- return nil
345
- end
333
+ discard_extra_tokens_until_newline(context)
346
334
  user_include_next_line =
347
335
  UserIncludeNextLine.new(keyword, header_name, context.include_depth)
348
336
  include_next_user_header(user_include_next_line, context)
@@ -351,9 +339,7 @@ module Cpp #:nodoc:
351
339
 
352
340
  def system_include_line(context, keyword)
353
341
  header_name = context.next_token
354
- unless new_line = context.next_token and new_line.type == :NEW_LINE
355
- return nil
356
- end
342
+ discard_extra_tokens_until_newline(context)
357
343
  system_include_line =
358
344
  SystemIncludeLine.new(keyword, header_name, context.include_depth)
359
345
  include_first_system_header(system_include_line, context)
@@ -362,9 +348,7 @@ module Cpp #:nodoc:
362
348
 
363
349
  def system_include_next_line(context, keyword)
364
350
  header_name = context.next_token
365
- unless new_line = context.next_token and new_line.type == :NEW_LINE
366
- return nil
367
- end
351
+ discard_extra_tokens_until_newline(context)
368
352
  system_include_next_line =
369
353
  SystemIncludeNextLine.new(keyword, header_name, context.include_depth)
370
354
  include_next_system_header(system_include_next_line, context)
@@ -375,9 +359,7 @@ module Cpp #:nodoc:
375
359
  unless pp_tokens = pp_tokens(context)
376
360
  return nil
377
361
  end
378
- unless new_line = context.next_token and new_line.type == :NEW_LINE
379
- return nil
380
- end
362
+ discard_extra_tokens_until_newline(context)
381
363
  PPTokensNormalizer.normalize(pp_tokens, context)
382
364
  return nil if pp_tokens.tokens.empty?
383
365
  case parameter = pp_tokens.tokens.map { |t| t.value }.join
@@ -403,9 +385,7 @@ module Cpp #:nodoc:
403
385
  unless pp_tokens = pp_tokens(context)
404
386
  return nil
405
387
  end
406
- unless new_line = context.next_token and new_line.type == :NEW_LINE
407
- return nil
408
- end
388
+ discard_extra_tokens_until_newline(context)
409
389
  PPTokensNormalizer.normalize(pp_tokens, context)
410
390
  return nil if pp_tokens.tokens.empty?
411
391
  case parameter = pp_tokens.tokens.map { |t| t.value }.join
@@ -454,9 +434,7 @@ module Cpp #:nodoc:
454
434
  return nil
455
435
  end
456
436
  replacement_list = replacement_list(context)
457
- unless new_line = context.next_token and new_line.type == :NEW_LINE
458
- return nil
459
- end
437
+ discard_extra_tokens_until_newline(context)
460
438
  if ellipsis
461
439
  define_line = VaFunctionLikeDefineLine.new(keyword, identifier,
462
440
  identifier_list,
@@ -472,9 +450,7 @@ module Cpp #:nodoc:
472
450
  end
473
451
  else
474
452
  replacement_list = replacement_list(context)
475
- unless new_line = context.next_token and new_line.type == :NEW_LINE
476
- return nil
477
- end
453
+ discard_extra_tokens_until_newline(context)
478
454
  define_line = ObjectLikeDefineLine.new(keyword, identifier,
479
455
  replacement_list, symbol)
480
456
  macro = ObjectLikeMacro.new(define_line)
@@ -490,9 +466,7 @@ module Cpp #:nodoc:
490
466
  unless identifier = context.next_token and identifier.type == :IDENTIFIER
491
467
  return nil
492
468
  end
493
- unless new_line = context.next_token and new_line.type == :NEW_LINE
494
- return nil
495
- end
469
+ discard_extra_tokens_until_newline(context)
496
470
 
497
471
  undef_line = UndefLine.new(keyword, identifier)
498
472
  macro = context.macro_table.lookup(identifier.value)
@@ -506,9 +480,7 @@ module Cpp #:nodoc:
506
480
  def line_line(context)
507
481
  keyword = context.next_token
508
482
  pp_tokens = pp_tokens(context)
509
- unless new_line = context.next_token and new_line.type == :NEW_LINE
510
- return nil
511
- end
483
+ discard_extra_tokens_until_newline(context)
512
484
 
513
485
  # NOTE: The ISO C99 standard saids;
514
486
  #
@@ -532,18 +504,14 @@ module Cpp #:nodoc:
532
504
  def error_line(context)
533
505
  keyword = context.next_token
534
506
  pp_tokens = pp_tokens(context)
535
- unless new_line = context.next_token and new_line.type == :NEW_LINE
536
- return nil
537
- end
507
+ discard_extra_tokens_until_newline(context)
538
508
  ErrorLine.new(keyword, pp_tokens)
539
509
  end
540
510
 
541
511
  def pragma_line(context)
542
512
  keyword = context.next_token
543
513
  pp_tokens = pp_tokens(context)
544
- unless new_line = context.next_token and new_line.type == :NEW_LINE
545
- return nil
546
- end
514
+ discard_extra_tokens_until_newline(context)
547
515
  pragma_line = PragmaLine.new(keyword, pp_tokens)
548
516
  if pp_tokens && pp_tokens.tokens.size == 1 &&
549
517
  pp_tokens.tokens.first.value == "once"
@@ -607,9 +575,7 @@ module Cpp #:nodoc:
607
575
  def asm_line(context)
608
576
  if keyword = context.next_token
609
577
  if keyword.type == :ASM
610
- unless new_line = context.next_token and new_line.type == :NEW_LINE
611
- return nil
612
- end
578
+ discard_extra_tokens_until_newline(context)
613
579
  return AsmLine.new(keyword)
614
580
  end
615
581
  end
@@ -619,9 +585,7 @@ module Cpp #:nodoc:
619
585
  def endasm_line(context)
620
586
  if keyword = context.next_token
621
587
  if keyword.type == :ENDASM
622
- unless new_line = context.next_token and new_line.type == :NEW_LINE
623
- return nil
624
- end
588
+ discard_extra_tokens_until_newline(context)
625
589
  return EndasmLine.new(keyword)
626
590
  end
627
591
  end
@@ -761,35 +725,41 @@ module Cpp #:nodoc:
761
725
  end
762
726
  end
763
727
 
728
+ def discard_extra_tokens_until_newline(context)
729
+ extra_tokens = []
730
+ while token = context.next_token
731
+ if token.type == :NEW_LINE
732
+ break
733
+ else
734
+ extra_tokens.push(token)
735
+ end
736
+ end
737
+ notify_extra_tokens_found(extra_tokens) unless extra_tokens.empty?
738
+ end
739
+
764
740
  def create_lexer(context, source)
765
741
  Lexer.new(source).tap { |lexer| attach_lexer_plugin(lexer, context) }
766
742
  end
767
743
 
768
744
  def attach_lexer_plugin(lexer, context)
769
- lexer.on_block_comment_found += lambda { |comment, location|
770
- on_block_comment_found.invoke(comment, location)
771
- }
772
- lexer.on_line_comment_found += lambda { |comment, location|
773
- on_line_comment_found.invoke(comment, location)
774
- }
775
- lexer.on_nested_block_comment_found += lambda { |location|
776
- on_nested_block_comment_found.invoke(location)
777
- }
778
- lexer.on_unterminated_block_comment += lambda { |location|
779
- handle_unterminated_block_comment(context, location)
780
- }
781
- lexer.on_eof_newline_not_found += lambda { |location|
782
- on_eof_newline_not_found.invoke(location)
783
- }
784
- lexer.on_unlexable_char_found += lambda { |char, location|
785
- on_unlexable_char_found.invoke(char, location)
786
- }
787
- lexer.on_cr_at_eol_found += lambda { |location|
788
- on_cr_at_eol_found.invoke(location)
789
- }
790
- lexer.on_eof_mark_at_eof_found += lambda { |location|
791
- on_eof_mark_at_eof_found.invoke(location)
792
- }
745
+ lexer.on_block_comment_found +=
746
+ lambda { |*args| on_block_comment_found.invoke(*args) }
747
+ lexer.on_line_comment_found +=
748
+ lambda { |*args| on_line_comment_found.invoke(*args) }
749
+ lexer.on_nested_block_comment_found +=
750
+ lambda { |*args| on_nested_block_comment_found.invoke(*args) }
751
+ lexer.on_unterminated_block_comment +=
752
+ lambda { |*args| handle_unterminated_block_comment(*args) }
753
+ lexer.on_eof_newline_not_found +=
754
+ lambda { |*args| on_eof_newline_not_found.invoke(*args) }
755
+ lexer.on_unlexable_char_found +=
756
+ lambda { |*args| on_unlexable_char_found.invoke(*args) }
757
+ lexer.on_cr_at_eol_found +=
758
+ lambda { |*args| on_cr_at_eol_found.invoke(*args) }
759
+ lexer.on_eof_mark_at_eof_found +=
760
+ lambda { |*args| on_eof_mark_at_eof_found.invoke(*args) }
761
+ lexer.on_illformed_newline_escape_found +=
762
+ lambda { |*args| on_illformed_newline_escape_found.invoke(*args) }
793
763
  end
794
764
 
795
765
  def notify_user_header_included(user_include_line, user_header)
@@ -828,14 +798,18 @@ module Cpp #:nodoc:
828
798
  on_pp_token_extracted.invoke(pp_token)
829
799
  end
830
800
 
831
- def notify_illformed_defined_op_found(location)
832
- on_illformed_defined_op_found.invoke(location)
801
+ def notify_illformed_defined_op_found(location, no_args)
802
+ on_illformed_defined_op_found.invoke(location, no_args)
833
803
  end
834
804
 
835
805
  def notify_undefined_macro_referred(identifier)
836
806
  on_undefined_macro_referred.invoke(identifier)
837
807
  end
838
808
 
809
+ def notify_extra_tokens_found(extra_tokens)
810
+ on_extra_tokens_found.invoke(extra_tokens)
811
+ end
812
+
839
813
  def handle_unterminated_block_comment(context, location)
840
814
  E(:E0016, location)
841
815
  raise UnterminatedCommentError.new(location,