lrama 0.5.4 → 0.5.5
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 +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:
|