lrama 0.6.9 → 0.6.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yaml +19 -0
  3. data/.gitignore +2 -0
  4. data/Gemfile +6 -3
  5. data/NEWS.md +220 -0
  6. data/README.md +41 -4
  7. data/Rakefile +2 -0
  8. data/Steepfile +6 -17
  9. data/exe/lrama +1 -0
  10. data/lib/lrama/bitmap.rb +2 -0
  11. data/lib/lrama/command.rb +8 -14
  12. data/lib/lrama/context.rb +8 -6
  13. data/lib/lrama/counterexamples/derivation.rb +2 -0
  14. data/lib/lrama/counterexamples/example.rb +2 -0
  15. data/lib/lrama/counterexamples/path.rb +2 -0
  16. data/lib/lrama/counterexamples/production_path.rb +2 -0
  17. data/lib/lrama/counterexamples/start_path.rb +2 -0
  18. data/lib/lrama/counterexamples/state_item.rb +2 -0
  19. data/lib/lrama/counterexamples/transition_path.rb +2 -0
  20. data/lib/lrama/counterexamples/triple.rb +2 -0
  21. data/lib/lrama/counterexamples.rb +17 -15
  22. data/lib/lrama/diagnostics.rb +36 -0
  23. data/lib/lrama/digraph.rb +2 -0
  24. data/lib/lrama/grammar/auxiliary.rb +2 -0
  25. data/lib/lrama/grammar/binding.rb +12 -1
  26. data/lib/lrama/grammar/code/destructor_code.rb +2 -0
  27. data/lib/lrama/grammar/code/initial_action_code.rb +2 -0
  28. data/lib/lrama/grammar/code/no_reference_code.rb +2 -0
  29. data/lib/lrama/grammar/code/printer_code.rb +2 -0
  30. data/lib/lrama/grammar/code/rule_action.rb +7 -3
  31. data/lib/lrama/grammar/code.rb +7 -5
  32. data/lib/lrama/grammar/counter.rb +2 -0
  33. data/lib/lrama/grammar/destructor.rb +2 -0
  34. data/lib/lrama/grammar/error_token.rb +2 -0
  35. data/lib/lrama/grammar/parameterizing_rule/resolver.rb +7 -1
  36. data/lib/lrama/grammar/parameterizing_rule/rhs.rb +5 -2
  37. data/lib/lrama/grammar/parameterizing_rule/rule.rb +6 -0
  38. data/lib/lrama/grammar/parameterizing_rule.rb +2 -0
  39. data/lib/lrama/grammar/percent_code.rb +2 -0
  40. data/lib/lrama/grammar/precedence.rb +2 -0
  41. data/lib/lrama/grammar/printer.rb +2 -0
  42. data/lib/lrama/grammar/reference.rb +2 -0
  43. data/lib/lrama/grammar/rule.rb +10 -3
  44. data/lib/lrama/grammar/rule_builder.rb +64 -65
  45. data/lib/lrama/grammar/symbol.rb +2 -0
  46. data/lib/lrama/grammar/symbols/resolver.rb +5 -1
  47. data/lib/lrama/grammar/symbols.rb +2 -0
  48. data/lib/lrama/grammar/type.rb +2 -0
  49. data/lib/lrama/grammar/union.rb +2 -0
  50. data/lib/lrama/grammar.rb +51 -30
  51. data/lib/lrama/grammar_validator.rb +37 -0
  52. data/lib/lrama/lexer/grammar_file.rb +2 -0
  53. data/lib/lrama/lexer/location.rb +2 -0
  54. data/lib/lrama/lexer/token/char.rb +2 -0
  55. data/lib/lrama/lexer/token/ident.rb +2 -0
  56. data/lib/lrama/lexer/token/instantiate_rule.rb +2 -0
  57. data/lib/lrama/lexer/token/tag.rb +2 -0
  58. data/lib/lrama/lexer/token/user_code.rb +3 -1
  59. data/lib/lrama/lexer/token.rb +7 -5
  60. data/lib/lrama/lexer.rb +11 -8
  61. data/lib/lrama/{warning.rb → logger.rb} +5 -13
  62. data/lib/lrama/option_parser.rb +58 -33
  63. data/lib/lrama/options.rb +5 -2
  64. data/lib/lrama/output.rb +38 -69
  65. data/lib/lrama/parser.rb +650 -779
  66. data/lib/lrama/report/duration.rb +2 -0
  67. data/lib/lrama/report/profile.rb +2 -0
  68. data/lib/lrama/report.rb +4 -2
  69. data/lib/lrama/state/reduce.rb +3 -0
  70. data/lib/lrama/state/reduce_reduce_conflict.rb +2 -0
  71. data/lib/lrama/state/resolved_conflict.rb +3 -1
  72. data/lib/lrama/state/shift.rb +2 -0
  73. data/lib/lrama/state/shift_reduce_conflict.rb +2 -0
  74. data/lib/lrama/state.rb +7 -5
  75. data/lib/lrama/states/item.rb +5 -3
  76. data/lib/lrama/states.rb +18 -46
  77. data/lib/lrama/states_reporter.rb +60 -19
  78. data/lib/lrama/trace_reporter.rb +30 -0
  79. data/lib/lrama/version.rb +3 -1
  80. data/lib/lrama.rb +22 -17
  81. data/lrama.gemspec +3 -1
  82. data/parser.y +110 -229
  83. data/sig/lrama/grammar/auxiliary.rbs +10 -0
  84. data/sig/lrama/grammar/binding.rbs +4 -0
  85. data/sig/lrama/grammar/code/destructor_code.rbs +3 -4
  86. data/sig/lrama/grammar/code/initial_action_code.rbs +15 -0
  87. data/sig/lrama/grammar/code/no_reference_code.rbs +15 -0
  88. data/sig/lrama/grammar/code/printer_code.rbs +3 -4
  89. data/sig/lrama/grammar/code/rule_action.rbs +19 -0
  90. data/sig/lrama/grammar/code.rbs +3 -3
  91. data/sig/lrama/grammar/destructor.rbs +3 -1
  92. data/sig/lrama/grammar/error_token.rbs +4 -2
  93. data/sig/lrama/grammar/parameterizing_rule/resolver.rbs +2 -1
  94. data/sig/lrama/grammar/parameterizing_rule/rhs.rbs +1 -1
  95. data/sig/lrama/grammar/precedence.rbs +3 -1
  96. data/sig/lrama/grammar/printer.rbs +3 -1
  97. data/sig/lrama/grammar/rule.rbs +35 -3
  98. data/sig/lrama/grammar/rule_builder.rbs +10 -9
  99. data/sig/lrama/grammar/symbol.rbs +6 -6
  100. data/sig/lrama/grammar/symbols/resolver.rbs +22 -3
  101. data/sig/lrama/grammar/type.rbs +2 -2
  102. data/sig/lrama/grammar/union.rbs +12 -0
  103. data/sig/lrama/grammar.rbs +91 -1
  104. data/sig/lrama/options.rbs +3 -2
  105. data/sig/lrama/state/reduce.rbs +20 -0
  106. data/sig/lrama/state/reduce_reduce_conflict.rbs +13 -0
  107. data/sig/lrama/state/resolved_conflict.rbs +14 -0
  108. data/sig/lrama/state/shift.rbs +14 -0
  109. data/sig/lrama/state/shift_reduce_conflict.rbs +13 -0
  110. data/sig/lrama/states/item.rbs +30 -0
  111. data/template/bison/yacc.c +24 -19
  112. metadata +17 -6
  113. data/sample/calc.output +0 -263
  114. data/sample/calc.y +0 -101
  115. data/sample/parse.y +0 -59
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9143e179e798e02afb8e7b2b4b1dd64291ac9ec128c851a4b4e660c647531675
4
- data.tar.gz: 34613495597d6d8c9334034d7167f34253ca97e910752b446fa6cc26f773a2ce
3
+ metadata.gz: 3fce10e3be7a24cd5dcae139d72e41bb586cb2a34bb6a6cd06412a420e65513b
4
+ data.tar.gz: 663d42179f28318ecb2a120d726dfcdfc8f599f2732771d39ed2d6a9e88fe07d
5
5
  SHA512:
6
- metadata.gz: a54f5f7096bc3f3f984a7da54945cd3913d02a16882975e99c982f06a2dd70988dba461106f000b54cc26f06c0e62eb294c63d3d35dd606b0e63ff6a17b127d4
7
- data.tar.gz: 007f8c7b8cf7ad1690f3b59e505f790273ddfacdab18ede2f1e3667a48309487739310d065fd7c54ee7656f9ee3791e2e1ed29e69726b69a4b861c083b8e5b4e
6
+ metadata.gz: 469a0e7bf84b68092e90187df12d7c9a71273e26caded2b27742cb7a83930a76626f73f2f872c931f496816348005a986d7edce639c326f7a83ed697708b4013
7
+ data.tar.gz: f053199c82ca39d614c56c55fd09daeb441e7e3b7504165042ee3c6a1275c400d640822365d939145a3a7a6c791da63119e614c4e5a36ad4f0cfa57a7561baa4
@@ -54,6 +54,25 @@ jobs:
54
54
  - run: flex --help
55
55
  - run: bundle install
56
56
  - run: bundle exec rspec
57
+ test-cpp:
58
+ needs: ruby-versions
59
+ runs-on: ubuntu-20.04
60
+ strategy:
61
+ fail-fast: false
62
+ matrix:
63
+ ruby: ['head']
64
+ compiler: ['g++', 'clang++']
65
+ steps:
66
+ - uses: actions/checkout@v4
67
+ - uses: ruby/setup-ruby@v1
68
+ with:
69
+ ruby-version: ${{ matrix.ruby }}
70
+ bundler-cache: true
71
+ - run: flex --help
72
+ - run: bundle install
73
+ - run: bundle exec rspec
74
+ env:
75
+ COMPILER: ${{ matrix.compiler }}
57
76
  test-memory:
58
77
  runs-on: ubuntu-20.04
59
78
  strategy:
data/.gitignore CHANGED
@@ -2,9 +2,11 @@
2
2
  /.bundle/
3
3
  /.gem_rbs_collection/
4
4
  /.irbrc
5
+ /.vscode/
5
6
  /Gemfile.lock
6
7
  /coverage/
7
8
  /parser.output
8
9
  /pkg/
9
10
  /tmp/
10
11
  /vendor/bundle
12
+ /.idea/
data/Gemfile CHANGED
@@ -1,17 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  gemspec
4
6
 
5
7
  gem "pry"
6
- gem "racc", "1.7.3"
8
+ gem "racc", "1.8.1"
7
9
  gem "rake"
8
10
  gem "rspec"
9
11
  gem "simplecov", require: false
10
12
  gem "stackprof", platforms: [:ruby] # stackprof doesn't support Windows
13
+ gem "memory_profiler"
11
14
 
12
15
  # Recent steep requires Ruby >= 3.0.0.
13
16
  # Then skip install on some CI jobs.
14
17
  if !ENV['GITHUB_ACTION'] || ENV['INSTALL_STEEP'] == 'true'
15
- gem "rbs", "3.4.4", require: false
16
- gem "steep", "1.6.0", require: false
18
+ gem "rbs", "3.5.3", require: false
19
+ gem "steep", "1.7.1", require: false
17
20
  end
data/NEWS.md CHANGED
@@ -1,5 +1,225 @@
1
1
  # NEWS for Lrama
2
2
 
3
+ ## Lrama 0.6.10 (2024-09-11)
4
+
5
+ ### Aliased Named References for actions of RHS in parameterizing rules
6
+
7
+ Allow to use aliased named references for actions of RHS in parameterizing rules.
8
+
9
+ ```
10
+ %rule sum(X, Y): X[summand] '+' Y[addend] { $$ = $summand + $addend }
11
+ ;
12
+ ```
13
+
14
+ https://github.com/ruby/lrama/pull/410
15
+
16
+
17
+ ### Named References for actions of RHS in parameterizing rules caller side
18
+
19
+ Allow to use named references for actions of RHS in parameterizing rules caller side.
20
+
21
+ ```
22
+ opt_nl: '\n'?[nl] <str> { $$ = $nl; }
23
+ ;
24
+ ```
25
+
26
+ https://github.com/ruby/lrama/pull/414
27
+
28
+ ### Widen the definable position of parameterizing rules
29
+
30
+ Allow to define parameterizing rules in the middle of the grammar.
31
+
32
+ ```
33
+ %rule defined_option(X): /* empty */
34
+ | X
35
+ ;
36
+
37
+ %%
38
+
39
+ program : defined_option(number) <i>
40
+ | defined_list(number) <i>
41
+ ;
42
+
43
+ %rule defined_list(X): /* empty */ /* <--- here */
44
+ | defined_list(X) number
45
+ ;
46
+ ```
47
+
48
+ https://github.com/ruby/lrama/pull/420
49
+
50
+ ### Report unused terminal symbols
51
+
52
+ Support to report unused terminal symbols.
53
+ Run `exe/lrama --report=terms` to show unused terminal symbols.
54
+
55
+ ```
56
+ ❯ exe/lrama --report=terms sample/calc.y
57
+ 11 Unused Terms
58
+ 0 YYerror
59
+ 1 YYUNDEF
60
+ 2 '\\\\'
61
+ 3 '\\13'
62
+ 4 keyword_class2
63
+ 5 tNUMBER
64
+ 6 tPLUS
65
+ 7 tMINUS
66
+ 8 tEQ
67
+ 9 tEQEQ
68
+ 10 '>'
69
+ ```
70
+ https://github.com/ruby/lrama/pull/439
71
+
72
+ ### Report unused rules
73
+
74
+ Support to report unused rules.
75
+ Run `exe/lrama --report=rules` to show unused rules.
76
+
77
+ ```
78
+ ❯ exe/lrama --report=rules sample/calc.y
79
+ 3 Unused Rules
80
+ 0 unused_option
81
+ 1 unused_list
82
+ 2 unused_nonempty_list
83
+ ```
84
+
85
+ https://github.com/ruby/lrama/pull/441
86
+
87
+ ### Ensure compatibility with Bison for `%locations` directive
88
+
89
+ Support `%locations` directive to ensure compatibility with Bison.
90
+ Change to `%locations` directive not set by default.
91
+
92
+ https://github.com/ruby/lrama/pull/446
93
+
94
+ ### Diagnostics report for parameterizing rules redefine
95
+
96
+ Support to warning redefined parameterizing rules.
97
+ Run `exe/lrama -W` or `exe/lrama --warnings` to show redefined parameterizing rules.
98
+
99
+ ```
100
+ ❯ exe/lrama -W sample/calc.y
101
+ parameterizing rule redefined: redefined_method(X)
102
+ parameterizing rule redefined: redefined_method(X)
103
+ ```
104
+
105
+ https://github.com/ruby/lrama/pull/448
106
+
107
+ ### Support `-v` and `--verbose` option
108
+
109
+ Support to `-v` and `--verbose` option.
110
+ These options align with Bison behavior. So same as '--report=state' option.
111
+
112
+ https://github.com/ruby/lrama/pull/457
113
+
114
+ ## Lrama 0.6.9 (2024-05-02)
115
+
116
+ ### Callee side tag specification of parameterizing rules
117
+
118
+ Allow to specify tag on callee side of parameterizing rules.
119
+
120
+ ```
121
+ %union {
122
+ int i;
123
+ }
124
+
125
+ %rule with_tag(X) <i>: X { $$ = $1; }
126
+ ;
127
+ ```
128
+
129
+ ### Named References for actions of RHS in parameterizing rules
130
+
131
+ Allow to use named references for actions of RHS in parameterizing rules.
132
+
133
+ ```
134
+ %rule option(number): /* empty */
135
+ | number { $$ = $number; }
136
+ ;
137
+ ```
138
+
139
+ ## Lrama 0.6.8 (2024-04-29)
140
+
141
+ ### Nested parameterizing rules with tag
142
+
143
+ Allow to nested parameterizing rules with tag.
144
+
145
+ ```
146
+ %union {
147
+ int i;
148
+ }
149
+
150
+ %rule nested_nested_option(X): /* empty */
151
+ | X
152
+ ;
153
+
154
+ %rule nested_option(X): /* empty */
155
+ | nested_nested_option(X) <i>
156
+ ;
157
+
158
+ %rule option(Y): /* empty */
159
+ | nested_option(Y) <i>
160
+ ;
161
+ ```
162
+
163
+ ## Lrama 0.6.7 (2024-04-28)
164
+
165
+ ### RHS of user defined parameterizing rules contains `'symbol'?`, `'symbol'+` and `'symbol'*`.
166
+
167
+ User can use `'symbol'?`, `'symbol'+` and `'symbol'*` in RHS of user defined parameterizing rules.
168
+
169
+ ```
170
+ %rule with_word_seps(X): /* empty */
171
+ | X ' '+
172
+ ;
173
+ ```
174
+
175
+ ## Lrama 0.6.6 (2024-04-27)
176
+
177
+ ### Trace actions
178
+
179
+ Support trace actions for debugging.
180
+ Run `exe/lrama --trace=actions` to show grammar rules with actions.
181
+
182
+ ```
183
+ ❯ exe/lrama --trace=actions sample/calc.y
184
+ Grammar rules with actions:
185
+ $accept -> list, YYEOF {}
186
+ list -> ε {}
187
+ list -> list, LF {}
188
+ list -> list, expr, LF { printf("=> %d\n", $2); }
189
+ expr -> NUM {}
190
+ expr -> expr, '+', expr { $$ = $1 + $3; }
191
+ expr -> expr, '-', expr { $$ = $1 - $3; }
192
+ expr -> expr, '*', expr { $$ = $1 * $3; }
193
+ expr -> expr, '/', expr { $$ = $1 / $3; }
194
+ expr -> '(', expr, ')' { $$ = $2; }
195
+ ```
196
+
197
+ ### Inlining
198
+
199
+ Support inlining for rules.
200
+ The `%inline` directive causes all references to symbols to be replaced with its definition.
201
+
202
+ ```
203
+ %rule %inline op: PLUS { + }
204
+ | TIMES { * }
205
+ ;
206
+
207
+ %%
208
+
209
+ expr : number { $$ = $1; }
210
+ | expr op expr { $$ = $1 $2 $3; }
211
+ ;
212
+ ```
213
+
214
+ as same as
215
+
216
+ ```
217
+ expr : number { $$ = $1; }
218
+ | expr '+' expr { $$ = $1 + $3; }
219
+ | expr '*' expr { $$ = $1 * $3; }
220
+ ;
221
+ ```
222
+
3
223
  ## Lrama 0.6.5 (2024-03-25)
4
224
 
5
225
  ### Typed Midrule Actions
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/lrama.svg)](https://badge.fury.io/rb/lrama)
4
4
  [![build](https://github.com/ruby/lrama/actions/workflows/test.yaml/badge.svg)](https://github.com/ruby/lrama/actions/workflows/test.yaml)
5
+ [![RubyDoc](https://img.shields.io/badge/%F0%9F%93%9ARubyDoc-documentation-informational.svg)](https://www.rubydoc.info/gems/lrama)
5
6
 
6
7
  Lrama is LALR (1) parser generator written by Ruby. The first goal of this project is providing error tolerant parser for CRuby with minimal changes on CRuby parse.y file.
7
8
 
@@ -13,7 +14,8 @@ Lrama is LALR (1) parser generator written by Ruby. The first goal of this proje
13
14
  * [Development](#development)
14
15
  * [How to generate parser.rb](#how-to-generate-parserrb)
15
16
  * [Test](#test)
16
- * [Profiling Lrama](#profiling-lrama)
17
+ * [Call-stack Profiling Lrama](#call-stack-profiling-lrama)
18
+ * [Memory Profiling Lrama](#memory-profiling-lrama)
17
19
  * [Build Ruby](#build-ruby)
18
20
  * [Release flow](#release-flow)
19
21
  * [License](#license)
@@ -94,7 +96,7 @@ This also requires Lrama to be able to run with only default gems because BASERU
94
96
  ### How to generate parser.rb
95
97
 
96
98
  ```shell
97
- $ rake build:parser
99
+ $ bundle exec rake build:parser
98
100
  ```
99
101
 
100
102
  `parser.rb` is generated from `parser.y` by Racc.
@@ -128,7 +130,7 @@ $ bundle install
128
130
  $ bundle exec rake
129
131
  ```
130
132
 
131
- ### Profiling Lrama
133
+ ### Call-stack Profiling Lrama
132
134
 
133
135
  #### 1. Create parse.tmp.y in ruby/ruby
134
136
 
@@ -166,6 +168,41 @@ $ exe/lrama -o parse.tmp.c --header=parse.tmp.h tmp/parse.tmp.y
166
168
  $ stackprof --d3-flamegraph tmp/stackprof-cpu-myapp.dump > tmp/flamegraph.html
167
169
  ```
168
170
 
171
+ ### Memory Profiling Lrama
172
+
173
+ #### 1. Create parse.tmp.y in ruby/ruby
174
+
175
+ ```shell
176
+ $ ruby tool/id2token.rb parse.y > parse.tmp.y
177
+ $ cp parse.tmp.y dir/lrama/tmp
178
+ ```
179
+
180
+ #### 2. Enable Profiler
181
+
182
+ ```diff
183
+ diff --git a/exe/lrama b/exe/lrama
184
+ index 1aece5d141..f5f94cf7fa 100755
185
+ --- a/exe/lrama
186
+ +++ b/exe/lrama
187
+ @@ -3,5 +3,9 @@
188
+
189
+ $LOAD_PATH << File.join(__dir__, "../lib")
190
+ require "lrama"
191
+ +require 'memory_profiler'
192
+
193
+ -Lrama::Command.new.run(ARGV.dup)
194
+ +report = MemoryProfiler.report do
195
+ + Lrama::Command.new.run(ARGV.dup)
196
+ +end
197
+ +report.pretty_print
198
+ ```
199
+
200
+ #### 3. Run Lrama
201
+
202
+ ```shell
203
+ $ exe/lrama -o parse.tmp.c --header=parse.tmp.h tmp/parse.tmp.y > report.txt
204
+ ```
205
+
169
206
  ### Build Ruby
170
207
 
171
208
  1. Install Lrama
@@ -180,4 +217,4 @@ $ stackprof --d3-flamegraph tmp/stackprof-cpu-myapp.dump > tmp/flamegraph.html
180
217
 
181
218
  ## License
182
219
 
183
- See LEGAL.md file.
220
+ See [LEGAL.md](./LEGAL.md) file.
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
 
3
5
  namespace "build" do
data/Steepfile CHANGED
@@ -1,30 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # D = Steep::Diagnostic
2
4
  #
3
5
  target :lib do
4
6
  repo_path '.gem_rbs_collection/'
5
7
  signature "sig"
6
8
 
7
- check "lib/lrama/grammar/binding.rb"
8
- check "lib/lrama/grammar/code/destructor_code.rb"
9
- check "lib/lrama/grammar/code/printer_code.rb"
10
- check "lib/lrama/grammar/code.rb"
11
- check "lib/lrama/grammar/counter.rb"
12
- check "lib/lrama/grammar/error_token.rb"
13
- check "lib/lrama/grammar/parameterizing_rule"
14
- check "lib/lrama/grammar/parameterizing_rules"
15
- check "lib/lrama/grammar/symbols"
16
- check "lib/lrama/grammar/percent_code.rb"
17
- check "lib/lrama/grammar/precedence.rb"
18
- check "lib/lrama/grammar/destructor.rb"
19
- check "lib/lrama/grammar/printer.rb"
20
- check "lib/lrama/grammar/reference.rb"
21
- check "lib/lrama/grammar/rule_builder.rb"
22
- check "lib/lrama/grammar/symbol.rb"
23
- check "lib/lrama/grammar/type.rb"
9
+ check "lib/lrama/grammar"
24
10
  check "lib/lrama/lexer"
25
11
  check "lib/lrama/report"
12
+ check "lib/lrama/state"
13
+ check "lib/lrama/states"
26
14
  check "lib/lrama/bitmap.rb"
27
15
  check "lib/lrama/digraph.rb"
16
+ check "lib/lrama/grammar.rb"
28
17
  check "lib/lrama/options.rb"
29
18
  check "lib/lrama/warning.rb"
30
19
  end
data/exe/lrama CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  $LOAD_PATH << File.join(__dir__, "../lib")
4
5
  require "lrama"
data/lib/lrama/bitmap.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  module Bitmap
3
5
  def self.from_array(ary)
data/lib/lrama/command.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Command
3
5
  LRAMA_LIB = File.realpath(File.join(File.dirname(__FILE__)))
@@ -14,7 +16,6 @@ module Lrama
14
16
 
15
17
  Report::Duration.enable if options.trace_opts[:time]
16
18
 
17
- warning = Lrama::Warning.new
18
19
  text = options.y.read
19
20
  options.y.close if options.y != STDIN
20
21
  begin
@@ -31,7 +32,7 @@ module Lrama
31
32
  message = message.gsub(/.+/, "\e[1m\\&\e[m") if Exception.to_tty?
32
33
  abort message
33
34
  end
34
- states = Lrama::States.new(grammar, warning, trace_state: (options.trace_opts[:automaton] || options.trace_opts[:closure]))
35
+ states = Lrama::States.new(grammar, trace_state: (options.trace_opts[:automaton] || options.trace_opts[:closure]))
35
36
  states.compute
36
37
  context = Lrama::Context.new(states)
37
38
 
@@ -42,15 +43,8 @@ module Lrama
42
43
  end
43
44
  end
44
45
 
45
- if options.trace_opts && options.trace_opts[:rules]
46
- puts "Grammar rules:"
47
- puts grammar.rules
48
- end
49
-
50
- if options.trace_opts && options.trace_opts[:actions]
51
- puts "Grammar rules with actions:"
52
- grammar.rules.each { |rule| puts rule.with_actions }
53
- end
46
+ reporter = Lrama::TraceReporter.new(grammar)
47
+ reporter.report(**options.trace_opts)
54
48
 
55
49
  File.open(options.outfile, "w+") do |f|
56
50
  Lrama::Output.new(
@@ -65,9 +59,9 @@ module Lrama
65
59
  ).render
66
60
  end
67
61
 
68
- if warning.has_error?
69
- exit false
70
- end
62
+ logger = Lrama::Logger.new
63
+ exit false unless Lrama::GrammarValidator.new(grammar, states, logger).valid?
64
+ Lrama::Diagnostics.new(grammar, states, logger).run(options.diagnostic)
71
65
  end
72
66
  end
73
67
  end
data/lib/lrama/context.rb CHANGED
@@ -1,4 +1,6 @@
1
- require "lrama/report/duration"
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "report/duration"
2
4
 
3
5
  module Lrama
4
6
  # This is passed to a template
@@ -253,7 +255,7 @@ module Lrama
253
255
 
254
256
  # If no default_reduction_rule, default behavior is an
255
257
  # error then replace ErrorActionNumber with zero.
256
- if !state.default_reduction_rule
258
+ unless state.default_reduction_rule
257
259
  actions.map! do |e|
258
260
  if e == ErrorActionNumber
259
261
  0
@@ -301,10 +303,7 @@ module Lrama
301
303
  end
302
304
 
303
305
  @states.nterms.each do |nterm|
304
- if !(states = nterm_to_next_states[nterm])
305
- default_goto = 0
306
- not_default_gotos = []
307
- else
306
+ if (states = nterm_to_next_states[nterm])
308
307
  default_state = states.map(&:last).group_by {|s| s }.max_by {|_, v| v.count }.first
309
308
  default_goto = default_state.id
310
309
  not_default_gotos = []
@@ -312,6 +311,9 @@ module Lrama
312
311
  next if to_state.id == default_goto
313
312
  not_default_gotos << [from_state.id, to_state.id]
314
313
  end
314
+ else
315
+ default_goto = 0
316
+ not_default_gotos = []
315
317
  end
316
318
 
317
319
  k = nterm_number_to_sequence_number(nterm.number)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Counterexamples
3
5
  class Derivation
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Counterexamples
3
5
  class Example
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Counterexamples
3
5
  class Path
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Counterexamples
3
5
  class ProductionPath < Path
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Counterexamples
3
5
  class StartPath < Path
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Counterexamples
3
5
  class StateItem < Struct.new(:state, :item)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Counterexamples
3
5
  class TransitionPath < Path
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  class Counterexamples
3
5
  # s: state
@@ -1,13 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "set"
2
4
 
3
- require "lrama/counterexamples/derivation"
4
- require "lrama/counterexamples/example"
5
- require "lrama/counterexamples/path"
6
- require "lrama/counterexamples/production_path"
7
- require "lrama/counterexamples/start_path"
8
- require "lrama/counterexamples/state_item"
9
- require "lrama/counterexamples/transition_path"
10
- require "lrama/counterexamples/triple"
5
+ require_relative "counterexamples/derivation"
6
+ require_relative "counterexamples/example"
7
+ require_relative "counterexamples/path"
8
+ require_relative "counterexamples/production_path"
9
+ require_relative "counterexamples/start_path"
10
+ require_relative "counterexamples/state_item"
11
+ require_relative "counterexamples/transition_path"
12
+ require_relative "counterexamples/triple"
11
13
 
12
14
  module Lrama
13
15
  # See: https://www.cs.cornell.edu/andru/papers/cupex/cupex.pdf
@@ -171,7 +173,13 @@ module Lrama
171
173
  break
172
174
  end
173
175
 
174
- if !si.item.beginning_of_rule?
176
+ if si.item.beginning_of_rule?
177
+ key = [si.state, si.item.lhs]
178
+ @reverse_productions[key].each do |item|
179
+ state_item = StateItem.new(si.state, item)
180
+ queue << (sis + [state_item])
181
+ end
182
+ else
175
183
  key = [si, si.item.previous_sym]
176
184
  @reverse_transitions[key].each do |prev_target_state_item|
177
185
  next if prev_target_state_item.state != prev_state_item.state
@@ -183,12 +191,6 @@ module Lrama
183
191
  queue.clear
184
192
  break
185
193
  end
186
- else
187
- key = [si.state, si.item.lhs]
188
- @reverse_productions[key].each do |item|
189
- state_item = StateItem.new(si.state, item)
190
- queue << (sis + [state_item])
191
- end
192
194
  end
193
195
  end
194
196
  else
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lrama
4
+ class Diagnostics
5
+ def initialize(grammar, states, logger)
6
+ @grammar = grammar
7
+ @states = states
8
+ @logger = logger
9
+ end
10
+
11
+ def run(diagnostic)
12
+ if diagnostic
13
+ diagnose_conflict
14
+ diagnose_parameterizing_redefined
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def diagnose_conflict
21
+ if @states.sr_conflicts_count != 0
22
+ @logger.warn("shift/reduce conflicts: #{@states.sr_conflicts_count} found")
23
+ end
24
+
25
+ if @states.rr_conflicts_count != 0
26
+ @logger.warn("reduce/reduce conflicts: #{@states.rr_conflicts_count} found")
27
+ end
28
+ end
29
+
30
+ def diagnose_parameterizing_redefined
31
+ @grammar.parameterizing_rule_resolver.redefined_rules.each do |rule|
32
+ @logger.warn("parameterizing rule redefined: #{rule}")
33
+ end
34
+ end
35
+ end
36
+ end
data/lib/lrama/digraph.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lrama
2
4
  # Algorithm Digraph of https://dl.acm.org/doi/pdf/10.1145/69622.357187 (P. 625)
3
5
  class Digraph