lrama 0.6.2 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|