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.
- checksums.yaml +4 -4
- data/.github/workflows/test.yaml +2 -3
- data/Gemfile +1 -1
- data/NEWS.md +101 -1
- data/README.md +23 -0
- data/Steepfile +5 -0
- data/lib/lrama/context.rb +4 -4
- data/lib/lrama/grammar/code/destructor_code.rb +40 -0
- data/lib/lrama/grammar/code/initial_action_code.rb +6 -0
- data/lib/lrama/grammar/code/no_reference_code.rb +4 -0
- data/lib/lrama/grammar/code/printer_code.rb +6 -0
- data/lib/lrama/grammar/code/rule_action.rb +11 -1
- data/lib/lrama/grammar/code.rb +1 -0
- data/lib/lrama/grammar/destructor.rb +9 -0
- data/lib/lrama/grammar/reference.rb +4 -3
- data/lib/lrama/grammar/rule_builder.rb +10 -3
- data/lib/lrama/grammar/stdlib.y +42 -0
- data/lib/lrama/grammar/symbol.rb +4 -2
- data/lib/lrama/grammar/symbols/resolver.rb +293 -0
- data/lib/lrama/grammar/symbols.rb +1 -0
- data/lib/lrama/grammar.rb +32 -244
- data/lib/lrama/lexer/token/user_code.rb +13 -2
- data/lib/lrama/lexer/token.rb +1 -1
- data/lib/lrama/lexer.rb +7 -0
- data/lib/lrama/option_parser.rb +25 -12
- data/lib/lrama/options.rb +1 -0
- data/lib/lrama/output.rb +75 -2
- data/lib/lrama/parser.rb +537 -464
- data/lib/lrama/state.rb +4 -4
- data/lib/lrama/states/item.rb +6 -8
- data/lib/lrama/states_reporter.rb +2 -2
- data/lib/lrama/version.rb +1 -1
- data/lrama.gemspec +7 -0
- data/parser.y +27 -0
- data/sig/lrama/grammar/binding.rbs +0 -1
- data/sig/lrama/grammar/code/destructor_code.rbs +15 -0
- data/sig/lrama/grammar/destructor.rbs +11 -0
- data/sig/lrama/grammar/parameterizing_rule/resolver.rbs +0 -1
- data/sig/lrama/grammar/reference.rbs +2 -2
- data/sig/lrama/grammar/symbol.rbs +5 -4
- data/sig/lrama/grammar/symbols/resolver.rbs +41 -0
- data/sig/lrama/grammar/type.rbs +11 -0
- data/sig/lrama/options.rbs +17 -0
- data/template/bison/yacc.c +12 -1
- 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
|
data/lib/lrama/lexer/token.rb
CHANGED
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
|
data/lib/lrama/option_parser.rb
CHANGED
@@ -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.
|
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
|
-
|
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)
|
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
|
-
(
|
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 =
|
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
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
|
|