lrama 0.6.9 → 0.6.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yaml +24 -1
  3. data/.gitignore +2 -0
  4. data/Gemfile +6 -3
  5. data/NEWS.md +269 -14
  6. data/README.md +41 -4
  7. data/Rakefile +2 -0
  8. data/Steepfile +9 -17
  9. data/doc/development/compressed_state_table/main.md +635 -0
  10. data/doc/development/compressed_state_table/parse.output +174 -0
  11. data/doc/development/compressed_state_table/parse.y +22 -0
  12. data/doc/development/compressed_state_table/parser.rb +282 -0
  13. data/exe/lrama +1 -0
  14. data/lib/lrama/bitmap.rb +3 -1
  15. data/lib/lrama/command.rb +8 -14
  16. data/lib/lrama/context.rb +11 -9
  17. data/lib/lrama/counterexamples/derivation.rb +8 -5
  18. data/lib/lrama/counterexamples/example.rb +9 -4
  19. data/lib/lrama/counterexamples/path.rb +6 -0
  20. data/lib/lrama/counterexamples/production_path.rb +2 -0
  21. data/lib/lrama/counterexamples/start_path.rb +2 -0
  22. data/lib/lrama/counterexamples/state_item.rb +2 -0
  23. data/lib/lrama/counterexamples/transition_path.rb +2 -0
  24. data/lib/lrama/counterexamples/triple.rb +2 -0
  25. data/lib/lrama/counterexamples.rb +36 -24
  26. data/lib/lrama/diagnostics.rb +36 -0
  27. data/lib/lrama/digraph.rb +2 -0
  28. data/lib/lrama/grammar/auxiliary.rb +2 -0
  29. data/lib/lrama/grammar/binding.rb +12 -1
  30. data/lib/lrama/grammar/code/destructor_code.rb +2 -0
  31. data/lib/lrama/grammar/code/initial_action_code.rb +2 -0
  32. data/lib/lrama/grammar/code/no_reference_code.rb +2 -0
  33. data/lib/lrama/grammar/code/printer_code.rb +2 -0
  34. data/lib/lrama/grammar/code/rule_action.rb +7 -3
  35. data/lib/lrama/grammar/code.rb +7 -5
  36. data/lib/lrama/grammar/counter.rb +2 -0
  37. data/lib/lrama/grammar/destructor.rb +2 -0
  38. data/lib/lrama/grammar/error_token.rb +2 -0
  39. data/lib/lrama/grammar/parameterizing_rule/resolver.rb +7 -1
  40. data/lib/lrama/grammar/parameterizing_rule/rhs.rb +6 -3
  41. data/lib/lrama/grammar/parameterizing_rule/rule.rb +6 -0
  42. data/lib/lrama/grammar/parameterizing_rule.rb +2 -0
  43. data/lib/lrama/grammar/percent_code.rb +2 -0
  44. data/lib/lrama/grammar/precedence.rb +2 -0
  45. data/lib/lrama/grammar/printer.rb +2 -0
  46. data/lib/lrama/grammar/reference.rb +2 -0
  47. data/lib/lrama/grammar/rule.rb +10 -3
  48. data/lib/lrama/grammar/rule_builder.rb +64 -65
  49. data/lib/lrama/grammar/symbol.rb +2 -0
  50. data/lib/lrama/grammar/symbols/resolver.rb +9 -1
  51. data/lib/lrama/grammar/symbols.rb +2 -0
  52. data/lib/lrama/grammar/type.rb +2 -0
  53. data/lib/lrama/grammar/union.rb +2 -0
  54. data/lib/lrama/grammar.rb +53 -32
  55. data/lib/lrama/grammar_validator.rb +37 -0
  56. data/lib/lrama/lexer/grammar_file.rb +2 -0
  57. data/lib/lrama/lexer/location.rb +2 -0
  58. data/lib/lrama/lexer/token/char.rb +2 -0
  59. data/lib/lrama/lexer/token/ident.rb +2 -0
  60. data/lib/lrama/lexer/token/instantiate_rule.rb +2 -0
  61. data/lib/lrama/lexer/token/tag.rb +2 -0
  62. data/lib/lrama/lexer/token/user_code.rb +4 -2
  63. data/lib/lrama/lexer/token.rb +7 -5
  64. data/lib/lrama/lexer.rb +12 -8
  65. data/lib/lrama/{warning.rb → logger.rb} +5 -13
  66. data/lib/lrama/option_parser.rb +58 -33
  67. data/lib/lrama/options.rb +5 -2
  68. data/lib/lrama/output.rb +38 -69
  69. data/lib/lrama/parser.rb +677 -773
  70. data/lib/lrama/report/duration.rb +2 -0
  71. data/lib/lrama/report/profile.rb +2 -0
  72. data/lib/lrama/report.rb +4 -2
  73. data/lib/lrama/state/reduce.rb +4 -2
  74. data/lib/lrama/state/reduce_reduce_conflict.rb +2 -0
  75. data/lib/lrama/state/resolved_conflict.rb +3 -1
  76. data/lib/lrama/state/shift.rb +2 -0
  77. data/lib/lrama/state/shift_reduce_conflict.rb +2 -0
  78. data/lib/lrama/state.rb +7 -5
  79. data/lib/lrama/states/item.rb +5 -3
  80. data/lib/lrama/states.rb +18 -46
  81. data/lib/lrama/states_reporter.rb +60 -19
  82. data/lib/lrama/trace_reporter.rb +30 -0
  83. data/lib/lrama/version.rb +3 -1
  84. data/lib/lrama.rb +22 -17
  85. data/lrama.gemspec +3 -1
  86. data/parser.y +129 -237
  87. data/rbs_collection.lock.yaml +10 -2
  88. data/sig/lrama/counterexamples/derivation.rbs +33 -0
  89. data/sig/lrama/counterexamples/example.rbs +45 -0
  90. data/sig/lrama/counterexamples/path.rbs +21 -0
  91. data/sig/lrama/counterexamples/production_path.rbs +11 -0
  92. data/sig/lrama/counterexamples/start_path.rbs +13 -0
  93. data/sig/lrama/counterexamples/state_item.rbs +10 -0
  94. data/sig/lrama/counterexamples/transition_path.rbs +11 -0
  95. data/sig/lrama/counterexamples/triple.rbs +20 -0
  96. data/sig/lrama/counterexamples.rbs +29 -0
  97. data/sig/lrama/grammar/auxiliary.rbs +10 -0
  98. data/sig/lrama/grammar/binding.rbs +4 -0
  99. data/sig/lrama/grammar/code/destructor_code.rbs +3 -4
  100. data/sig/lrama/grammar/code/initial_action_code.rbs +15 -0
  101. data/sig/lrama/grammar/code/no_reference_code.rbs +15 -0
  102. data/sig/lrama/grammar/code/printer_code.rbs +3 -4
  103. data/sig/lrama/grammar/code/rule_action.rbs +19 -0
  104. data/sig/lrama/grammar/code.rbs +3 -3
  105. data/sig/lrama/grammar/destructor.rbs +3 -1
  106. data/sig/lrama/grammar/error_token.rbs +4 -2
  107. data/sig/lrama/grammar/parameterizing_rule/resolver.rbs +2 -1
  108. data/sig/lrama/grammar/parameterizing_rule/rhs.rbs +1 -1
  109. data/sig/lrama/grammar/precedence.rbs +3 -1
  110. data/sig/lrama/grammar/printer.rbs +3 -1
  111. data/sig/lrama/grammar/rule.rbs +35 -3
  112. data/sig/lrama/grammar/rule_builder.rbs +10 -9
  113. data/sig/lrama/grammar/symbol.rbs +6 -6
  114. data/sig/lrama/grammar/symbols/resolver.rbs +24 -5
  115. data/sig/lrama/grammar/type.rbs +2 -2
  116. data/sig/lrama/grammar/union.rbs +12 -0
  117. data/sig/lrama/grammar.rbs +104 -1
  118. data/sig/lrama/options.rbs +3 -2
  119. data/sig/lrama/state/reduce.rbs +20 -0
  120. data/sig/lrama/state/reduce_reduce_conflict.rbs +13 -0
  121. data/sig/lrama/state/resolved_conflict.rbs +14 -0
  122. data/sig/lrama/state/shift.rbs +14 -0
  123. data/sig/lrama/state/shift_reduce_conflict.rbs +13 -0
  124. data/sig/lrama/state.rbs +79 -0
  125. data/sig/lrama/states/item.rbs +30 -0
  126. data/sig/lrama/states.rbs +101 -0
  127. data/template/bison/yacc.c +24 -19
  128. metadata +32 -6
  129. data/sample/calc.output +0 -263
  130. data/sample/calc.y +0 -101
  131. data/sample/parse.y +0 -59
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'optparse'
2
4
 
3
5
  module Lrama
@@ -16,7 +18,7 @@ module Lrama
16
18
  @options.report_opts = validate_report(@report)
17
19
  @options.grammar_file = argv.shift
18
20
 
19
- if !@options.grammar_file
21
+ unless @options.grammar_file
20
22
  abort "File should be specified\n"
21
23
  end
22
24
 
@@ -63,20 +65,35 @@ module Lrama
63
65
  o.separator 'Output:'
64
66
  o.on('-H', '--header=[FILE]', 'also produce a header file named FILE') {|v| @options.header = true; @options.header_file = v }
65
67
  o.on('-d', 'also produce a header file') { @options.header = true }
66
- o.on('-r', '--report=THINGS', Array, 'also produce details on the automaton') {|v| @report = v }
68
+ o.on('-r', '--report=REPORTS', Array, 'also produce details on the automaton') {|v| @report = v }
67
69
  o.on_tail ''
68
- o.on_tail 'Valid Reports:'
69
- o.on_tail " #{VALID_REPORTS.join(' ')}"
70
-
70
+ o.on_tail 'REPORTS is a list of comma-separated words that can include:'
71
+ o.on_tail ' states describe the states'
72
+ o.on_tail ' itemsets complete the core item sets with their closure'
73
+ o.on_tail ' lookaheads explicitly associate lookahead tokens to items'
74
+ o.on_tail ' solved describe shift/reduce conflicts solving'
75
+ o.on_tail ' counterexamples, cex generate conflict counterexamples'
76
+ o.on_tail ' rules list unused rules'
77
+ o.on_tail ' terms list unused terminals'
78
+ o.on_tail ' verbose report detailed internal state and analysis results'
79
+ o.on_tail ' all include all the above reports'
80
+ o.on_tail ' none disable all reports'
71
81
  o.on('--report-file=FILE', 'also produce details on the automaton output to a file named FILE') {|v| @options.report_file = v }
72
82
  o.on('-o', '--output=FILE', 'leave output to FILE') {|v| @options.outfile = v }
73
-
74
- o.on('--trace=THINGS', Array, 'also output trace logs at runtime') {|v| @trace = v }
83
+ o.on('--trace=TRACES', Array, 'also output trace logs at runtime') {|v| @trace = v }
75
84
  o.on_tail ''
76
- o.on_tail 'Valid Traces:'
77
- o.on_tail " #{VALID_TRACES.join(' ')}"
78
-
79
- o.on('-v', 'reserved, do nothing') { }
85
+ o.on_tail 'TRACES is a list of comma-separated words that can include:'
86
+ o.on_tail ' automaton display states'
87
+ o.on_tail ' closure display states'
88
+ o.on_tail ' rules display grammar rules'
89
+ o.on_tail ' actions display grammar rules with actions'
90
+ o.on_tail ' time display generation time'
91
+ o.on_tail ' all include all the above traces'
92
+ o.on_tail ' none disable all traces'
93
+ o.on('-v', '--verbose', "same as '--report=state'") {|_v| @report << 'states' }
94
+ o.separator ''
95
+ o.separator 'Diagnostics:'
96
+ o.on('-W', '--warnings', 'report the warnings') {|v| @options.diagnostic = true }
80
97
  o.separator ''
81
98
  o.separator 'Error Recovery:'
82
99
  o.on('-e', 'enable error recovery') {|v| @options.error_recovery = true }
@@ -89,47 +106,55 @@ module Lrama
89
106
  end
90
107
  end
91
108
 
92
- BISON_REPORTS = %w[states itemsets lookaheads solved counterexamples cex all none]
93
- OTHER_REPORTS = %w[verbose]
94
- NOT_SUPPORTED_REPORTS = %w[cex none]
95
- VALID_REPORTS = BISON_REPORTS + OTHER_REPORTS - NOT_SUPPORTED_REPORTS
109
+ ALIASED_REPORTS = { cex: :counterexamples }.freeze
110
+ VALID_REPORTS = %i[states itemsets lookaheads solved counterexamples rules terms verbose].freeze
96
111
 
97
112
  def validate_report(report)
98
- list = VALID_REPORTS
99
113
  h = { grammar: true }
114
+ return h if report.empty?
115
+ return {} if report == ['none']
116
+ if report == ['all']
117
+ VALID_REPORTS.each { |r| h[r] = true }
118
+ return h
119
+ end
100
120
 
101
121
  report.each do |r|
102
- if list.include?(r)
103
- h[r.to_sym] = true
122
+ aliased = aliased_report_option(r)
123
+ if VALID_REPORTS.include?(aliased)
124
+ h[aliased] = true
104
125
  else
105
126
  raise "Invalid report option \"#{r}\"."
106
127
  end
107
128
  end
108
129
 
109
- if h[:all]
110
- (BISON_REPORTS - NOT_SUPPORTED_REPORTS).each do |r|
111
- h[r.to_sym] = true
112
- end
113
-
114
- h.delete(:all)
115
- end
116
-
117
130
  return h
118
131
  end
119
132
 
133
+ def aliased_report_option(opt)
134
+ (ALIASED_REPORTS[opt.to_sym] || opt).to_sym
135
+ end
136
+
120
137
  VALID_TRACES = %w[
121
- none locations scan parse automaton bitsets
122
- closure grammar rules actions resource
123
- sets muscles tools m4-early m4 skeleton time
124
- ielr cex all
125
- ]
138
+ locations scan parse automaton bitsets closure
139
+ grammar rules actions resource sets muscles
140
+ tools m4-early m4 skeleton time ielr cex
141
+ ].freeze
142
+ NOT_SUPPORTED_TRACES = %w[
143
+ locations scan parse bitsets grammar resource
144
+ sets muscles tools m4-early m4 skeleton ielr cex
145
+ ].freeze
126
146
 
127
147
  def validate_trace(trace)
128
- list = VALID_TRACES
129
148
  h = {}
149
+ return h if trace.empty? || trace == ['none']
150
+ supported = VALID_TRACES - NOT_SUPPORTED_TRACES
151
+ if trace == ['all']
152
+ supported.each { |t| h[t.to_sym] = true }
153
+ return h
154
+ end
130
155
 
131
156
  trace.each do |t|
132
- if list.include?(t)
157
+ if supported.include?(t)
133
158
  h[t.to_sym] = true
134
159
  else
135
160
  raise "Invalid trace option \"#{t}\"."
data/lib/lrama/options.rb CHANGED
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  # Command line options.
3
5
  class Options
4
6
  attr_accessor :skeleton, :header, :header_file,
5
7
  :report_file, :outfile,
6
8
  :error_recovery, :grammar_file,
7
- :trace_opts, :report_opts, :y,
8
- :debug
9
+ :trace_opts, :report_opts,
10
+ :diagnostic, :y, :debug
9
11
 
10
12
  def initialize
11
13
  @skeleton = "bison/yacc.c"
@@ -17,6 +19,7 @@ module Lrama
17
19
  @grammar_file = nil
18
20
  @trace_opts = nil
19
21
  @report_opts = nil
22
+ @diagnostic = false
20
23
  @y = STDIN
21
24
  @debug = false
22
25
  end
data/lib/lrama/output.rb CHANGED
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "erb"
2
4
  require "forwardable"
3
- require "lrama/report/duration"
5
+ require_relative "report/duration"
4
6
 
5
7
  module Lrama
6
8
  class Output
@@ -63,37 +65,29 @@ module Lrama
63
65
 
64
66
  # A part of b4_token_enums
65
67
  def token_enums
66
- str = ""
67
-
68
- @context.yytokentype.each do |s_value, token_id, display_name|
68
+ @context.yytokentype.map do |s_value, token_id, display_name|
69
69
  s = sprintf("%s = %d%s", s_value, token_id, token_id == yymaxutok ? "" : ",")
70
70
 
71
71
  if display_name
72
- str << sprintf(" %-30s /* %s */\n", s, display_name)
72
+ sprintf(" %-30s /* %s */\n", s, display_name)
73
73
  else
74
- str << sprintf(" %s\n", s)
74
+ sprintf(" %s\n", s)
75
75
  end
76
- end
77
-
78
- str
76
+ end.join
79
77
  end
80
78
 
81
79
  # b4_symbol_enum
82
80
  def symbol_enum
83
- str = ""
84
-
85
81
  last_sym_number = @context.yysymbol_kind_t.last[1]
86
- @context.yysymbol_kind_t.each do |s_value, sym_number, display_name|
82
+ @context.yysymbol_kind_t.map do |s_value, sym_number, display_name|
87
83
  s = sprintf("%s = %d%s", s_value, sym_number, (sym_number == last_sym_number) ? "" : ",")
88
84
 
89
85
  if display_name
90
- str << sprintf(" %-40s /* %s */\n", s, display_name)
86
+ sprintf(" %-40s /* %s */\n", s, display_name)
91
87
  else
92
- str << sprintf(" %s\n", s)
88
+ sprintf(" %s\n", s)
93
89
  end
94
- end
95
-
96
- str
90
+ end.join
97
91
  end
98
92
 
99
93
  def yytranslate
@@ -132,12 +126,10 @@ module Lrama
132
126
  end
133
127
 
134
128
  def symbol_actions_for_printer
135
- str = ""
136
-
137
- @grammar.symbols.each do |sym|
129
+ @grammar.symbols.map do |sym|
138
130
  next unless sym.printer
139
131
 
140
- str << <<-STR
132
+ <<-STR
141
133
  case #{sym.enum_name}: /* #{sym.comment} */
142
134
  #line #{sym.printer.lineno} "#{@grammar_file_path}"
143
135
  {#{sym.printer.translated_code(sym.tag)}}
@@ -145,18 +137,14 @@ module Lrama
145
137
  break;
146
138
 
147
139
  STR
148
- end
149
-
150
- str
140
+ end.join
151
141
  end
152
142
 
153
143
  def symbol_actions_for_destructor
154
- str = ""
155
-
156
- @grammar.symbols.each do |sym|
144
+ @grammar.symbols.map do |sym|
157
145
  next unless sym.destructor
158
146
 
159
- str << <<-STR
147
+ <<-STR
160
148
  case #{sym.enum_name}: /* #{sym.comment} */
161
149
  #line #{sym.destructor.lineno} "#{@grammar_file_path}"
162
150
  {#{sym.destructor.translated_code(sym.tag)}}
@@ -164,9 +152,7 @@ module Lrama
164
152
  break;
165
153
 
166
154
  STR
167
- end
168
-
169
- str
155
+ end.join
170
156
  end
171
157
 
172
158
  # b4_user_initial_action
@@ -236,12 +222,10 @@ module Lrama
236
222
  end
237
223
 
238
224
  def symbol_actions_for_error_token
239
- str = ""
240
-
241
- @grammar.symbols.each do |sym|
225
+ @grammar.symbols.map do |sym|
242
226
  next unless sym.error_token
243
227
 
244
- str << <<-STR
228
+ <<-STR
245
229
  case #{sym.enum_name}: /* #{sym.comment} */
246
230
  #line #{sym.error_token.lineno} "#{@grammar_file_path}"
247
231
  {#{sym.error_token.translated_code(sym.tag)}}
@@ -249,22 +233,18 @@ module Lrama
249
233
  break;
250
234
 
251
235
  STR
252
- end
253
-
254
- str
236
+ end.join
255
237
  end
256
238
 
257
239
  # b4_user_actions
258
240
  def user_actions
259
- str = ""
260
-
261
- @context.states.rules.each do |rule|
241
+ action = @context.states.rules.map do |rule|
262
242
  next unless rule.token_code
263
243
 
264
244
  code = rule.token_code
265
245
  spaces = " " * (code.column - 1)
266
246
 
267
- str << <<-STR
247
+ <<-STR
268
248
  case #{rule.id + 1}: /* #{rule.as_comment} */
269
249
  #line #{code.line} "#{@grammar_file_path}"
270
250
  #{spaces}{#{rule.translated_code}}
@@ -272,14 +252,12 @@ module Lrama
272
252
  break;
273
253
 
274
254
  STR
275
- end
255
+ end.join
276
256
 
277
- str << <<-STR
257
+ action + <<-STR
278
258
 
279
259
  #line [@oline@] [@ofile@]
280
260
  STR
281
-
282
- str
283
261
  end
284
262
 
285
263
  def omit_blanks(param)
@@ -343,7 +321,7 @@ module Lrama
343
321
 
344
322
  # b4_parse_param_use
345
323
  def parse_param_use(val, loc)
346
- str = <<-STR
324
+ str = <<-STR.dup
347
325
  YY_USE (#{val});
348
326
  YY_USE (#{loc});
349
327
  STR
@@ -357,7 +335,8 @@ module Lrama
357
335
 
358
336
  # b4_yylex_formals
359
337
  def yylex_formals
360
- ary = ["&yylval", "&yylloc"]
338
+ ary = ["&yylval"]
339
+ ary << "&yylloc" if @grammar.locations
361
340
 
362
341
  if @grammar.lex_param
363
342
  ary << lex_param_name
@@ -397,17 +376,9 @@ module Lrama
397
376
  def int_array_to_string(ary)
398
377
  last = ary.count - 1
399
378
 
400
- s = ary.each_with_index.each_slice(10).map do |slice|
401
- str = " "
402
-
403
- slice.each do |e, i|
404
- str << sprintf("%6d%s", e, (i == last) ? "" : ",")
405
- end
406
-
407
- str
408
- end
409
-
410
- s.join("\n")
379
+ ary.each_with_index.each_slice(10).map do |slice|
380
+ " " + slice.map { |e, i| sprintf("%6d%s", e, (i == last) ? "" : ",") }.join
381
+ end.join("\n")
411
382
  end
412
383
 
413
384
  def spec_mapped_header_file
@@ -457,26 +428,24 @@ module Lrama
457
428
  end
458
429
 
459
430
  def template_dir
460
- File.expand_path("../../../template", __FILE__)
431
+ File.expand_path('../../template', __dir__)
461
432
  end
462
433
 
463
434
  def string_array_to_string(ary)
464
- str = ""
435
+ result = ""
465
436
  tmp = " "
466
437
 
467
438
  ary.each do |s|
468
- s = s.gsub('\\', '\\\\\\\\')
469
- s = s.gsub('"', '\\"')
470
-
471
- if (tmp + s + " \"\",").length > 75
472
- str << tmp << "\n"
473
- tmp = " \"#{s}\","
439
+ replaced = s.gsub('\\', '\\\\\\\\').gsub('"', '\\"')
440
+ if (tmp + replaced + " \"\",").length > 75
441
+ result = "#{result}#{tmp}\n"
442
+ tmp = " \"#{replaced}\","
474
443
  else
475
- tmp << " \"#{s}\","
444
+ tmp = "#{tmp} \"#{replaced}\","
476
445
  end
477
446
  end
478
447
 
479
- str << tmp
448
+ result + tmp
480
449
  end
481
450
 
482
451
  def replace_special_variables(str, ofile)