lrama 0.6.10 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/gh-pages.yml +46 -0
  3. data/.github/workflows/test.yaml +40 -8
  4. data/.gitignore +1 -0
  5. data/.rdoc_options +2 -0
  6. data/Gemfile +4 -2
  7. data/NEWS.md +125 -30
  8. data/README.md +44 -15
  9. data/Rakefile +13 -1
  10. data/Steepfile +5 -0
  11. data/doc/Index.md +58 -0
  12. data/doc/development/compressed_state_table/main.md +635 -0
  13. data/doc/development/compressed_state_table/parse.output +174 -0
  14. data/doc/development/compressed_state_table/parse.y +22 -0
  15. data/doc/development/compressed_state_table/parser.rb +282 -0
  16. data/lib/lrama/bitmap.rb +4 -1
  17. data/lib/lrama/command.rb +2 -1
  18. data/lib/lrama/context.rb +3 -3
  19. data/lib/lrama/counterexamples/derivation.rb +6 -5
  20. data/lib/lrama/counterexamples/example.rb +7 -4
  21. data/lib/lrama/counterexamples/path.rb +4 -0
  22. data/lib/lrama/counterexamples.rb +19 -9
  23. data/lib/lrama/digraph.rb +30 -0
  24. data/lib/lrama/grammar/binding.rb +47 -15
  25. data/lib/lrama/grammar/parameterizing_rule/rhs.rb +1 -1
  26. data/lib/lrama/grammar/rule.rb +8 -0
  27. data/lib/lrama/grammar/rule_builder.rb +4 -16
  28. data/lib/lrama/grammar/symbols/resolver.rb +4 -0
  29. data/lib/lrama/grammar.rb +10 -5
  30. data/lib/lrama/lexer/grammar_file.rb +8 -1
  31. data/lib/lrama/lexer/location.rb +17 -1
  32. data/lib/lrama/lexer/token/char.rb +1 -0
  33. data/lib/lrama/lexer/token/ident.rb +1 -0
  34. data/lib/lrama/lexer/token/instantiate_rule.rb +6 -1
  35. data/lib/lrama/lexer/token/tag.rb +3 -1
  36. data/lib/lrama/lexer/token/user_code.rb +6 -2
  37. data/lib/lrama/lexer/token.rb +14 -2
  38. data/lib/lrama/lexer.rb +5 -5
  39. data/lib/lrama/logger.rb +4 -0
  40. data/lib/lrama/option_parser.rb +10 -8
  41. data/lib/lrama/options.rb +2 -1
  42. data/lib/lrama/parser.rb +529 -490
  43. data/lib/lrama/state/reduce.rb +2 -3
  44. data/lib/lrama/state.rb +288 -1
  45. data/lib/lrama/states/item.rb +8 -0
  46. data/lib/lrama/states.rb +69 -2
  47. data/lib/lrama/trace_reporter.rb +17 -2
  48. data/lib/lrama/version.rb +1 -1
  49. data/lrama.gemspec +1 -1
  50. data/parser.y +42 -30
  51. data/rbs_collection.lock.yaml +10 -2
  52. data/sig/generated/lrama/bitmap.rbs +11 -0
  53. data/sig/generated/lrama/digraph.rbs +39 -0
  54. data/sig/generated/lrama/grammar/binding.rbs +34 -0
  55. data/sig/generated/lrama/lexer/grammar_file.rbs +28 -0
  56. data/sig/generated/lrama/lexer/location.rbs +52 -0
  57. data/sig/{lrama → generated/lrama}/lexer/token/char.rbs +2 -0
  58. data/sig/{lrama → generated/lrama}/lexer/token/ident.rbs +2 -0
  59. data/sig/{lrama → generated/lrama}/lexer/token/instantiate_rule.rbs +8 -0
  60. data/sig/{lrama → generated/lrama}/lexer/token/tag.rbs +3 -0
  61. data/sig/{lrama → generated/lrama}/lexer/token/user_code.rbs +6 -1
  62. data/sig/{lrama → generated/lrama}/lexer/token.rbs +26 -3
  63. data/sig/generated/lrama/logger.rbs +14 -0
  64. data/sig/generated/lrama/trace_reporter.rbs +25 -0
  65. data/sig/lrama/counterexamples/derivation.rbs +33 -0
  66. data/sig/lrama/counterexamples/example.rbs +45 -0
  67. data/sig/lrama/counterexamples/path.rbs +21 -0
  68. data/sig/lrama/counterexamples/production_path.rbs +11 -0
  69. data/sig/lrama/counterexamples/start_path.rbs +13 -0
  70. data/sig/lrama/counterexamples/state_item.rbs +10 -0
  71. data/sig/lrama/counterexamples/transition_path.rbs +11 -0
  72. data/sig/lrama/counterexamples/triple.rbs +20 -0
  73. data/sig/lrama/counterexamples.rbs +29 -0
  74. data/sig/lrama/grammar/rule_builder.rbs +0 -1
  75. data/sig/lrama/grammar/symbol.rbs +1 -1
  76. data/sig/lrama/grammar/symbols/resolver.rbs +3 -3
  77. data/sig/lrama/grammar.rbs +13 -0
  78. data/sig/lrama/options.rbs +1 -0
  79. data/sig/lrama/state/reduce_reduce_conflict.rbs +2 -2
  80. data/sig/lrama/state.rbs +79 -0
  81. data/sig/lrama/states.rbs +101 -0
  82. metadata +34 -14
  83. data/sig/lrama/bitmap.rbs +0 -7
  84. data/sig/lrama/digraph.rbs +0 -23
  85. data/sig/lrama/grammar/binding.rbs +0 -19
  86. data/sig/lrama/lexer/grammar_file.rbs +0 -17
  87. data/sig/lrama/lexer/location.rbs +0 -26
@@ -0,0 +1,174 @@
1
+ Symbol
2
+
3
+ -2 EMPTY
4
+ 0 "end of file"
5
+ 1 error
6
+ 2 "invalid token" (undef)
7
+ 3 LF
8
+ 4 NUM
9
+ 5 '+'
10
+ 6 '*'
11
+ 7 '('
12
+ 8 ')'
13
+ 9 $accept # Start of nonterminal
14
+ 10 program
15
+ 11 expr
16
+
17
+
18
+ Grammar
19
+
20
+ 0 $accept: program "end of file"
21
+
22
+ 1 program: ε
23
+ 2 | expr LF
24
+
25
+ 3 expr: NUM
26
+ 4 | expr '+' expr
27
+ 5 | expr '*' expr
28
+ 6 | '(' expr ')'
29
+
30
+
31
+ State 0
32
+
33
+ 0 $accept: • program "end of file"
34
+ 1 program: ε • ["end of file"]
35
+ 2 | • expr LF
36
+ 3 expr: • NUM
37
+ 4 | • expr '+' expr
38
+ 5 | • expr '*' expr
39
+ 6 | • '(' expr ')'
40
+
41
+ NUM shift, and go to state 1
42
+ '(' shift, and go to state 2
43
+
44
+ $default reduce using rule 1 (program)
45
+
46
+ program go to state 3
47
+ expr go to state 4
48
+
49
+
50
+ State 1
51
+
52
+ 3 expr: NUM •
53
+
54
+ $default reduce using rule 3 (expr)
55
+
56
+
57
+ State 2
58
+
59
+ 3 expr: • NUM
60
+ 4 | • expr '+' expr
61
+ 5 | • expr '*' expr
62
+ 6 | • '(' expr ')'
63
+ 6 | '(' • expr ')'
64
+
65
+ NUM shift, and go to state 1
66
+ '(' shift, and go to state 2
67
+
68
+ expr go to state 5
69
+
70
+
71
+ State 3
72
+
73
+ 0 $accept: program • "end of file"
74
+
75
+ "end of file" shift, and go to state 6
76
+
77
+
78
+ State 4
79
+
80
+ 2 program: expr • LF
81
+ 4 expr: expr • '+' expr
82
+ 5 | expr • '*' expr
83
+
84
+ LF shift, and go to state 7
85
+ '+' shift, and go to state 8
86
+ '*' shift, and go to state 9
87
+
88
+
89
+ State 5
90
+
91
+ 4 expr: expr • '+' expr
92
+ 5 | expr • '*' expr
93
+ 6 | '(' expr • ')'
94
+
95
+ '+' shift, and go to state 8
96
+ '*' shift, and go to state 9
97
+ ')' shift, and go to state 10
98
+
99
+
100
+ State 6
101
+
102
+ 0 $accept: program "end of file" •
103
+
104
+ $default accept
105
+
106
+
107
+ State 7
108
+
109
+ 2 program: expr LF •
110
+
111
+ $default reduce using rule 2 (program)
112
+
113
+
114
+ State 8
115
+
116
+ 3 expr: • NUM
117
+ 4 | • expr '+' expr
118
+ 4 | expr '+' • expr
119
+ 5 | • expr '*' expr
120
+ 6 | • '(' expr ')'
121
+
122
+ NUM shift, and go to state 1
123
+ '(' shift, and go to state 2
124
+
125
+ expr go to state 11
126
+
127
+
128
+ State 9
129
+
130
+ 3 expr: • NUM
131
+ 4 | • expr '+' expr
132
+ 5 | • expr '*' expr
133
+ 5 | expr '*' • expr
134
+ 6 | • '(' expr ')'
135
+
136
+ NUM shift, and go to state 1
137
+ '(' shift, and go to state 2
138
+
139
+ expr go to state 12
140
+
141
+
142
+ State 10
143
+
144
+ 6 expr: '(' expr ')' •
145
+
146
+ $default reduce using rule 6 (expr)
147
+
148
+
149
+ State 11
150
+
151
+ 4 expr: expr • '+' expr
152
+ 4 | expr '+' expr • [LF, '+', ')']
153
+ 5 | expr • '*' expr
154
+
155
+ '*' shift, and go to state 9
156
+
157
+ $default reduce using rule 4 (expr)
158
+
159
+ Conflict between rule 4 and token '+' resolved as reduce (%left '+').
160
+ Conflict between rule 4 and token '*' resolved as shift ('+' < '*').
161
+
162
+
163
+ State 12
164
+
165
+ 4 expr: expr • '+' expr
166
+ 5 | expr • '*' expr
167
+ 5 | expr '*' expr • [LF, '+', '*', ')']
168
+
169
+ $default reduce using rule 5 (expr)
170
+
171
+ Conflict between rule 5 and token '+' resolved as reduce ('+' < '*').
172
+ Conflict between rule 5 and token '*' resolved as reduce (%left '*').
173
+
174
+
@@ -0,0 +1,22 @@
1
+ %union {
2
+ int val;
3
+ }
4
+ %token LF
5
+ %token <val> NUM
6
+ %type <val> expr
7
+ %left '+'
8
+ %left '*'
9
+
10
+ %%
11
+
12
+ program : /* empty */
13
+ | expr LF { printf("=> %d\n", $1); }
14
+ ;
15
+
16
+ expr : NUM
17
+ | expr '+' expr { $$ = $1 + $3; }
18
+ | expr '*' expr { $$ = $1 * $3; }
19
+ | '(' expr ')' { $$ = $2; }
20
+ ;
21
+
22
+ %%
@@ -0,0 +1,282 @@
1
+ class Parser
2
+ YYNTOKENS = 9
3
+ YYLAST = 13
4
+ YYTABLE_NINF = -1
5
+ YYTABLE = [ 5, 6, 7, 9, 8, 9, 11, 12, 8, 9, 1, 10, 0, 2]
6
+ YYCHECK = [ 2, 0, 3, 6, 5, 6, 8, 9, 5, 6, 4, 8, -1, 7]
7
+
8
+ YYPACT_NINF = -4
9
+ YYPACT = [ 6, -4, 6, 1, -1, 3, -4, -4, 6, 6, -4, -3, -4]
10
+ YYPGOTO = [ -4, -4, -2]
11
+
12
+ YYDEFACT = [ 2, 4, 0, 0, 0, 0, 1, 3, 0, 0, 7, 5, 6]
13
+ YYDEFGOTO = [ 0, 3, 4]
14
+
15
+ YYR1 = [ 0, 9, 10, 10, 11, 11, 11, 11]
16
+ YYR2 = [ 0, 2, 0, 2, 1, 3, 3, 3]
17
+
18
+ YYFINAL = 6
19
+
20
+ # Symbols
21
+ SYM_EMPTY = -2
22
+ SYM_EOF = 0 # "end of file"
23
+ SYM_ERROR = 1 # error
24
+ SYM_UNDEF = 2 # Invalid Token
25
+ SYM_LF = 3 # LF
26
+ SYM_NUM = 4 # NUM
27
+ SYM_PLUS = 5 # '+'
28
+ SYM_ASTER = 6 # '*'
29
+ SYM_LPAREN = 7 # '('
30
+ SYM_RPAREN = 8 # ')'
31
+ # Start of nonterminal
32
+ SYM_ACCEPT = 9 # $accept
33
+ SYM_PROGRAM = 10 # program
34
+ SYM_EXPR = 11 # expr
35
+
36
+ def initialize(debug = false)
37
+ @debug = debug
38
+ end
39
+
40
+ def parse(lexer)
41
+ state = 0
42
+ stack = []
43
+ yytoken = SYM_EMPTY
44
+ parser_action = :push_state
45
+ next_state = nil
46
+ rule = nil
47
+
48
+ while true
49
+ _parser_action = parser_action
50
+ parser_action = nil
51
+
52
+ case _parser_action
53
+ when :syntax_error
54
+ debug_print("Entering :syntax_error")
55
+
56
+ return 1
57
+ when :accept
58
+ debug_print("Entering :accept")
59
+
60
+ return 0
61
+ when :push_state
62
+ # Precondition: `state` is set to new state
63
+ debug_print("Entering :push_state")
64
+
65
+ debug_print("Push state #{state}")
66
+ stack.push(state)
67
+ debug_print("Current stack #{stack}")
68
+
69
+ if state == YYFINAL
70
+ parser_action = :accept
71
+ next
72
+ end
73
+
74
+ parser_action = :decide_parser_action
75
+ next
76
+ when :decide_parser_action
77
+ debug_print("Entering :decide_parser_action")
78
+
79
+ offset = yypact[state]
80
+ if offset == YYPACT_NINF
81
+ parser_action = :yydefault
82
+ next
83
+ end
84
+
85
+ # Ensure next token
86
+ if yytoken == SYM_EMPTY
87
+ debug_print("Reading a token")
88
+
89
+ yytoken = lexer.next_token
90
+ end
91
+
92
+ case yytoken
93
+ when SYM_EOF
94
+ debug_print("Now at end of input.")
95
+ when SYM_ERROR
96
+ parser_action = :syntax_error
97
+ next
98
+ else
99
+ debug_print("Next token is #{yytoken}")
100
+ end
101
+
102
+ idx = offset + yytoken
103
+ if idx < 0 || YYLAST < idx
104
+ debug_print("Decide next parser action as :yydefault")
105
+
106
+ parser_action = :yydefault
107
+ next
108
+ end
109
+ if yycheck[idx] != yytoken
110
+ debug_print("Decide next parser action as :yydefault")
111
+
112
+ parser_action = :yydefault
113
+ next
114
+ end
115
+
116
+ action = yytable[idx]
117
+ if action == YYTABLE_NINF
118
+ parser_action = :syntax_error
119
+ next
120
+ end
121
+ if action > 0
122
+ # Shift
123
+ debug_print("Decide next parser action as :yyshift")
124
+
125
+ next_state = action
126
+ parser_action = :yyshift
127
+ next
128
+ else
129
+ # Reduce
130
+ debug_print("Decide next parser action as :yyreduce")
131
+
132
+ rule = -action
133
+ parser_action = :yyreduce
134
+ next
135
+ end
136
+ when :yyshift
137
+ # Precondition: `next_state` is set
138
+ debug_print("Entering :yyshift")
139
+ raise "next_state is not set" unless next_state
140
+
141
+ yytoken = SYM_EMPTY
142
+ state = next_state
143
+ next_state = nil
144
+ parser_action = :push_state
145
+ next
146
+ when :yydefault
147
+ debug_print("Entering :yydefault")
148
+
149
+ rule = yydefact[state]
150
+ if rule == 0
151
+ parser_action = :syntax_error
152
+ next
153
+ end
154
+
155
+ parser_action = :yyreduce
156
+ next
157
+ when :yyreduce
158
+ # Precondition: `rule`, used for reduce, is set
159
+ debug_print("Entering :yyreduce")
160
+ raise "rule is not set" unless rule
161
+
162
+ rhs_length = yyr2[rule]
163
+ lhs_nterm = yyr1[rule]
164
+ lhs_nterm_id = lhs_nterm - YYNTOKENS
165
+
166
+ text = "Execute action for Rule (#{rule}) "
167
+ case rule
168
+ when 1
169
+ text << "$accept: program \"end of file\""
170
+ when 2
171
+ text << "program: ε"
172
+ when 3
173
+ text << "program: expr LF"
174
+ when 4
175
+ text << "expr: NUM"
176
+ when 5
177
+ text << "expr: expr '+' expr"
178
+ when 6
179
+ text << "expr: expr '*' expr"
180
+ when 7
181
+ text << "expr: '(' expr ')'"
182
+ end
183
+ debug_print(text)
184
+
185
+ debug_print("Pop #{rhs_length} elements")
186
+ debug_print("Stack before pop: #{stack}")
187
+ stack.pop(rhs_length)
188
+ debug_print("Stack after pop: #{stack}")
189
+ state = stack[-1]
190
+
191
+ # "Shift" LHS nonterminal
192
+ offset = yypgoto[lhs_nterm_id]
193
+ if offset == YYPACT_NINF
194
+ state = yydefgoto[lhs_nterm_id]
195
+ else
196
+ idx = offset + state
197
+ if idx < 0 || YYLAST < idx
198
+ state = yydefgoto[lhs_nterm_id]
199
+ elsif yycheck[idx] != state
200
+ state = yydefgoto[lhs_nterm_id]
201
+ else
202
+ state = yytable[idx]
203
+ end
204
+ end
205
+
206
+ rule = nil
207
+ parser_action = :push_state
208
+ next
209
+ else
210
+ raise "Unknown parser_action: #{parser_action}"
211
+ end
212
+ end
213
+ end
214
+
215
+ private
216
+
217
+ def debug_print(str)
218
+ if @debug
219
+ $stderr.puts str
220
+ end
221
+ end
222
+
223
+ def yytable
224
+ YYTABLE
225
+ end
226
+
227
+ def yycheck
228
+ YYCHECK
229
+ end
230
+
231
+ def yypact
232
+ YYPACT
233
+ end
234
+
235
+ def yypgoto
236
+ YYPGOTO
237
+ end
238
+
239
+ def yydefact
240
+ YYDEFACT
241
+ end
242
+
243
+ def yydefgoto
244
+ YYDEFGOTO
245
+ end
246
+
247
+ def yyr1
248
+ YYR1
249
+ end
250
+
251
+ def yyr2
252
+ YYR2
253
+ end
254
+ end
255
+
256
+ class Lexer
257
+ def initialize(tokens)
258
+ @tokens = tokens
259
+ @index = 0
260
+ end
261
+
262
+ def next_token
263
+ if @tokens.length > @index
264
+ token = @tokens[@index]
265
+ @index += 1
266
+ return token
267
+ else
268
+ return Parser::SYM_EOF
269
+ end
270
+ end
271
+ end
272
+
273
+ lexer = Lexer.new([
274
+ # 1 + 2 + 3 LF
275
+ Parser::SYM_NUM,
276
+ Parser::SYM_PLUS,
277
+ Parser::SYM_NUM,
278
+ Parser::SYM_PLUS,
279
+ Parser::SYM_NUM,
280
+ Parser::SYM_LF,
281
+ ])
282
+ Parser.new(debug: true).parse(lexer)
data/lib/lrama/bitmap.rb CHANGED
@@ -1,7 +1,9 @@
1
+ # rbs_inline: enabled
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Lrama
4
5
  module Bitmap
6
+ # @rbs (Array[Integer] ary) -> Integer
5
7
  def self.from_array(ary)
6
8
  bit = 0
7
9
 
@@ -12,8 +14,9 @@ module Lrama
12
14
  bit
13
15
  end
14
16
 
17
+ # @rbs (Integer int) -> Array[Integer]
15
18
  def self.to_array(int)
16
- a = []
19
+ a = [] #: Array[Integer]
17
20
  i = 0
18
21
 
19
22
  while int > 0 do
data/lib/lrama/command.rb CHANGED
@@ -19,7 +19,7 @@ module Lrama
19
19
  text = options.y.read
20
20
  options.y.close if options.y != STDIN
21
21
  begin
22
- grammar = Lrama::Parser.new(text, options.grammar_file, options.debug).parse
22
+ grammar = Lrama::Parser.new(text, options.grammar_file, options.debug, options.define).parse
23
23
  unless grammar.no_stdlib
24
24
  stdlib_grammar = Lrama::Parser.new(File.read(STDLIB_FILE_PATH), STDLIB_FILE_PATH, options.debug).parse
25
25
  grammar.insert_before_parameterizing_rules(stdlib_grammar.parameterizing_rules)
@@ -34,6 +34,7 @@ module Lrama
34
34
  end
35
35
  states = Lrama::States.new(grammar, trace_state: (options.trace_opts[:automaton] || options.trace_opts[:closure]))
36
36
  states.compute
37
+ states.compute_ielr if grammar.ielr_defined?
37
38
  context = Lrama::Context.new(states)
38
39
 
39
40
  if options.report_file
data/lib/lrama/context.rb CHANGED
@@ -405,7 +405,7 @@ module Lrama
405
405
  @check = []
406
406
  # Key is froms_and_tos, value is index position
407
407
  pushed = {}
408
- userd_res = {}
408
+ used_res = {}
409
409
  lowzero = 0
410
410
  high = 0
411
411
 
@@ -430,7 +430,7 @@ module Lrama
430
430
  end
431
431
  end
432
432
 
433
- if ok && userd_res[res]
433
+ if ok && used_res[res]
434
434
  ok = false
435
435
  end
436
436
 
@@ -458,7 +458,7 @@ module Lrama
458
458
 
459
459
  @base[state_id] = res
460
460
  pushed[froms_and_tos] = res
461
- userd_res[res] = true
461
+ used_res[res] = true
462
462
  end
463
463
 
464
464
  @yylast = high
@@ -18,7 +18,7 @@ module Lrama
18
18
  alias :inspect :to_s
19
19
 
20
20
  def render_strings_for_report
21
- result = []
21
+ result = [] #: Array[String]
22
22
  _render_for_report(self, 0, result, 0)
23
23
  result.map(&:rstrip)
24
24
  end
@@ -44,18 +44,19 @@ module Lrama
44
44
  str << "#{item.next_sym.display_name}"
45
45
  length = _render_for_report(derivation.left, len, strings, index + 1)
46
46
  # I want String#ljust!
47
- str << " " * (length - str.length)
47
+ str << " " * (length - str.length) if length > str.length
48
48
  else
49
49
  str << " • #{item.symbols_after_dot.map(&:display_name).join(" ")} "
50
50
  return str.length
51
51
  end
52
52
 
53
53
  if derivation.right&.left
54
- length = _render_for_report(derivation.right.left, str.length, strings, index + 1)
55
- str << "#{item.symbols_after_dot[1..-1].map(&:display_name).join(" ")} "
54
+ left = derivation.right&.left #: Derivation
55
+ length = _render_for_report(left, str.length, strings, index + 1)
56
+ str << "#{item.symbols_after_dot[1..-1].map(&:display_name).join(" ")} " # steep:ignore
56
57
  str << " " * (length - str.length) if length > str.length
57
58
  elsif item.next_next_sym
58
- str << "#{item.symbols_after_dot[1..-1].map(&:display_name).join(" ")} "
59
+ str << "#{item.symbols_after_dot[1..-1].map(&:display_name).join(" ")} " # steep:ignore
59
60
  end
60
61
 
61
62
  return str.length
@@ -38,9 +38,10 @@ module Lrama
38
38
  private
39
39
 
40
40
  def _derivations(paths)
41
- derivation = nil
41
+ derivation = nil #: Derivation
42
42
  current = :production
43
- lookahead_sym = paths.last.to.item.end_of_rule? ? @conflict_symbol : nil
43
+ last_path = paths.last #: Path
44
+ lookahead_sym = last_path.to.item.end_of_rule? ? @conflict_symbol : nil
44
45
 
45
46
  paths.reverse_each do |path|
46
47
  item = path.to.item
@@ -57,12 +58,14 @@ module Lrama
57
58
  when ProductionPath
58
59
  derivation = Derivation.new(item, derivation)
59
60
  current = :production
61
+ else
62
+ raise "Unexpected. #{path}"
60
63
  end
61
64
 
62
65
  if lookahead_sym && item.next_next_sym && item.next_next_sym.first_set.include?(lookahead_sym)
63
66
  state_item = @counterexamples.transitions[[path.to, item.next_sym]]
64
67
  derivation2 = find_derivation_for_symbol(state_item, lookahead_sym)
65
- derivation.right = derivation2
68
+ derivation.right = derivation2 # steep:ignore
66
69
  lookahead_sym = nil
67
70
  end
68
71
 
@@ -89,7 +92,7 @@ module Lrama
89
92
  end
90
93
 
91
94
  def find_derivation_for_symbol(state_item, sym)
92
- queue = []
95
+ queue = [] #: Array[Array[StateItem]]
93
96
  queue << [state_item]
94
97
 
95
98
  while (sis = queue.shift)
@@ -20,6 +20,10 @@ module Lrama
20
20
  "#<Path(#{type})>"
21
21
  end
22
22
  alias :inspect :to_s
23
+
24
+ def type
25
+ raise NotImplementedError
26
+ end
23
27
  end
24
28
  end
25
29
  end