lrama 0.5.4 → 0.5.5
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 +14 -0
- data/Gemfile +3 -2
- data/exe/lrama +0 -1
- data/lib/lrama/command.rb +2 -7
- data/lib/lrama/context.rb +0 -2
- data/lib/lrama/counterexamples.rb +1 -3
- data/lib/lrama/grammar/code.rb +0 -1
- data/lib/lrama/grammar.rb +5 -2
- data/lib/lrama/lexer/token.rb +1 -0
- data/lib/lrama/lexer.rb +3 -4
- data/lib/lrama/output.rb +1 -1
- data/lib/lrama/parser.rb +8 -0
- data/lib/lrama/state.rb +0 -1
- data/lib/lrama/states.rb +7 -2
- data/lib/lrama/states_reporter.rb +4 -16
- data/lib/lrama/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d79363afacc07dac12ab5c1a861123e099626591104079c962e02f3df74a24f3
|
4
|
+
data.tar.gz: d8ddf78087e27510ab9da808301505a10ec0151ef55d1df3a59cc80ffde81b53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acc15bb56862ea03c6b195253ba881786acf498719f930b8a8435a60f86b44d4383778cc215e7497971833c4be596a9c41a6c5134f77703a9f5cd0a6b5714ad2
|
7
|
+
data.tar.gz: d45b2ec3a22ce2e29beb6a5ec0f4d7b142cebca3b6ca76786fa19b841c257d3841d5a7a43d7d564459b8f9c5b05faa7229bd9b2e2178592ec3988b64f77b535c
|
data/.github/workflows/test.yaml
CHANGED
@@ -22,6 +22,20 @@ jobs:
|
|
22
22
|
bundler-cache: true
|
23
23
|
- run: bundle install
|
24
24
|
- run: bundle exec rspec
|
25
|
+
test-windows:
|
26
|
+
runs-on: windows-2022
|
27
|
+
strategy:
|
28
|
+
fail-fast: false
|
29
|
+
matrix:
|
30
|
+
ruby: ['head']
|
31
|
+
steps:
|
32
|
+
- uses: actions/checkout@v3
|
33
|
+
- uses: ruby/setup-ruby@v1
|
34
|
+
with:
|
35
|
+
ruby-version: ${{ matrix.ruby }}
|
36
|
+
bundler-cache: true
|
37
|
+
- run: bundle install
|
38
|
+
- run: bundle exec rspec
|
25
39
|
check-misc:
|
26
40
|
runs-on: ubuntu-20.04
|
27
41
|
steps:
|
data/Gemfile
CHANGED
@@ -4,8 +4,9 @@ gemspec
|
|
4
4
|
|
5
5
|
gem "rspec"
|
6
6
|
gem "pry"
|
7
|
-
|
7
|
+
# stackprof doesn't support Windows
|
8
|
+
gem "stackprof", platforms: [:ruby]
|
8
9
|
gem "rake"
|
9
10
|
gem "rbs", require: false
|
10
11
|
gem "steep", require: false
|
11
|
-
gem "simplecov", require: false
|
12
|
+
gem "simplecov", require: false
|
data/exe/lrama
CHANGED
data/lib/lrama/command.rb
CHANGED
@@ -5,7 +5,6 @@ module Lrama
|
|
5
5
|
def initialize(argv)
|
6
6
|
@argv = argv
|
7
7
|
|
8
|
-
@version = nil
|
9
8
|
@skeleton = "bison/yacc.c"
|
10
9
|
@header = false
|
11
10
|
@header_file = nil
|
@@ -23,15 +22,11 @@ module Lrama
|
|
23
22
|
def run
|
24
23
|
parse_option
|
25
24
|
|
26
|
-
if @version
|
27
|
-
puts Lrama::VERSION
|
28
|
-
exit 0
|
29
|
-
end
|
30
|
-
|
31
25
|
Report::Duration.enable if @trace_opts[:time]
|
32
26
|
|
33
27
|
warning = Lrama::Warning.new
|
34
28
|
grammar = Lrama::Parser.new(@y.read).parse
|
29
|
+
@y.close if @y != STDIN
|
35
30
|
states = Lrama::States.new(grammar, warning, trace_state: (@trace_opts[:automaton] || @trace_opts[:closure]))
|
36
31
|
states.compute
|
37
32
|
context = Lrama::Context.new(states)
|
@@ -112,7 +107,7 @@ module Lrama
|
|
112
107
|
opt = OptionParser.new
|
113
108
|
|
114
109
|
# opt.on('-h') {|v| p v }
|
115
|
-
opt.on('-V', '--version') {|v|
|
110
|
+
opt.on('-V', '--version') {|v| puts "lrama #{Lrama::VERSION}"; exit 0 }
|
116
111
|
|
117
112
|
# Tuning the Parser
|
118
113
|
opt.on('-S', '--skeleton=FILE') {|v| @skeleton = v }
|
data/lib/lrama/context.rb
CHANGED
@@ -401,7 +401,6 @@ module Lrama
|
|
401
401
|
end
|
402
402
|
print sprintf("]\n\n")
|
403
403
|
|
404
|
-
|
405
404
|
print sprintf("width [\n")
|
406
405
|
vectors_count.times do |i|
|
407
406
|
print sprintf("%d, ", ary[i] ? ary[i][3] : 0)
|
@@ -409,7 +408,6 @@ module Lrama
|
|
409
408
|
end
|
410
409
|
print sprintf("]\n\n")
|
411
410
|
|
412
|
-
|
413
411
|
print sprintf("tally [\n")
|
414
412
|
vectors_count.times do |i|
|
415
413
|
print sprintf("%d, ", ary[i] ? ary[i][2] : 0)
|
@@ -205,7 +205,7 @@ module Lrama
|
|
205
205
|
end
|
206
206
|
|
207
207
|
def build_paths_from_state_items(state_items)
|
208
|
-
|
208
|
+
state_items.zip([nil] + state_items).map do |si, prev_si|
|
209
209
|
case
|
210
210
|
when prev_si.nil?
|
211
211
|
StartPath.new(si)
|
@@ -215,8 +215,6 @@ module Lrama
|
|
215
215
|
TransitionPath.new(prev_si, si)
|
216
216
|
end
|
217
217
|
end
|
218
|
-
|
219
|
-
paths
|
220
218
|
end
|
221
219
|
|
222
220
|
def shortest_path(conflict_state, conflict_reduce_item, conflict_term)
|
data/lib/lrama/grammar/code.rb
CHANGED
data/lib/lrama/grammar.rb
CHANGED
@@ -103,6 +103,10 @@ module Lrama
|
|
103
103
|
set_precedence(sym, Precedence.new(type: :right, precedence: precedence))
|
104
104
|
end
|
105
105
|
|
106
|
+
def add_precedence(sym, precedence)
|
107
|
+
set_precedence(sym, Precedence.new(type: :precedence, precedence: precedence))
|
108
|
+
end
|
109
|
+
|
106
110
|
def set_precedence(sym, precedence)
|
107
111
|
raise "" if sym.nterm?
|
108
112
|
sym.precedence = precedence
|
@@ -310,7 +314,6 @@ module Lrama
|
|
310
314
|
end || (raise "Nterm not found: #{id}")
|
311
315
|
end
|
312
316
|
|
313
|
-
|
314
317
|
def append_special_symbols
|
315
318
|
# YYEMPTY (token_id: -2, number: -2) is added when a template is evaluated
|
316
319
|
# term = add_term(id: Token.new(Token::Ident, "YYEMPTY"), token_id: -2)
|
@@ -512,7 +515,7 @@ module Lrama
|
|
512
515
|
sym.token_id = 11
|
513
516
|
when "\""
|
514
517
|
sym.token_id = 34
|
515
|
-
when "
|
518
|
+
when "'"
|
516
519
|
sym.token_id = 39
|
517
520
|
when "\\\\"
|
518
521
|
sym.token_id = 92
|
data/lib/lrama/lexer/token.rb
CHANGED
data/lib/lrama/lexer.rb
CHANGED
@@ -30,7 +30,6 @@ module Lrama
|
|
30
30
|
@grammar_rules = []
|
31
31
|
@epilogue = []
|
32
32
|
|
33
|
-
#
|
34
33
|
@bison_declarations_tokens = []
|
35
34
|
@grammar_rules_tokens = []
|
36
35
|
|
@@ -155,6 +154,8 @@ module Lrama
|
|
155
154
|
tokens << create_token(Token::P_left, ss[0], line, ss.pos - column)
|
156
155
|
when ss.scan(/%right/)
|
157
156
|
tokens << create_token(Token::P_right, ss[0], line, ss.pos - column)
|
157
|
+
when ss.scan(/%precedence/)
|
158
|
+
tokens << create_token(Token::P_precedence, ss[0], line, ss.pos - column)
|
158
159
|
when ss.scan(/%prec/)
|
159
160
|
tokens << create_token(Token::P_prec, ss[0], line, ss.pos - column)
|
160
161
|
when ss.scan(/{/)
|
@@ -223,7 +224,7 @@ module Lrama
|
|
223
224
|
references << [:dollar, ss[2], tag, str.length, str.length + ss[0].length - 1]
|
224
225
|
when ss.scan(/@\$/) # @$
|
225
226
|
references << [:at, "$", nil, str.length, str.length + ss[0].length - 1]
|
226
|
-
when ss.scan(/@(\d)
|
227
|
+
when ss.scan(/@(\d+)/) # @1
|
227
228
|
references << [:at, Integer(ss[1]), nil, str.length, str.length + ss[0].length - 1]
|
228
229
|
when ss.scan(/{/)
|
229
230
|
brace_count += 1
|
@@ -314,8 +315,6 @@ module Lrama
|
|
314
315
|
str << ss.getch
|
315
316
|
next
|
316
317
|
end
|
317
|
-
|
318
|
-
str << ss[0]
|
319
318
|
end
|
320
319
|
|
321
320
|
line # Reach to end of input
|
data/lib/lrama/output.rb
CHANGED
data/lib/lrama/parser.rb
CHANGED
@@ -159,6 +159,14 @@ module Lrama
|
|
159
159
|
grammar.add_right(sym, precedence_number)
|
160
160
|
end
|
161
161
|
precedence_number += 1
|
162
|
+
when T::P_precedence
|
163
|
+
# %precedence (ident|char|string)+
|
164
|
+
ts.next
|
165
|
+
while (id = ts.consume(T::Ident, T::Char, T::String)) do
|
166
|
+
sym = grammar.add_term(id: id)
|
167
|
+
grammar.add_precedence(sym, precedence_number)
|
168
|
+
end
|
169
|
+
precedence_number += 1
|
162
170
|
when nil
|
163
171
|
# end of input
|
164
172
|
raise "Reach to end of input within declarations"
|
data/lib/lrama/state.rb
CHANGED
data/lib/lrama/states.rb
CHANGED
@@ -455,6 +455,11 @@ module Lrama
|
|
455
455
|
|
456
456
|
# shift_prec == reduce_prec, then check associativity
|
457
457
|
case sym.precedence.type
|
458
|
+
when :precedence
|
459
|
+
# %precedence only specifies precedence and not specify associativity
|
460
|
+
# then a conflict is unresolved if precedence is same.
|
461
|
+
state.conflicts << State::ShiftReduceConflict.new(symbols: [sym], shift: shift, reduce: reduce)
|
462
|
+
next
|
458
463
|
when :right
|
459
464
|
# Shift is selected
|
460
465
|
state.resolved_conflicts << State::ResolvedConflict.new(symbol: sym, reduce: reduce, which: :shift, same_prec: true)
|
@@ -515,9 +520,9 @@ module Lrama
|
|
515
520
|
|
516
521
|
state.default_reduction_rule = state.reduces.map do |r|
|
517
522
|
[r.rule, r.rule.id, (r.look_ahead || []).count]
|
518
|
-
end.
|
523
|
+
end.min_by do |rule, rule_id, count|
|
519
524
|
[-count, rule_id]
|
520
|
-
end.first
|
525
|
+
end.first
|
521
526
|
end
|
522
527
|
end
|
523
528
|
|
@@ -110,7 +110,6 @@ module Lrama
|
|
110
110
|
end
|
111
111
|
io << "\n"
|
112
112
|
|
113
|
-
|
114
113
|
# Report shifts
|
115
114
|
tmp = state.term_transitions.select do |shift, _|
|
116
115
|
!shift.not_selected
|
@@ -123,7 +122,6 @@ module Lrama
|
|
123
122
|
end
|
124
123
|
io << "\n" if !tmp.empty?
|
125
124
|
|
126
|
-
|
127
125
|
# Report error caused by %nonassoc
|
128
126
|
nl = false
|
129
127
|
tmp = state.resolved_conflicts.select do |resolved|
|
@@ -138,7 +136,6 @@ module Lrama
|
|
138
136
|
end
|
139
137
|
io << "\n" if !tmp.empty?
|
140
138
|
|
141
|
-
|
142
139
|
# Report reduces
|
143
140
|
nl = false
|
144
141
|
max_len = state.non_default_reduces.flat_map(&:look_ahead).compact.map(&:display_name).map(&:length).max || 0
|
@@ -171,7 +168,6 @@ module Lrama
|
|
171
168
|
end
|
172
169
|
io << "\n" if nl
|
173
170
|
|
174
|
-
|
175
171
|
# Report nonterminal transitions
|
176
172
|
tmp = []
|
177
173
|
max_len = 0
|
@@ -189,7 +185,6 @@ module Lrama
|
|
189
185
|
end
|
190
186
|
io << "\n" if !tmp.empty?
|
191
187
|
|
192
|
-
|
193
188
|
if solved
|
194
189
|
# Report conflict resolutions
|
195
190
|
state.resolved_conflicts.each do |resolved|
|
@@ -202,13 +197,13 @@ module Lrama
|
|
202
197
|
# Report counterexamples
|
203
198
|
examples = cex.compute(state)
|
204
199
|
examples.each do |example|
|
205
|
-
label0 = example.type == :shift_reduce ? "shift/reduce"
|
200
|
+
label0 = example.type == :shift_reduce ? "shift/reduce" : "reduce/reduce"
|
206
201
|
label1 = example.type == :shift_reduce ? "Shift derivation" : "First Reduce derivation"
|
207
202
|
label2 = example.type == :shift_reduce ? "Reduce derivation" : "Second Reduce derivation"
|
208
203
|
|
209
204
|
io << " #{label0} conflict on token #{example.conflict_symbol.id.s_value}:\n"
|
210
|
-
io << " #{example.path1_item
|
211
|
-
io << " #{example.path2_item
|
205
|
+
io << " #{example.path1_item}\n"
|
206
|
+
io << " #{example.path2_item}\n"
|
212
207
|
io << " #{label1}\n"
|
213
208
|
example.derivations1.render_strings_for_report.each do |str|
|
214
209
|
io << " #{str}\n"
|
@@ -234,7 +229,6 @@ module Lrama
|
|
234
229
|
end
|
235
230
|
io << "\n"
|
236
231
|
|
237
|
-
|
238
232
|
# Report reads_relation
|
239
233
|
io << " [Reads Relation]\n"
|
240
234
|
@states.nterms.each do |nterm|
|
@@ -248,7 +242,6 @@ module Lrama
|
|
248
242
|
end
|
249
243
|
io << "\n"
|
250
244
|
|
251
|
-
|
252
245
|
# Report read_sets
|
253
246
|
io << " [Read sets]\n"
|
254
247
|
read_sets = @states.read_sets
|
@@ -263,7 +256,6 @@ module Lrama
|
|
263
256
|
end
|
264
257
|
io << "\n"
|
265
258
|
|
266
|
-
|
267
259
|
# Report includes_relation
|
268
260
|
io << " [Includes Relation]\n"
|
269
261
|
@states.nterms.each do |nterm|
|
@@ -277,7 +269,6 @@ module Lrama
|
|
277
269
|
end
|
278
270
|
io << "\n"
|
279
271
|
|
280
|
-
|
281
272
|
# Report lookback_relation
|
282
273
|
io << " [Lookback Relation]\n"
|
283
274
|
@states.rules.each do |rule|
|
@@ -286,12 +277,11 @@ module Lrama
|
|
286
277
|
|
287
278
|
a.each do |state_id2, nterm_id2|
|
288
279
|
n = @states.nterms.find {|n| n.token_id == nterm_id2 }
|
289
|
-
io << " (Rule: #{rule
|
280
|
+
io << " (Rule: #{rule}) -> (State #{state_id2}, #{n.id.s_value})\n"
|
290
281
|
end
|
291
282
|
end
|
292
283
|
io << "\n"
|
293
284
|
|
294
|
-
|
295
285
|
# Report follow_sets
|
296
286
|
io << " [Follow sets]\n"
|
297
287
|
follow_sets = @states.follow_sets
|
@@ -306,7 +296,6 @@ module Lrama
|
|
306
296
|
end
|
307
297
|
io << "\n"
|
308
298
|
|
309
|
-
|
310
299
|
# Report LA
|
311
300
|
io << " [Look-Ahead Sets]\n"
|
312
301
|
tmp = []
|
@@ -326,7 +315,6 @@ module Lrama
|
|
326
315
|
io << "\n" if !tmp.empty?
|
327
316
|
end
|
328
317
|
|
329
|
-
|
330
318
|
# End of Report State
|
331
319
|
io << "\n"
|
332
320
|
end
|
data/lib/lrama/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lrama
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yuichiro Kaneko
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-08-
|
11
|
+
date: 2023-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: LALR (1) parser generator written by Ruby
|
14
14
|
email:
|