lrama 0.5.9 → 0.5.11
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 +25 -0
- data/.gitignore +7 -4
- data/Gemfile +9 -5
- data/Rakefile +13 -0
- data/Steepfile +13 -11
- data/lib/lrama/context.rb +1 -3
- data/lib/lrama/counterexamples/path.rb +0 -46
- data/lib/lrama/counterexamples/production_path.rb +17 -0
- data/lib/lrama/counterexamples/start_path.rb +21 -0
- data/lib/lrama/counterexamples/transition_path.rb +17 -0
- data/lib/lrama/counterexamples.rb +3 -0
- data/lib/lrama/grammar/code/initial_action_code.rb +28 -0
- data/lib/lrama/grammar/code/no_reference_code.rb +24 -0
- data/lib/lrama/grammar/code/printer_code.rb +34 -0
- data/lib/lrama/grammar/code/rule_action.rb +62 -0
- data/lib/lrama/grammar/code.rb +9 -93
- data/lib/lrama/grammar/counter.rb +15 -0
- data/lib/lrama/grammar/error_token.rb +3 -3
- data/lib/lrama/grammar/parameterizing_rules/builder/base.rb +36 -0
- data/lib/lrama/grammar/parameterizing_rules/builder/list.rb +28 -0
- data/lib/lrama/grammar/parameterizing_rules/builder/nonempty_list.rb +28 -0
- data/lib/lrama/grammar/parameterizing_rules/builder/option.rb +28 -0
- data/lib/lrama/grammar/parameterizing_rules/builder/separated_list.rb +39 -0
- data/lib/lrama/grammar/parameterizing_rules/builder/separated_nonempty_list.rb +34 -0
- data/lib/lrama/grammar/parameterizing_rules/builder.rb +60 -0
- data/lib/lrama/grammar/printer.rb +3 -3
- data/lib/lrama/grammar/reference.rb +7 -16
- data/lib/lrama/grammar/rule.rb +19 -2
- data/lib/lrama/grammar/rule_builder.rb +177 -0
- data/lib/lrama/grammar/symbol.rb +16 -2
- data/lib/lrama/grammar/type.rb +6 -0
- data/lib/lrama/grammar.rb +115 -325
- data/lib/lrama/lexer/location.rb +22 -0
- data/lib/lrama/lexer/token/parameterizing.rb +18 -3
- data/lib/lrama/lexer/token/tag.rb +4 -0
- data/lib/lrama/lexer/token/user_code.rb +54 -4
- data/lib/lrama/lexer/token.rb +35 -10
- data/lib/lrama/lexer.rb +32 -31
- data/lib/lrama/options.rb +1 -2
- data/lib/lrama/output.rb +2 -2
- data/lib/lrama/parser.rb +514 -424
- data/lib/lrama/report/profile.rb +1 -12
- data/lib/lrama/version.rb +1 -1
- data/lib/lrama.rb +0 -1
- data/parser.y +111 -52
- data/rbs_collection.lock.yaml +6 -8
- data/rbs_collection.yaml +1 -0
- data/sig/lrama/grammar/code/printer_code.rbs +15 -0
- data/sig/lrama/grammar/code.rbs +24 -0
- data/sig/lrama/grammar/counter.rbs +11 -0
- data/sig/lrama/grammar/error_token.rbs +11 -0
- data/sig/lrama/grammar/parameterizing_rules/builder/base.rbs +26 -0
- data/sig/lrama/grammar/parameterizing_rules/builder/list.rbs +10 -0
- data/sig/lrama/grammar/parameterizing_rules/builder/nonempty_list.rbs +10 -0
- data/sig/lrama/grammar/parameterizing_rules/builder/option.rbs +10 -0
- data/sig/lrama/grammar/parameterizing_rules/builder/separated_list.rbs +11 -0
- data/sig/lrama/grammar/parameterizing_rules/builder/separated_nonempty_list.rbs +11 -0
- data/sig/lrama/grammar/parameterizing_rules/builder.rbs +23 -0
- data/sig/lrama/grammar/precedence.rbs +11 -0
- data/sig/lrama/grammar/printer.rbs +11 -0
- data/sig/lrama/grammar/reference.rbs +6 -6
- data/sig/lrama/grammar/rule.rbs +13 -0
- data/sig/lrama/grammar/rule_builder.rbs +42 -0
- data/sig/lrama/grammar/symbol.rbs +37 -0
- data/sig/lrama/lexer/location.rbs +14 -0
- data/sig/lrama/lexer/token/parameterizing.rbs +9 -0
- data/sig/lrama/lexer/token/tag.rbs +1 -0
- data/sig/lrama/lexer/token/user_code.rbs +8 -1
- data/sig/lrama/lexer/token.rbs +9 -4
- data/sig/stdlib/strscan/string_scanner.rbs +5 -0
- data/template/bison/yacc.c +5 -2
- metadata +38 -3
- data/lib/lrama/type.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 634093bc73fd1504910364bffa6827a66fa7479f1f5b5238fdf577f0bb6d3d9d
|
4
|
+
data.tar.gz: 96db570d049f47f20bf619535ee91e7f0f846a492404a54f7fe41a6addcce484
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b09e84cd16cd162f263e68abf7ada808418212ca449fab0f4a380c42c0193f479cad3d0d1afcc1d5f17d81b890e3754642d1a9433f7be5f6fc71fdcb2df3f97
|
7
|
+
data.tar.gz: 1994a670f1033e737f2193e2e71ccaa0818e4144ac7f4424ebf24046ece23efc3f67eeb0927c5336663a244f270b321247b39dbbdbe76cfacc13b94da6289a8b
|
data/.github/workflows/test.yaml
CHANGED
@@ -20,6 +20,7 @@ jobs:
|
|
20
20
|
with:
|
21
21
|
ruby-version: ${{ matrix.ruby }}
|
22
22
|
bundler-cache: true
|
23
|
+
- run: flex --help
|
23
24
|
- run: bundle install
|
24
25
|
- run: bundle exec rspec
|
25
26
|
test-windows:
|
@@ -34,8 +35,30 @@ jobs:
|
|
34
35
|
with:
|
35
36
|
ruby-version: ${{ matrix.ruby }}
|
36
37
|
bundler-cache: true
|
38
|
+
- run: choco install winflexbison || choco install winflexbison
|
39
|
+
- run: win_flex --help
|
37
40
|
- run: bundle install
|
38
41
|
- run: bundle exec rspec
|
42
|
+
test-memory:
|
43
|
+
runs-on: ubuntu-20.04
|
44
|
+
strategy:
|
45
|
+
fail-fast: false
|
46
|
+
matrix:
|
47
|
+
ruby: ['head']
|
48
|
+
steps:
|
49
|
+
- uses: actions/checkout@v4
|
50
|
+
- uses: ruby/setup-ruby@v1
|
51
|
+
with:
|
52
|
+
ruby-version: ${{ matrix.ruby }}
|
53
|
+
bundler-cache: true
|
54
|
+
- run: |
|
55
|
+
sudo apt-get update -q
|
56
|
+
sudo apt-get install --no-install-recommends -q -y valgrind
|
57
|
+
- run: valgrind --version
|
58
|
+
- run: bundle install
|
59
|
+
- run: bundle exec rspec spec/lrama/integration_spec.rb
|
60
|
+
env:
|
61
|
+
ENABEL_VALGRIND: 'true'
|
39
62
|
check-misc:
|
40
63
|
runs-on: ubuntu-20.04
|
41
64
|
strategy:
|
@@ -65,6 +88,8 @@ jobs:
|
|
65
88
|
fail-fast: false
|
66
89
|
matrix:
|
67
90
|
ruby: ['head']
|
91
|
+
env:
|
92
|
+
INSTALL_STEEP: 'true'
|
68
93
|
steps:
|
69
94
|
- uses: actions/checkout@v4
|
70
95
|
- uses: ruby/setup-ruby@v1
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -2,12 +2,16 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
gem "rspec"
|
6
5
|
gem "pry"
|
7
|
-
# stackprof doesn't support Windows
|
8
|
-
gem "stackprof", platforms: [:ruby]
|
9
6
|
gem "racc", "1.7.3"
|
10
7
|
gem "rake"
|
11
|
-
gem "
|
12
|
-
gem "steep", require: false
|
8
|
+
gem "rspec"
|
13
9
|
gem "simplecov", require: false
|
10
|
+
gem "stackprof", platforms: [:ruby] # stackprof doesn't support Windows
|
11
|
+
|
12
|
+
# Recent steep requires Ruby >= 3.0.0.
|
13
|
+
# Then skip install on some CI jobs.
|
14
|
+
if !ENV['GITHUB_ACTION'] || ENV['INSTALL_STEEP'] == 'true'
|
15
|
+
gem "rbs", "3.3.0", require: false
|
16
|
+
gem "steep", "1.6.0", require: false
|
17
|
+
end
|
data/Rakefile
CHANGED
@@ -6,3 +6,16 @@ namespace "build" do
|
|
6
6
|
sh "bundle exec racc parser.y --embedded -o lib/lrama/parser.rb -t --log-file=parser.output"
|
7
7
|
end
|
8
8
|
end
|
9
|
+
|
10
|
+
require 'rspec/core/rake_task'
|
11
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
12
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
13
|
+
end
|
14
|
+
task :spec => "build:parser"
|
15
|
+
|
16
|
+
desc "steep check"
|
17
|
+
task :steep do
|
18
|
+
sh "bundle exec steep check"
|
19
|
+
end
|
20
|
+
|
21
|
+
task default: %i[spec steep]
|
data/Steepfile
CHANGED
@@ -4,18 +4,20 @@ target :lib do
|
|
4
4
|
repo_path '.gem_rbs_collection/'
|
5
5
|
signature "sig"
|
6
6
|
|
7
|
+
check "lib/lrama/grammar/code/printer_code.rb"
|
8
|
+
check "lib/lrama/grammar/code.rb"
|
9
|
+
check "lib/lrama/grammar/counter.rb"
|
10
|
+
check "lib/lrama/grammar/error_token.rb"
|
11
|
+
check "lib/lrama/grammar/parameterizing_rules"
|
12
|
+
check "lib/lrama/grammar/percent_code.rb"
|
13
|
+
check "lib/lrama/grammar/precedence.rb"
|
14
|
+
check "lib/lrama/grammar/printer.rb"
|
15
|
+
check "lib/lrama/grammar/reference.rb"
|
16
|
+
check "lib/lrama/grammar/rule_builder.rb"
|
17
|
+
check "lib/lrama/grammar/symbol.rb"
|
18
|
+
check "lib/lrama/lexer"
|
19
|
+
check "lib/lrama/report"
|
7
20
|
check "lib/lrama/bitmap.rb"
|
8
21
|
check "lib/lrama/digraph.rb"
|
9
|
-
check "lib/lrama/grammar/percent_code.rb"
|
10
|
-
# TODO: Include this file once Lrama::Grammar::Symbol type is defined
|
11
|
-
# check "lib/lrama/grammar/reference.rb"
|
12
|
-
check "lib/lrama/lexer/token.rb"
|
13
|
-
check "lib/lrama/lexer/token/char.rb"
|
14
|
-
check "lib/lrama/lexer/token/ident.rb"
|
15
|
-
check "lib/lrama/lexer/token/parameterizing.rb"
|
16
|
-
check "lib/lrama/lexer/token/tag.rb"
|
17
|
-
check "lib/lrama/lexer/token/user_code.rb"
|
18
|
-
check "lib/lrama/report/duration.rb"
|
19
|
-
check "lib/lrama/report/profile.rb"
|
20
22
|
check "lib/lrama/warning.rb"
|
21
23
|
end
|
data/lib/lrama/context.rb
CHANGED
@@ -309,10 +309,8 @@ module Lrama
|
|
309
309
|
# Index is sequence number of nterm, value is state id
|
310
310
|
# of a default nterm transition destination.
|
311
311
|
@yydefgoto = Array.new(@states.nterms.count, 0)
|
312
|
-
h = {}
|
313
312
|
# Mapping from nterm to next_states
|
314
313
|
nterm_to_next_states = {}
|
315
|
-
terms_count = @states.terms.count
|
316
314
|
|
317
315
|
@states.states.each do |state|
|
318
316
|
state.nterm_transitions.each do |shift, next_state|
|
@@ -369,7 +367,7 @@ module Lrama
|
|
369
367
|
end
|
370
368
|
|
371
369
|
j = @sorted_actions.count - 1
|
372
|
-
|
370
|
+
_state_id, _froms_and_tos, count, width = action
|
373
371
|
|
374
372
|
while (j >= 0) do
|
375
373
|
case
|
@@ -19,51 +19,5 @@ module Lrama
|
|
19
19
|
end
|
20
20
|
alias :inspect :to_s
|
21
21
|
end
|
22
|
-
|
23
|
-
class StartPath < Path
|
24
|
-
def initialize(to_state_item)
|
25
|
-
super nil, to_state_item
|
26
|
-
end
|
27
|
-
|
28
|
-
def type
|
29
|
-
:start
|
30
|
-
end
|
31
|
-
|
32
|
-
def transition?
|
33
|
-
false
|
34
|
-
end
|
35
|
-
|
36
|
-
def production?
|
37
|
-
false
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
class TransitionPath < Path
|
42
|
-
def type
|
43
|
-
:transition
|
44
|
-
end
|
45
|
-
|
46
|
-
def transition?
|
47
|
-
true
|
48
|
-
end
|
49
|
-
|
50
|
-
def production?
|
51
|
-
false
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
class ProductionPath < Path
|
56
|
-
def type
|
57
|
-
:production
|
58
|
-
end
|
59
|
-
|
60
|
-
def transition?
|
61
|
-
false
|
62
|
-
end
|
63
|
-
|
64
|
-
def production?
|
65
|
-
true
|
66
|
-
end
|
67
|
-
end
|
68
22
|
end
|
69
23
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Lrama
|
2
|
+
class Counterexamples
|
3
|
+
class StartPath < Path
|
4
|
+
def initialize(to_state_item)
|
5
|
+
super nil, to_state_item
|
6
|
+
end
|
7
|
+
|
8
|
+
def type
|
9
|
+
:start
|
10
|
+
end
|
11
|
+
|
12
|
+
def transition?
|
13
|
+
false
|
14
|
+
end
|
15
|
+
|
16
|
+
def production?
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -3,7 +3,10 @@ require "set"
|
|
3
3
|
require "lrama/counterexamples/derivation"
|
4
4
|
require "lrama/counterexamples/example"
|
5
5
|
require "lrama/counterexamples/path"
|
6
|
+
require "lrama/counterexamples/production_path"
|
7
|
+
require "lrama/counterexamples/start_path"
|
6
8
|
require "lrama/counterexamples/state_item"
|
9
|
+
require "lrama/counterexamples/transition_path"
|
7
10
|
require "lrama/counterexamples/triple"
|
8
11
|
|
9
12
|
module Lrama
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Lrama
|
2
|
+
class Grammar
|
3
|
+
class Code
|
4
|
+
class InitialActionCode < Code
|
5
|
+
private
|
6
|
+
|
7
|
+
# * ($$) yylval
|
8
|
+
# * (@$) yylloc
|
9
|
+
# * ($1) error
|
10
|
+
# * (@1) error
|
11
|
+
def reference_to_c(ref)
|
12
|
+
case
|
13
|
+
when ref.type == :dollar && ref.name == "$" # $$
|
14
|
+
"yylval"
|
15
|
+
when ref.type == :at && ref.name == "$" # @$
|
16
|
+
"yylloc"
|
17
|
+
when ref.type == :dollar # $n
|
18
|
+
raise "$#{ref.value} can not be used in initial_action."
|
19
|
+
when ref.type == :at # @n
|
20
|
+
raise "@#{ref.value} can not be used in initial_action."
|
21
|
+
else
|
22
|
+
raise "Unexpected. #{self}, #{ref}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Lrama
|
2
|
+
class Grammar
|
3
|
+
class Code
|
4
|
+
class NoReferenceCode < Code
|
5
|
+
private
|
6
|
+
|
7
|
+
# * ($$) error
|
8
|
+
# * (@$) error
|
9
|
+
# * ($1) error
|
10
|
+
# * (@1) error
|
11
|
+
def reference_to_c(ref)
|
12
|
+
case
|
13
|
+
when ref.type == :dollar # $$, $n
|
14
|
+
raise "$#{ref.value} can not be used in #{type}."
|
15
|
+
when ref.type == :at # @$, @n
|
16
|
+
raise "@#{ref.value} can not be used in #{type}."
|
17
|
+
else
|
18
|
+
raise "Unexpected. #{self}, #{ref}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Lrama
|
2
|
+
class Grammar
|
3
|
+
class Code
|
4
|
+
class PrinterCode < Code
|
5
|
+
def initialize(type: nil, token_code: nil, tag: nil)
|
6
|
+
super(type: type, token_code: token_code)
|
7
|
+
@tag = tag
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# * ($$) *yyvaluep
|
13
|
+
# * (@$) *yylocationp
|
14
|
+
# * ($1) error
|
15
|
+
# * (@1) error
|
16
|
+
def reference_to_c(ref)
|
17
|
+
case
|
18
|
+
when ref.type == :dollar && ref.name == "$" # $$
|
19
|
+
member = @tag.member
|
20
|
+
"((*yyvaluep).#{member})"
|
21
|
+
when ref.type == :at && ref.name == "$" # @$
|
22
|
+
"(*yylocationp)"
|
23
|
+
when ref.type == :dollar # $n
|
24
|
+
raise "$#{ref.value} can not be used in #{type}."
|
25
|
+
when ref.type == :at # @n
|
26
|
+
raise "@#{ref.value} can not be used in #{type}."
|
27
|
+
else
|
28
|
+
raise "Unexpected. #{self}, #{ref}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Lrama
|
2
|
+
class Grammar
|
3
|
+
class Code
|
4
|
+
class RuleAction < Code
|
5
|
+
def initialize(type: nil, token_code: nil, rule: nil)
|
6
|
+
super(type: type, token_code: token_code)
|
7
|
+
@rule = rule
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# * ($$) yyval
|
13
|
+
# * (@$) yyloc
|
14
|
+
# * ($1) yyvsp[i]
|
15
|
+
# * (@1) yylsp[i]
|
16
|
+
#
|
17
|
+
# "Rule" class: keyword_class { $1 } tSTRING { $2 + $3 } keyword_end { $class = $1 + $keyword_end }
|
18
|
+
# "Position in grammar" $1 $2 $3 $4 $5 $6
|
19
|
+
# "Index for yyvsp" -4 -3 -2 -1 0
|
20
|
+
def reference_to_c(ref)
|
21
|
+
case
|
22
|
+
when ref.type == :dollar && ref.name == "$" # $$
|
23
|
+
tag = ref.ex_tag || lhs.tag
|
24
|
+
raise_tag_not_found_error(ref) unless tag
|
25
|
+
"(yyval.#{tag.member})"
|
26
|
+
when ref.type == :at && ref.name == "$" # @$
|
27
|
+
"(yyloc)"
|
28
|
+
when ref.type == :dollar # $n
|
29
|
+
i = -position_in_rhs + ref.index
|
30
|
+
tag = ref.ex_tag || rhs[ref.index - 1].tag
|
31
|
+
raise_tag_not_found_error(ref) unless tag
|
32
|
+
"(yyvsp[#{i}].#{tag.member})"
|
33
|
+
when ref.type == :at # @n
|
34
|
+
i = -position_in_rhs + ref.index
|
35
|
+
"(yylsp[#{i}])"
|
36
|
+
else
|
37
|
+
raise "Unexpected. #{self}, #{ref}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def position_in_rhs
|
42
|
+
# If rule is not derived rule, User Code is only action at
|
43
|
+
# the end of rule RHS. In such case, the action is located on
|
44
|
+
# `@rule.rhs.count`.
|
45
|
+
@rule.position_in_original_rule_rhs || @rule.rhs.count
|
46
|
+
end
|
47
|
+
|
48
|
+
def rhs
|
49
|
+
(@rule.original_rule || @rule).rhs
|
50
|
+
end
|
51
|
+
|
52
|
+
def lhs
|
53
|
+
@rule.lhs
|
54
|
+
end
|
55
|
+
|
56
|
+
def raise_tag_not_found_error(ref)
|
57
|
+
raise "Tag is not specified for '$#{ref.value}' in '#{@rule.to_s}'"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/lrama/grammar/code.rb
CHANGED
@@ -7,116 +7,32 @@ module Lrama
|
|
7
7
|
|
8
8
|
def_delegators "token_code", :s_value, :line, :column, :references
|
9
9
|
|
10
|
-
# $$, $n, @$, @n
|
10
|
+
# $$, $n, @$, @n are translated to C code
|
11
11
|
def translated_code
|
12
|
-
case type
|
13
|
-
when :user_code
|
14
|
-
translated_user_code
|
15
|
-
when :initial_action
|
16
|
-
translated_initial_action_code
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# * ($1) error
|
21
|
-
# * ($$) *yyvaluep
|
22
|
-
# * (@1) error
|
23
|
-
# * (@$) *yylocationp
|
24
|
-
def translated_printer_code(tag)
|
25
12
|
t_code = s_value.dup
|
26
13
|
|
27
14
|
references.reverse.each do |ref|
|
28
15
|
first_column = ref.first_column
|
29
16
|
last_column = ref.last_column
|
30
17
|
|
31
|
-
|
32
|
-
when ref.value == "$" && ref.type == :dollar # $$
|
33
|
-
# Omit "<>"
|
34
|
-
member = tag.s_value[1..-2]
|
35
|
-
str = "((*yyvaluep).#{member})"
|
36
|
-
when ref.value == "$" && ref.type == :at # @$
|
37
|
-
str = "(*yylocationp)"
|
38
|
-
when ref.type == :dollar # $n
|
39
|
-
raise "$#{ref.value} can not be used in %printer."
|
40
|
-
when ref.type == :at # @n
|
41
|
-
raise "@#{ref.value} can not be used in %printer."
|
42
|
-
else
|
43
|
-
raise "Unexpected. #{self}, #{ref}"
|
44
|
-
end
|
18
|
+
str = reference_to_c(ref)
|
45
19
|
|
46
20
|
t_code[first_column..last_column] = str
|
47
21
|
end
|
48
22
|
|
49
23
|
return t_code
|
50
24
|
end
|
51
|
-
alias :translated_error_token_code :translated_printer_code
|
52
25
|
|
53
26
|
private
|
54
27
|
|
55
|
-
|
56
|
-
|
57
|
-
# * (@1) yylsp[i]
|
58
|
-
# * (@$) yyloc
|
59
|
-
def translated_user_code
|
60
|
-
t_code = s_value.dup
|
61
|
-
|
62
|
-
references.reverse.each do |ref|
|
63
|
-
first_column = ref.first_column
|
64
|
-
last_column = ref.last_column
|
65
|
-
|
66
|
-
case
|
67
|
-
when ref.value == "$" && ref.type == :dollar # $$
|
68
|
-
# Omit "<>"
|
69
|
-
member = ref.tag.s_value[1..-2]
|
70
|
-
str = "(yyval.#{member})"
|
71
|
-
when ref.value == "$" && ref.type == :at # @$
|
72
|
-
str = "(yyloc)"
|
73
|
-
when ref.type == :dollar # $n
|
74
|
-
i = -ref.position_in_rhs + ref.value
|
75
|
-
# Omit "<>"
|
76
|
-
member = ref.tag.s_value[1..-2]
|
77
|
-
str = "(yyvsp[#{i}].#{member})"
|
78
|
-
when ref.type == :at # @n
|
79
|
-
i = -ref.position_in_rhs + ref.value
|
80
|
-
str = "(yylsp[#{i}])"
|
81
|
-
else
|
82
|
-
raise "Unexpected. #{self}, #{ref}"
|
83
|
-
end
|
84
|
-
|
85
|
-
t_code[first_column..last_column] = str
|
86
|
-
end
|
87
|
-
|
88
|
-
return t_code
|
89
|
-
end
|
90
|
-
|
91
|
-
# * ($1) error
|
92
|
-
# * ($$) yylval
|
93
|
-
# * (@1) error
|
94
|
-
# * (@$) yylloc
|
95
|
-
def translated_initial_action_code
|
96
|
-
t_code = s_value.dup
|
97
|
-
|
98
|
-
references.reverse.each do |ref|
|
99
|
-
first_column = ref.first_column
|
100
|
-
last_column = ref.last_column
|
101
|
-
|
102
|
-
case
|
103
|
-
when ref.value == "$" && ref.type == :dollar # $$
|
104
|
-
str = "yylval"
|
105
|
-
when ref.value == "$" && ref.type == :at # @$
|
106
|
-
str = "yylloc"
|
107
|
-
when ref.type == :dollar # $n
|
108
|
-
raise "$#{ref.value} can not be used in initial_action."
|
109
|
-
when ref.type == :at # @n
|
110
|
-
raise "@#{ref.value} can not be used in initial_action."
|
111
|
-
else
|
112
|
-
raise "Unexpected. #{self}, #{ref}"
|
113
|
-
end
|
114
|
-
|
115
|
-
t_code[first_column..last_column] = str
|
116
|
-
end
|
117
|
-
|
118
|
-
return t_code
|
28
|
+
def reference_to_c(ref)
|
29
|
+
raise NotImplementedError.new("#reference_to_c is not implemented")
|
119
30
|
end
|
120
31
|
end
|
121
32
|
end
|
122
33
|
end
|
34
|
+
|
35
|
+
require "lrama/grammar/code/initial_action_code"
|
36
|
+
require "lrama/grammar/code/no_reference_code"
|
37
|
+
require "lrama/grammar/code/printer_code"
|
38
|
+
require "lrama/grammar/code/rule_action"
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Lrama
|
2
2
|
class Grammar
|
3
|
-
class ErrorToken < Struct.new(:ident_or_tags, :
|
4
|
-
def translated_code(
|
5
|
-
|
3
|
+
class ErrorToken < Struct.new(:ident_or_tags, :token_code, :lineno, keyword_init: true)
|
4
|
+
def translated_code(tag)
|
5
|
+
Code::PrinterCode.new(type: :error_token, token_code: token_code, tag: tag).translated_code
|
6
6
|
end
|
7
7
|
end
|
8
8
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Lrama
|
2
|
+
class Grammar
|
3
|
+
class ParameterizingRules
|
4
|
+
class Builder
|
5
|
+
# Base class for parameterizing rules builder
|
6
|
+
class Base
|
7
|
+
attr_reader :build_token
|
8
|
+
|
9
|
+
def initialize(token, rule_counter, lhs_tag, user_code, precedence_sym, line)
|
10
|
+
@args = token.args
|
11
|
+
@token = @args.first
|
12
|
+
@rule_counter = rule_counter
|
13
|
+
@lhs_tag = lhs_tag
|
14
|
+
@user_code = user_code
|
15
|
+
@precedence_sym = precedence_sym
|
16
|
+
@line = line
|
17
|
+
@expected_argument_num = 1
|
18
|
+
@build_token = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def build
|
22
|
+
raise NotImplementedError
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def validate_argument_number!
|
28
|
+
unless @args.count == @expected_argument_num
|
29
|
+
raise "Invalid number of arguments. expect: #{@expected_argument_num} actual: #{@args.count}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Lrama
|
2
|
+
class Grammar
|
3
|
+
class ParameterizingRules
|
4
|
+
class Builder
|
5
|
+
# Builder for list of general parameterizing rules
|
6
|
+
class List < Base
|
7
|
+
|
8
|
+
# program: list(number)
|
9
|
+
#
|
10
|
+
# =>
|
11
|
+
#
|
12
|
+
# program: list_number
|
13
|
+
# list_number: ε
|
14
|
+
# list_number: list_number number
|
15
|
+
def build
|
16
|
+
validate_argument_number!
|
17
|
+
|
18
|
+
rules = []
|
19
|
+
@build_token = Lrama::Lexer::Token::Ident.new(s_value: "list_#{@token.s_value}")
|
20
|
+
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
|
21
|
+
rules << Rule.new(id: @rule_counter.increment, _lhs: @build_token, _rhs: [@build_token, @token], lhs_tag: @lhs_tag, token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
|
22
|
+
rules
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|