lrama 0.5.8 → 0.5.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yaml +6 -1
  3. data/.gitignore +7 -4
  4. data/Gemfile +10 -6
  5. data/README.md +3 -3
  6. data/Rakefile +15 -7
  7. data/Steepfile +15 -1
  8. data/lib/lrama/command.rb +6 -1
  9. data/lib/lrama/context.rb +1 -3
  10. data/lib/lrama/counterexamples/path.rb +0 -46
  11. data/lib/lrama/counterexamples/production_path.rb +17 -0
  12. data/lib/lrama/counterexamples/start_path.rb +21 -0
  13. data/lib/lrama/counterexamples/transition_path.rb +17 -0
  14. data/lib/lrama/counterexamples.rb +3 -0
  15. data/lib/lrama/grammar/code/initial_action_code.rb +28 -0
  16. data/lib/lrama/grammar/code/no_reference_code.rb +24 -0
  17. data/lib/lrama/grammar/code/printer_code.rb +34 -0
  18. data/lib/lrama/grammar/code/rule_action.rb +62 -0
  19. data/lib/lrama/grammar/code.rb +9 -93
  20. data/lib/lrama/grammar/counter.rb +15 -0
  21. data/lib/lrama/grammar/error_token.rb +3 -3
  22. data/lib/lrama/grammar/parameterizing_rules/builder/base.rb +28 -0
  23. data/lib/lrama/grammar/parameterizing_rules/builder/list.rb +20 -0
  24. data/lib/lrama/grammar/parameterizing_rules/builder/nonempty_list.rb +20 -0
  25. data/lib/lrama/grammar/parameterizing_rules/builder/option.rb +20 -0
  26. data/lib/lrama/grammar/parameterizing_rules/builder/separated_list.rb +28 -0
  27. data/lib/lrama/grammar/parameterizing_rules/builder/separated_nonempty_list.rb +27 -0
  28. data/lib/lrama/grammar/parameterizing_rules/builder.rb +43 -0
  29. data/lib/lrama/grammar/percent_code.rb +12 -0
  30. data/lib/lrama/grammar/printer.rb +3 -3
  31. data/lib/lrama/grammar/reference.rb +7 -16
  32. data/lib/lrama/grammar/rule.rb +18 -2
  33. data/lib/lrama/grammar/rule_builder.rb +179 -0
  34. data/lib/lrama/grammar/symbol.rb +2 -2
  35. data/lib/lrama/grammar.rb +132 -302
  36. data/lib/lrama/lexer/location.rb +22 -0
  37. data/lib/lrama/lexer/token/char.rb +8 -0
  38. data/lib/lrama/lexer/token/ident.rb +8 -0
  39. data/lib/lrama/lexer/token/parameterizing.rb +34 -0
  40. data/lib/lrama/lexer/token/tag.rb +12 -0
  41. data/lib/lrama/lexer/token/user_code.rb +64 -0
  42. data/lib/lrama/lexer/token.rb +23 -63
  43. data/lib/lrama/lexer.rb +38 -37
  44. data/lib/lrama/option_parser.rb +2 -1
  45. data/lib/lrama/options.rb +2 -2
  46. data/lib/lrama/output.rb +11 -2
  47. data/lib/lrama/parser.rb +607 -488
  48. data/lib/lrama/report/profile.rb +1 -12
  49. data/lib/lrama/version.rb +1 -1
  50. data/parser.y +177 -96
  51. data/rbs_collection.lock.yaml +17 -1
  52. data/rbs_collection.yaml +1 -0
  53. data/sample/calc.y +3 -1
  54. data/sample/parse.y +5 -1
  55. data/sig/lrama/grammar/code/printer_code.rbs +15 -0
  56. data/sig/lrama/grammar/code.rbs +24 -0
  57. data/sig/lrama/grammar/counter.rbs +11 -0
  58. data/sig/lrama/grammar/parameterizing_rules/builder.rbs +10 -0
  59. data/sig/lrama/grammar/percent_code.rbs +10 -0
  60. data/sig/lrama/grammar/precedence.rbs +11 -0
  61. data/sig/lrama/grammar/printer.rbs +11 -0
  62. data/sig/lrama/grammar/reference.rbs +22 -0
  63. data/sig/lrama/grammar/rule.rbs +13 -0
  64. data/sig/lrama/grammar/rule_builder.rbs +41 -0
  65. data/sig/lrama/grammar.rbs +5 -0
  66. data/sig/lrama/lexer/location.rbs +14 -0
  67. data/sig/lrama/lexer/token/char.rbs +8 -0
  68. data/sig/lrama/lexer/token/ident.rbs +8 -0
  69. data/sig/lrama/lexer/token/parameterizing.rbs +15 -0
  70. data/sig/lrama/lexer/token/tag.rbs +9 -0
  71. data/sig/lrama/lexer/token/user_code.rbs +16 -0
  72. data/sig/lrama/lexer/token.rbs +22 -0
  73. data/sig/stdlib/strscan/string_scanner.rbs +5 -0
  74. data/template/bison/_yacc.h +2 -2
  75. data/template/bison/yacc.c +5 -2
  76. metadata +44 -4
  77. data/lib/lrama/lexer/token/type.rb +0 -8
  78. data/sig/lrama/lexer/token/type.rbs +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52e495f849079217c2cb4ee28edf873dd7c999d02f2f486acf8b9c2c1e74006f
4
- data.tar.gz: 708aea3d87d066b71857d09c4b9fc0705c8abaedc1e8b8e465ae5f6c2a5e0315
3
+ metadata.gz: '0097beb1eb7af4947e417b356a7e3c81c3002916f4a1b2940b2df196ee58f144'
4
+ data.tar.gz: 982c957cdb8c42d8b77210756046e35f395875bb527f32a66b3a82ff236cbe78
5
5
  SHA512:
6
- metadata.gz: 779e08f5090a78347214d8fbe73e710469ed62f61e923b5fbf50ed1e4c022a4096961df035b517b4c6434fa69326d3a006d94cff144f2c87b48407093f8961c7
7
- data.tar.gz: df1e4828906ae7613bca0f5f7dda3466091aa0fe15d7d5147e92bcd803f8ef0e58b6935a6e5061bb18d715a1e0f8b47aaab678c553edda828cb7ff1b05b2bc0f
6
+ metadata.gz: a4bbdebc7f100a1b26c801c3c153519e3fb11d34f6dc5001391302665e779905d95041781917af93b2dac64854f174630044e384465bd5606df40f9f878707b1
7
+ data.tar.gz: b46f8eb2dffa4df04563bbc8997a9efd06f5a70dcbc26e19f6301624aadf5bc416721045ecf6650b83ae64b9889689c8aeef078e9637e0a152a9ac204ab766de
@@ -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,6 +35,8 @@ jobs:
34
35
  with:
35
36
  ruby-version: ${{ matrix.ruby }}
36
37
  bundler-cache: true
38
+ - run: choco install winflexbison
39
+ - run: win_flex --help
37
40
  - run: bundle install
38
41
  - run: bundle exec rspec
39
42
  check-misc:
@@ -57,7 +60,7 @@ jobs:
57
60
 
58
61
  - name: Check for parser.rb is up to date
59
62
  run: |
60
- bundle exec rake build:racc_parser
63
+ bundle exec rake build:parser
61
64
  git diff --color --no-ext-diff --ignore-submodules --exit-code lib/lrama/parser.rb
62
65
  steep-check:
63
66
  runs-on: ubuntu-20.04
@@ -65,6 +68,8 @@ jobs:
65
68
  fail-fast: false
66
69
  matrix:
67
70
  ruby: ['head']
71
+ env:
72
+ INSTALL_STEEP: 'true'
68
73
  steps:
69
74
  - uses: actions/checkout@v4
70
75
  - uses: ruby/setup-ruby@v1
data/.gitignore CHANGED
@@ -1,7 +1,10 @@
1
+ /.DS_Store
2
+ /.bundle/
1
3
  /.gem_rbs_collection/
2
- /tmp
3
- .irbrc
4
+ /.irbrc
4
5
  /Gemfile.lock
5
- /pkg/
6
- coverage/
6
+ /coverage/
7
7
  /parser.output
8
+ /pkg/
9
+ /tmp/
10
+ /vendor/bundle
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
- gem "racc"
6
+ gem "racc", "1.7.3"
10
7
  gem "rake"
11
- gem "rbs", require: false
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/README.md CHANGED
@@ -65,13 +65,13 @@ This also requires Lrama to be able to run with only default gems because BASERU
65
65
 
66
66
  ## Development
67
67
 
68
- ### How to generate new_parser.rb
68
+ ### How to generate parser.rb
69
69
 
70
70
  ```shell
71
- $ rake build:racc_parser
71
+ $ rake build:parser
72
72
  ```
73
73
 
74
- `new_parser.rb` is generated from `parser.y` by Racc.
74
+ `parser.rb` is generated from `parser.y` by Racc.
75
75
  Run the rake command when you update `parser.y` then commit changes of both files.
76
76
 
77
77
  ### Test
data/Rakefile CHANGED
@@ -1,13 +1,21 @@
1
1
  require "bundler/gem_tasks"
2
2
 
3
3
  namespace "build" do
4
- desc "build parser from parser.y by using Racc"
5
- task :racc_parser do
6
- sh "bundle exec racc parser.y --embedded -o lib/lrama/parser.rb"
7
- end
8
-
9
- desc "build parser for debugging"
10
- task :racc_verbose_parser do
4
+ desc "build parser from parser.y"
5
+ task :parser do
11
6
  sh "bundle exec racc parser.y --embedded -o lib/lrama/parser.rb -t --log-file=parser.output"
12
7
  end
13
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
@@ -6,8 +6,22 @@ target :lib do
6
6
 
7
7
  check "lib/lrama/bitmap.rb"
8
8
  check "lib/lrama/digraph.rb"
9
+ check "lib/lrama/grammar/code.rb"
10
+ check "lib/lrama/grammar/code/printer_code.rb"
11
+ check "lib/lrama/grammar/counter.rb"
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/lexer/token/char.rb"
18
+ check "lib/lrama/lexer/token/ident.rb"
19
+ check "lib/lrama/lexer/token/parameterizing.rb"
20
+ check "lib/lrama/lexer/token/tag.rb"
21
+ check "lib/lrama/lexer/token/user_code.rb"
22
+ check "lib/lrama/lexer/location.rb"
23
+ check "lib/lrama/lexer/token.rb"
9
24
  check "lib/lrama/report/duration.rb"
10
25
  check "lib/lrama/report/profile.rb"
11
- check "lib/lrama/token/type.rb"
12
26
  check "lib/lrama/warning.rb"
13
27
  end
data/lib/lrama/command.rb CHANGED
@@ -8,7 +8,7 @@ module Lrama
8
8
  warning = Lrama::Warning.new
9
9
  text = options.y.read
10
10
  options.y.close if options.y != STDIN
11
- grammar = Lrama::Parser.new(text, options.grammar_file).parse
11
+ grammar = Lrama::Parser.new(text, options.grammar_file, options.debug).parse
12
12
  states = Lrama::States.new(grammar, warning, trace_state: (options.trace_opts[:automaton] || options.trace_opts[:closure]))
13
13
  states.compute
14
14
  context = Lrama::Context.new(states)
@@ -20,6 +20,11 @@ module Lrama
20
20
  end
21
21
  end
22
22
 
23
+ if options.trace_opts && options.trace_opts[:rules]
24
+ puts "Grammar rules:"
25
+ puts grammar.rules
26
+ end
27
+
23
28
  File.open(options.outfile, "w+") do |f|
24
29
  Lrama::Output.new(
25
30
  out: f,
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
- state_id, froms_and_tos, count, width = action
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,17 @@
1
+ module Lrama
2
+ class Counterexamples
3
+ class ProductionPath < Path
4
+ def type
5
+ :production
6
+ end
7
+
8
+ def transition?
9
+ false
10
+ end
11
+
12
+ def production?
13
+ true
14
+ end
15
+ end
16
+ end
17
+ 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
@@ -0,0 +1,17 @@
1
+ module Lrama
2
+ class Counterexamples
3
+ class TransitionPath < Path
4
+ def type
5
+ :transition
6
+ end
7
+
8
+ def transition?
9
+ true
10
+ end
11
+
12
+ def production?
13
+ false
14
+ end
15
+ end
16
+ end
17
+ 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.original_rule || @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
@@ -7,116 +7,32 @@ module Lrama
7
7
 
8
8
  def_delegators "token_code", :s_value, :line, :column, :references
9
9
 
10
- # $$, $n, @$, @n is translated to C code
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
- case
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
- # * ($1) yyvsp[i]
56
- # * ($$) yyval
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"
@@ -0,0 +1,15 @@
1
+ module Lrama
2
+ class Grammar
3
+ class Counter
4
+ def initialize(number)
5
+ @number = number
6
+ end
7
+
8
+ def increment
9
+ n = @number
10
+ @number += 1
11
+ n
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,8 +1,8 @@
1
1
  module Lrama
2
2
  class Grammar
3
- class ErrorToken < Struct.new(:ident_or_tags, :code, :lineno, keyword_init: true)
4
- def translated_code(member)
5
- code.translated_error_token_code(member)
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,28 @@
1
+ module Lrama
2
+ class Grammar
3
+ class ParameterizingRules
4
+ class Builder
5
+ class Base
6
+ def initialize(token, rule_counter, lhs, user_code, precedence_sym, line)
7
+ @args = token.args
8
+ @token = @args.first
9
+ @rule_counter = rule_counter
10
+ @lhs = lhs
11
+ @user_code = user_code
12
+ @precedence_sym = precedence_sym
13
+ @line = line
14
+ @expected_argument_num = 1
15
+ end
16
+
17
+ private
18
+
19
+ def validate_argument_number!
20
+ unless @args.count == @expected_argument_num
21
+ raise "Invalid number of arguments. expect: #{@expected_argument_num} actual: #{@args.count}"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ module Lrama
2
+ class Grammar
3
+ class ParameterizingRules
4
+ class Builder
5
+ class List < Base
6
+ def build
7
+ validate_argument_number!
8
+
9
+ rules = []
10
+ list_token = Lrama::Lexer::Token::Ident.new(s_value: "list_#{@token.s_value}")
11
+ rules << Rule.new(id: @rule_counter.increment, _lhs: @lhs, _rhs: [list_token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
12
+ rules << Rule.new(id: @rule_counter.increment, _lhs: list_token, _rhs: [], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
13
+ rules << Rule.new(id: @rule_counter.increment, _lhs: list_token, _rhs: [list_token, @token], token_code: @user_code, precedence_sym: @precedence_sym, lineno: @line)
14
+ rules
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end