lrama 0.6.2 → 0.6.4

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yaml +2 -3
  3. data/Gemfile +1 -1
  4. data/NEWS.md +101 -1
  5. data/README.md +23 -0
  6. data/Steepfile +5 -0
  7. data/lib/lrama/context.rb +4 -4
  8. data/lib/lrama/grammar/code/destructor_code.rb +40 -0
  9. data/lib/lrama/grammar/code/initial_action_code.rb +6 -0
  10. data/lib/lrama/grammar/code/no_reference_code.rb +4 -0
  11. data/lib/lrama/grammar/code/printer_code.rb +6 -0
  12. data/lib/lrama/grammar/code/rule_action.rb +11 -1
  13. data/lib/lrama/grammar/code.rb +1 -0
  14. data/lib/lrama/grammar/destructor.rb +9 -0
  15. data/lib/lrama/grammar/reference.rb +4 -3
  16. data/lib/lrama/grammar/rule_builder.rb +10 -3
  17. data/lib/lrama/grammar/stdlib.y +42 -0
  18. data/lib/lrama/grammar/symbol.rb +4 -2
  19. data/lib/lrama/grammar/symbols/resolver.rb +293 -0
  20. data/lib/lrama/grammar/symbols.rb +1 -0
  21. data/lib/lrama/grammar.rb +32 -244
  22. data/lib/lrama/lexer/token/user_code.rb +13 -2
  23. data/lib/lrama/lexer/token.rb +1 -1
  24. data/lib/lrama/lexer.rb +7 -0
  25. data/lib/lrama/option_parser.rb +25 -12
  26. data/lib/lrama/options.rb +1 -0
  27. data/lib/lrama/output.rb +75 -2
  28. data/lib/lrama/parser.rb +537 -464
  29. data/lib/lrama/state.rb +4 -4
  30. data/lib/lrama/states/item.rb +6 -8
  31. data/lib/lrama/states_reporter.rb +2 -2
  32. data/lib/lrama/version.rb +1 -1
  33. data/lrama.gemspec +7 -0
  34. data/parser.y +27 -0
  35. data/sig/lrama/grammar/binding.rbs +0 -1
  36. data/sig/lrama/grammar/code/destructor_code.rbs +15 -0
  37. data/sig/lrama/grammar/destructor.rbs +11 -0
  38. data/sig/lrama/grammar/parameterizing_rule/resolver.rbs +0 -1
  39. data/sig/lrama/grammar/reference.rbs +2 -2
  40. data/sig/lrama/grammar/symbol.rbs +5 -4
  41. data/sig/lrama/grammar/symbols/resolver.rbs +41 -0
  42. data/sig/lrama/grammar/type.rbs +11 -0
  43. data/sig/lrama/options.rbs +17 -0
  44. data/template/bison/yacc.c +12 -1
  45. metadata +17 -3
@@ -38,7 +38,7 @@ module Lrama
38
38
  return Lrama::Grammar::Reference.new(type: :dollar, name: "$", ex_tag: tag, first_column: start, last_column: scanner.pos)
39
39
  when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?(\d+)/) # $1, $2, $<long>1
40
40
  tag = scanner[1] ? Lrama::Lexer::Token::Tag.new(s_value: scanner[1]) : nil
41
- return Lrama::Grammar::Reference.new(type: :dollar, index: Integer(scanner[2]), ex_tag: tag, first_column: start, last_column: scanner.pos)
41
+ return Lrama::Grammar::Reference.new(type: :dollar, number: Integer(scanner[2]), index: Integer(scanner[2]), ex_tag: tag, first_column: start, last_column: scanner.pos)
42
42
  when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?([a-zA-Z_][a-zA-Z0-9_]*)/) # $foo, $expr, $<long>program (named reference without brackets)
43
43
  tag = scanner[1] ? Lrama::Lexer::Token::Tag.new(s_value: scanner[1]) : nil
44
44
  return Lrama::Grammar::Reference.new(type: :dollar, name: scanner[2], ex_tag: tag, first_column: start, last_column: scanner.pos)
@@ -51,11 +51,22 @@ module Lrama
51
51
  when scanner.scan(/@\$/) # @$
52
52
  return Lrama::Grammar::Reference.new(type: :at, name: "$", first_column: start, last_column: scanner.pos)
53
53
  when scanner.scan(/@(\d+)/) # @1
54
- return Lrama::Grammar::Reference.new(type: :at, index: Integer(scanner[1]), first_column: start, last_column: scanner.pos)
54
+ return Lrama::Grammar::Reference.new(type: :at, number: Integer(scanner[1]), index: Integer(scanner[1]), first_column: start, last_column: scanner.pos)
55
55
  when scanner.scan(/@([a-zA-Z][a-zA-Z0-9_]*)/) # @foo, @expr (named reference without brackets)
56
56
  return Lrama::Grammar::Reference.new(type: :at, name: scanner[1], first_column: start, last_column: scanner.pos)
57
57
  when scanner.scan(/@\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # @[expr.right], @[expr-right] (named reference with brackets)
58
58
  return Lrama::Grammar::Reference.new(type: :at, name: scanner[1], first_column: start, last_column: scanner.pos)
59
+
60
+ # $: references
61
+ when scanner.scan(/\$:\$/) # $:$
62
+ return Lrama::Grammar::Reference.new(type: :index, name: "$", first_column: start, last_column: scanner.pos)
63
+ when scanner.scan(/\$:(\d+)/) # $:1
64
+ return Lrama::Grammar::Reference.new(type: :index, number: Integer(scanner[1]), first_column: start, last_column: scanner.pos)
65
+ when scanner.scan(/\$:([a-zA-Z_][a-zA-Z0-9_]*)/) # $:foo, $:expr (named reference without brackets)
66
+ return Lrama::Grammar::Reference.new(type: :index, name: scanner[1], first_column: start, last_column: scanner.pos)
67
+ when scanner.scan(/\$:\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # $:[expr.right], $:[expr-right] (named reference with brackets)
68
+ return Lrama::Grammar::Reference.new(type: :index, name: scanner[1], first_column: start, last_column: scanner.pos)
69
+
59
70
  end
60
71
  end
61
72
  end
@@ -18,7 +18,7 @@ module Lrama
18
18
  end
19
19
 
20
20
  def to_s
21
- "#{super} location: #{location}"
21
+ "value: `#{s_value}`, location: #{location}"
22
22
  end
23
23
 
24
24
  def referred_by?(string)
data/lib/lrama/lexer.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "strscan"
2
+
2
3
  require "lrama/lexer/grammar_file"
3
4
  require "lrama/lexer/location"
4
5
  require "lrama/lexer/token"
@@ -20,12 +21,18 @@ module Lrama
20
21
  %define
21
22
  %require
22
23
  %printer
24
+ %destructor
23
25
  %lex-param
24
26
  %parse-param
25
27
  %initial-action
26
28
  %precedence
27
29
  %prec
28
30
  %error-token
31
+ %before-reduce
32
+ %after-reduce
33
+ %after-shift-error-token
34
+ %after-shift
35
+ %after-pop-stack
29
36
  %empty
30
37
  %code
31
38
  %rule
@@ -64,9 +64,18 @@ module Lrama
64
64
  o.on('-H', '--header=[FILE]', 'also produce a header file named FILE') {|v| @options.header = true; @options.header_file = v }
65
65
  o.on('-d', 'also produce a header file') { @options.header = true }
66
66
  o.on('-r', '--report=THINGS', Array, 'also produce details on the automaton') {|v| @report = v }
67
+ o.on_tail ''
68
+ o.on_tail 'Valid Reports:'
69
+ o.on_tail " #{VALID_REPORTS.join(' ')}"
70
+
67
71
  o.on('--report-file=FILE', 'also produce details on the automaton output to a file named FILE') {|v| @options.report_file = v }
68
72
  o.on('-o', '--output=FILE', 'leave output to FILE') {|v| @options.outfile = v }
73
+
69
74
  o.on('--trace=THINGS', Array, 'also output trace logs at runtime') {|v| @trace = v }
75
+ o.on_tail ''
76
+ o.on_tail 'Valid Traces:'
77
+ o.on_tail " #{VALID_TRACES.join(' ')}"
78
+
70
79
  o.on('-v', 'reserved, do nothing') { }
71
80
  o.separator ''
72
81
  o.separator 'Error Recovery:'
@@ -75,20 +84,22 @@ module Lrama
75
84
  o.separator 'Other options:'
76
85
  o.on('-V', '--version', "output version information and exit") {|v| puts "lrama #{Lrama::VERSION}"; exit 0 }
77
86
  o.on('-h', '--help', "display this help and exit") {|v| puts o; exit 0 }
78
- o.separator ''
87
+ o.on_tail
79
88
  o.parse!(argv)
80
89
  end
81
90
  end
82
91
 
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
96
+
83
97
  def validate_report(report)
84
- bison_list = %w[states itemsets lookaheads solved counterexamples cex all none]
85
- others = %w[verbose]
86
- list = bison_list + others
87
- not_supported = %w[cex none]
98
+ list = VALID_REPORTS
88
99
  h = { grammar: true }
89
100
 
90
101
  report.each do |r|
91
- if list.include?(r) && !not_supported.include?(r)
102
+ if list.include?(r)
92
103
  h[r.to_sym] = true
93
104
  else
94
105
  raise "Invalid report option \"#{r}\"."
@@ -96,7 +107,7 @@ module Lrama
96
107
  end
97
108
 
98
109
  if h[:all]
99
- (bison_list - not_supported).each do |r|
110
+ (BISON_REPORTS - NOT_SUPPORTED_REPORTS).each do |r|
100
111
  h[r.to_sym] = true
101
112
  end
102
113
 
@@ -106,12 +117,14 @@ module Lrama
106
117
  return h
107
118
  end
108
119
 
120
+ VALID_TRACES = %w[
121
+ none locations scan parse automaton bitsets
122
+ closure grammar rules resource sets muscles tools
123
+ m4-early m4 skeleton time ielr cex all
124
+ ]
125
+
109
126
  def validate_trace(trace)
110
- list = %w[
111
- none locations scan parse automaton bitsets
112
- closure grammar rules resource sets muscles tools
113
- m4-early m4 skeleton time ielr cex all
114
- ]
127
+ list = VALID_TRACES
115
128
  h = {}
116
129
 
117
130
  trace.each do |t|
data/lib/lrama/options.rb CHANGED
@@ -18,6 +18,7 @@ module Lrama
18
18
  @trace_opts = nil
19
19
  @report_opts = nil
20
20
  @y = STDIN
21
+ @debug = false
21
22
  end
22
23
  end
23
24
  end
data/lib/lrama/output.rb CHANGED
@@ -16,8 +16,7 @@ module Lrama
16
16
 
17
17
  def initialize(
18
18
  out:, output_file_path:, template_name:, grammar_file_path:,
19
- header_out: nil, header_file_path: nil,
20
- context:, grammar:, error_recovery: false
19
+ context:, grammar:, header_out: nil, header_file_path: nil, error_recovery: false
21
20
  )
22
21
  @out = out
23
22
  @output_file_path = output_file_path
@@ -151,6 +150,25 @@ module Lrama
151
150
  str
152
151
  end
153
152
 
153
+ def symbol_actions_for_destructor
154
+ str = ""
155
+
156
+ @grammar.symbols.each do |sym|
157
+ next unless sym.destructor
158
+
159
+ str << <<-STR
160
+ case #{sym.enum_name}: /* #{sym.comment} */
161
+ #line #{sym.destructor.lineno} "#{@grammar_file_path}"
162
+ {#{sym.destructor.translated_code(sym.tag)}}
163
+ #line [@oline@] [@ofile@]
164
+ break;
165
+
166
+ STR
167
+ end
168
+
169
+ str
170
+ end
171
+
154
172
  # b4_user_initial_action
155
173
  def user_initial_action(comment = "")
156
174
  return "" unless @grammar.initial_action
@@ -162,6 +180,61 @@ module Lrama
162
180
  STR
163
181
  end
164
182
 
183
+ def after_shift_function(comment = "")
184
+ return "" unless @grammar.after_shift
185
+
186
+ <<-STR
187
+ #{comment}
188
+ #line #{@grammar.after_shift.line} "#{@grammar_file_path}"
189
+ {#{@grammar.after_shift.s_value}(#{parse_param_name});}
190
+ #line [@oline@] [@ofile@]
191
+ STR
192
+ end
193
+
194
+ def before_reduce_function(comment = "")
195
+ return "" unless @grammar.before_reduce
196
+
197
+ <<-STR
198
+ #{comment}
199
+ #line #{@grammar.before_reduce.line} "#{@grammar_file_path}"
200
+ {#{@grammar.before_reduce.s_value}(yylen#{user_args});}
201
+ #line [@oline@] [@ofile@]
202
+ STR
203
+ end
204
+
205
+ def after_reduce_function(comment = "")
206
+ return "" unless @grammar.after_reduce
207
+
208
+ <<-STR
209
+ #{comment}
210
+ #line #{@grammar.after_reduce.line} "#{@grammar_file_path}"
211
+ {#{@grammar.after_reduce.s_value}(yylen#{user_args});}
212
+ #line [@oline@] [@ofile@]
213
+ STR
214
+ end
215
+
216
+ def after_shift_error_token_function(comment = "")
217
+ return "" unless @grammar.after_shift_error_token
218
+
219
+ <<-STR
220
+ #{comment}
221
+ #line #{@grammar.after_shift_error_token.line} "#{@grammar_file_path}"
222
+ {#{@grammar.after_shift_error_token.s_value}(#{parse_param_name});}
223
+ #line [@oline@] [@ofile@]
224
+ STR
225
+ end
226
+
227
+ def after_pop_stack_function(len, comment = "")
228
+ return "" unless @grammar.after_pop_stack
229
+
230
+ <<-STR
231
+ #{comment}
232
+ #line #{@grammar.after_pop_stack.line} "#{@grammar_file_path}"
233
+ {#{@grammar.after_pop_stack.s_value}(#{len}#{user_args});}
234
+ #line [@oline@] [@ofile@]
235
+ STR
236
+ end
237
+
165
238
  def symbol_actions_for_error_token
166
239
  str = ""
167
240