antelope 0.3.2 → 0.4.0

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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +25 -25
  3. data/.rspec +3 -3
  4. data/.travis.yml +10 -10
  5. data/.yardopts +7 -7
  6. data/CONTRIBUTING.md +50 -38
  7. data/GENERATORS.md +180 -124
  8. data/Gemfile +7 -7
  9. data/LICENSE.txt +22 -22
  10. data/README.md +240 -104
  11. data/Rakefile +2 -2
  12. data/TODO.md +58 -58
  13. data/antelope.gemspec +29 -28
  14. data/bin/antelope +7 -7
  15. data/examples/deterministic.ace +35 -35
  16. data/examples/example.ace +52 -51
  17. data/examples/example.ace.err +192 -192
  18. data/examples/example.ace.inf +432 -432
  19. data/examples/example.ate +70 -70
  20. data/examples/example.ate.err +192 -192
  21. data/examples/example.ate.inf +432 -432
  22. data/examples/liquidscript.ace +233 -233
  23. data/examples/simple.ace +22 -22
  24. data/lib/antelope/ace/compiler.rb +334 -334
  25. data/lib/antelope/ace/errors.rb +30 -30
  26. data/lib/antelope/ace/scanner/argument.rb +57 -57
  27. data/lib/antelope/ace/scanner/first.rb +89 -89
  28. data/lib/antelope/ace/scanner/second.rb +178 -178
  29. data/lib/antelope/ace/scanner/third.rb +27 -27
  30. data/lib/antelope/ace/scanner.rb +144 -144
  31. data/lib/antelope/ace.rb +47 -47
  32. data/lib/antelope/cli.rb +60 -60
  33. data/lib/antelope/errors.rb +25 -25
  34. data/lib/antelope/generation/constructor/first.rb +86 -86
  35. data/lib/antelope/generation/constructor/follow.rb +105 -105
  36. data/lib/antelope/generation/constructor/nullable.rb +64 -64
  37. data/lib/antelope/generation/constructor.rb +127 -127
  38. data/lib/antelope/generation/errors.rb +17 -17
  39. data/lib/antelope/generation/null.rb +13 -13
  40. data/lib/antelope/generation/recognizer/rule.rb +216 -216
  41. data/lib/antelope/generation/recognizer/state.rb +129 -129
  42. data/lib/antelope/generation/recognizer.rb +177 -177
  43. data/lib/antelope/generation/tableizer.rb +176 -176
  44. data/lib/antelope/generation.rb +15 -15
  45. data/lib/antelope/generator/base/coerce.rb +115 -0
  46. data/lib/antelope/generator/base/extra.rb +50 -0
  47. data/lib/antelope/generator/base.rb +134 -264
  48. data/lib/antelope/generator/c.rb +11 -11
  49. data/lib/antelope/generator/c_header.rb +105 -105
  50. data/lib/antelope/generator/c_source.rb +39 -39
  51. data/lib/antelope/generator/error.rb +34 -34
  52. data/lib/antelope/generator/group.rb +60 -57
  53. data/lib/antelope/generator/html.rb +51 -51
  54. data/lib/antelope/generator/info.rb +47 -47
  55. data/lib/antelope/generator/null.rb +18 -18
  56. data/lib/antelope/generator/output.rb +17 -17
  57. data/lib/antelope/generator/ruby.rb +112 -79
  58. data/lib/antelope/generator/templates/c_header.ant +36 -36
  59. data/lib/antelope/generator/templates/c_source.ant +202 -202
  60. data/lib/antelope/generator/templates/error.erb +40 -0
  61. data/lib/antelope/generator/templates/html/antelope.css +53 -1
  62. data/lib/antelope/generator/templates/html/antelope.html +82 -1
  63. data/lib/antelope/generator/templates/html/antelope.js +9 -1
  64. data/lib/antelope/generator/templates/html/css.ant +53 -53
  65. data/lib/antelope/generator/templates/html/html.ant +82 -82
  66. data/lib/antelope/generator/templates/html/js.ant +9 -9
  67. data/lib/antelope/generator/templates/info.erb +61 -0
  68. data/lib/antelope/generator/templates/{ruby.ant → ruby.erb} +171 -178
  69. data/lib/antelope/generator.rb +62 -66
  70. data/lib/antelope/grammar/generation.rb +76 -76
  71. data/lib/antelope/grammar/loading.rb +84 -84
  72. data/lib/antelope/grammar/precedence.rb +59 -59
  73. data/lib/antelope/grammar/precedences.rb +64 -64
  74. data/lib/antelope/grammar/production.rb +56 -56
  75. data/lib/antelope/grammar/productions.rb +154 -154
  76. data/lib/antelope/grammar/symbols.rb +64 -64
  77. data/lib/antelope/grammar/token/epsilon.rb +23 -23
  78. data/lib/antelope/grammar/token/error.rb +24 -24
  79. data/lib/antelope/grammar/token/nonterminal.rb +15 -15
  80. data/lib/antelope/grammar/token/terminal.rb +15 -15
  81. data/lib/antelope/grammar/token.rb +231 -231
  82. data/lib/antelope/grammar.rb +68 -68
  83. data/lib/antelope/version.rb +6 -6
  84. data/lib/antelope.rb +18 -19
  85. data/optimizations.txt +42 -42
  86. data/spec/antelope/ace/compiler_spec.rb +60 -60
  87. data/spec/antelope/ace/scanner_spec.rb +27 -27
  88. data/spec/antelope/generation/constructor_spec.rb +131 -131
  89. data/spec/fixtures/simple.ace +22 -22
  90. data/spec/spec_helper.rb +39 -39
  91. data/spec/support/benchmark_helper.rb +5 -5
  92. data/spec/support/grammar_helper.rb +14 -14
  93. data/subl/Ace (Ruby).JSON-tmLanguage +94 -94
  94. data/subl/Ace (Ruby).tmLanguage +153 -153
  95. metadata +22 -11
  96. data/lib/antelope/generator/templates/error.ant +0 -34
  97. data/lib/antelope/generator/templates/info.ant +0 -53
  98. data/lib/antelope/template/compiler.rb +0 -78
  99. data/lib/antelope/template/errors.rb +0 -9
  100. data/lib/antelope/template/scanner.rb +0 -109
  101. data/lib/antelope/template.rb +0 -64
  102. data/spec/antelope/template_spec.rb +0 -50
@@ -0,0 +1,40 @@
1
+ Productions:
2
+ <%
3
+ len = grammar.all_productions.size.to_s.size
4
+ productions = recognizer.states.map(&:rules).inject(:merge).
5
+ select(&:final?).map { |x| [x.to_s(false), x.production.block] }
6
+ body = productions.map { |_| _[0].size }.max
7
+ productions.each do |prod|
8
+ -%>
9
+ <%= sprintf("%-#{body}s", prod[0]) %> <%= prod[1] %>
10
+ <% end -%>
11
+
12
+ <%
13
+ if table.each_with_index.any? { |_, i| tableizer.conflicts[i].each.
14
+ select { |(_, v)| v[:result] == 0 || directives.output.verbose }.any? }
15
+ -%>
16
+ Error:
17
+ <%
18
+ table.each_with_index do |_, i|
19
+ conflicts = tableizer.conflicts[i].each.
20
+ select { |(_, v)| v[:result] == 0 || directives.output.verbose }
21
+ next unless conflicts.any?
22
+ -%>
23
+ Conflicts in State <%= i %>:
24
+ <%- conflicts.each do |token, value| -%>
25
+ On <%= token %><%= ' (resolved)' if value[:result] != 0 %>:
26
+ <%= value[:data][0].join(' ') %>/<%= value[:data][1].join(' ') %> (<%= value[:prec] %> vs <%= value[:terminal] %>, <%= value[:result] %>)
27
+ Rules:
28
+ <%- value[:rules].each do |rule| -%>
29
+ <%= rule %>
30
+ {<%= rule.lookahead.to_a.join(', ') %>}
31
+ <%- end -%>
32
+ Transitions:
33
+ <%- value[:transitions].each do |transition| -%>
34
+ <%= transition %>
35
+ <%- end -%>
36
+ <%- end -%>
37
+ <%- end -%>
38
+ <%- else -%>
39
+ No errors :)
40
+ <%- end -%>
@@ -1 +1,53 @@
1
- css.ant
1
+ body {
2
+ font-family: sans-serif;
3
+ color: #696265;
4
+ background-color: #fefefe;
5
+ }
6
+
7
+ h1, h2, h3, h4, h5, h6 {
8
+ font-family: serif;
9
+ color: #327CCB;
10
+ margin: 0;
11
+ }
12
+
13
+ code, kbd, pre {
14
+ font-family: monospace;
15
+ }
16
+
17
+ .body .section {
18
+ background-color: #f9f9f9;
19
+ padding: 0.5em;
20
+ }
21
+
22
+ .body .section h2 {
23
+ font-size: 1.5em;
24
+ }
25
+
26
+ .body .section h2, .body .section h3, .body .section h4,
27
+ .body .section h5, .body .section h6 {
28
+ padding: 0;
29
+ cursor: pointer;
30
+
31
+ }
32
+
33
+ .body .section .section-data {
34
+ display: none;
35
+ padding: 0.3em 2em;
36
+ }
37
+
38
+ .body .section .section-data.display {
39
+ display: block;
40
+ }
41
+
42
+ .body .section ul {
43
+ list-style-type: none;
44
+ }
45
+
46
+ .body .section ul, .body .section ol {
47
+ margin: 0;
48
+ padding: 0;
49
+ }
50
+
51
+ .conflict.resolved { color: #d9d9d9; }
52
+ .conflict.resolved:before { content: "resolved: "; color: #00B057; }
53
+ code.block { display: block; }
@@ -1 +1,82 @@
1
- html.ant
1
+ <!DOCTYPE html>
2
+
3
+ <html>
4
+ <head>
5
+ <title>Antelope State Data</title>
6
+
7
+ <meta charset="utf-8">
8
+ <link rel="stylesheet" type="text/css" href="%{file}.css">
9
+ </head>
10
+
11
+ <body>
12
+
13
+ <div class="body">
14
+ <div class="section productions">
15
+ <h2>Productions</h2>
16
+ <ol class="rules section-data">
17
+ {{ grammar.all_productions.each do |prod| }}
18
+ <li>
19
+ <code>{{= prod.label }}: {{= prod.items.join(' ') }}</code>
20
+ <code class="block">{{= prod.block }}</code>
21
+ </li>
22
+ {{ end }}
23
+ </ol>
24
+ </div>
25
+
26
+ <div class="section states">
27
+ <h2>States</h2>
28
+ <ul class="section-data">
29
+ {{ states = grammar.states.to_a }}
30
+ {{ table.each_with_index do |v, i| }}
31
+ <li class="section state">
32
+ {{ state = states[i] }}
33
+ <h3>State %{i}</h3>
34
+ <div class="section-data">
35
+ {{ state.rules.each do |rule| }}
36
+ <pre>{{= rule }}
37
+ {{= "{" << rule.lookahead.to_a.join(", ") << "}" }}</pre>
38
+ {{ end }}
39
+ {{
40
+ transitions = v.each.select { |_, a| a && a[0] == :state }
41
+ reductions = v.each.select { |_, a| a && a[0] == :reduce}
42
+ accepting = v.each.select { |_, a| a && a[0] == :accept}
43
+ conflicts = tableizer.conflicts[i].each
44
+ thing = [:transitions, :reductions, :accepting]
45
+ num_type = {
46
+ transitions: "State",
47
+ reductions: "Rule",
48
+ accepting: "Rule"
49
+ }
50
+ h = Hash[thing.zip([transitions, reductions, accepting])]
51
+ }}
52
+ {{ h.each do |key, value| }}
53
+ {{ next unless value.any? }}
54
+ <div class="part">
55
+ <h4>{{= key }}</h4>
56
+ {{ value.each do |token, (_, name)| }}
57
+ {{ token_value = grammar.terminals.find { |_| _.name == token } || token }}
58
+ <div>
59
+ <code>{{= token_value}}: {{= num_type[key] }} {{= name }}</code class="block"></div>
60
+ {{ end }}
61
+ </div>
62
+ {{ end }}
63
+ {{ if conflicts.any? }}
64
+ <div class="part">
65
+ <h4>Conflicts</h4>
66
+ {{ conflicts.each do |token, (value, first, second, rule, terminal)| }}
67
+ <div class="conflict {{ if value != 0 }}resolved{{ end }}">
68
+ <code>{{= token }}: {{= first.join(" ") }}/{{= second.join(" ") }} ({{= rule }} vs {{= terminal }})</code>
69
+ </div>
70
+ {{ end }}
71
+ </div>
72
+ {{ end }}
73
+ </div>
74
+ </li>
75
+ {{ end }}
76
+ </ul>
77
+ </div>
78
+ </div>
79
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
80
+ <script src="%{file}.js"></script>
81
+ </body>
82
+ </html>
@@ -1 +1,9 @@
1
- js.ant
1
+ $(function() {
2
+ $(".section").each(function(i, element) {
3
+ var $element = $(element);
4
+
5
+ $(element).children("h2, h3, h4, h5, h6").on("click", function() {
6
+ $(element).children(".section-data").toggleClass("display");
7
+ });
8
+ });
9
+ });
@@ -1,53 +1,53 @@
1
- body {
2
- font-family: sans-serif;
3
- color: #696265;
4
- background-color: #fefefe;
5
- }
6
-
7
- h1, h2, h3, h4, h5, h6 {
8
- font-family: serif;
9
- color: #327CCB;
10
- margin: 0;
11
- }
12
-
13
- code, kbd, pre {
14
- font-family: monospace;
15
- }
16
-
17
- .body .section {
18
- background-color: #f9f9f9;
19
- padding: 0.5em;
20
- }
21
-
22
- .body .section h2 {
23
- font-size: 1.5em;
24
- }
25
-
26
- .body .section h2, .body .section h3, .body .section h4,
27
- .body .section h5, .body .section h6 {
28
- padding: 0;
29
- cursor: pointer;
30
-
31
- }
32
-
33
- .body .section .section-data {
34
- display: none;
35
- padding: 0.3em 2em;
36
- }
37
-
38
- .body .section .section-data.display {
39
- display: block;
40
- }
41
-
42
- .body .section ul {
43
- list-style-type: none;
44
- }
45
-
46
- .body .section ul, .body .section ol {
47
- margin: 0;
48
- padding: 0;
49
- }
50
-
51
- .conflict.resolved { color: #d9d9d9; }
52
- .conflict.resolved:before { content: "resolved: "; color: #00B057; }
53
- code.block { display: block; }
1
+ body {
2
+ font-family: sans-serif;
3
+ color: #696265;
4
+ background-color: #fefefe;
5
+ }
6
+
7
+ h1, h2, h3, h4, h5, h6 {
8
+ font-family: serif;
9
+ color: #327CCB;
10
+ margin: 0;
11
+ }
12
+
13
+ code, kbd, pre {
14
+ font-family: monospace;
15
+ }
16
+
17
+ .body .section {
18
+ background-color: #f9f9f9;
19
+ padding: 0.5em;
20
+ }
21
+
22
+ .body .section h2 {
23
+ font-size: 1.5em;
24
+ }
25
+
26
+ .body .section h2, .body .section h3, .body .section h4,
27
+ .body .section h5, .body .section h6 {
28
+ padding: 0;
29
+ cursor: pointer;
30
+
31
+ }
32
+
33
+ .body .section .section-data {
34
+ display: none;
35
+ padding: 0.3em 2em;
36
+ }
37
+
38
+ .body .section .section-data.display {
39
+ display: block;
40
+ }
41
+
42
+ .body .section ul {
43
+ list-style-type: none;
44
+ }
45
+
46
+ .body .section ul, .body .section ol {
47
+ margin: 0;
48
+ padding: 0;
49
+ }
50
+
51
+ .conflict.resolved { color: #d9d9d9; }
52
+ .conflict.resolved:before { content: "resolved: "; color: #00B057; }
53
+ code.block { display: block; }
@@ -1,82 +1,82 @@
1
- <!DOCTYPE html>
2
-
3
- <html>
4
- <head>
5
- <title>Antelope State Data</title>
6
-
7
- <meta charset="utf-8">
8
- <link rel="stylesheet" type="text/css" href="%{file}.css">
9
- </head>
10
-
11
- <body>
12
-
13
- <div class="body">
14
- <div class="section productions">
15
- <h2>Productions</h2>
16
- <ol class="rules section-data">
17
- {{ grammar.all_productions.each do |prod| }}
18
- <li>
19
- <code>{{= prod.label }}: {{= prod.items.join(' ') }}</code>
20
- <code class="block">{{= prod.block }}</code>
21
- </li>
22
- {{ end }}
23
- </ol>
24
- </div>
25
-
26
- <div class="section states">
27
- <h2>States</h2>
28
- <ul class="section-data">
29
- {{ states = grammar.states.to_a }}
30
- {{ table.each_with_index do |v, i| }}
31
- <li class="section state">
32
- {{ state = states[i] }}
33
- <h3>State %{i}</h3>
34
- <div class="section-data">
35
- {{ state.rules.each do |rule| }}
36
- <pre>{{= rule }}
37
- {{= "{" << rule.lookahead.to_a.join(", ") << "}" }}</pre>
38
- {{ end }}
39
- {{
40
- transitions = v.each.select { |_, a| a && a[0] == :state }
41
- reductions = v.each.select { |_, a| a && a[0] == :reduce}
42
- accepting = v.each.select { |_, a| a && a[0] == :accept}
43
- conflicts = tableizer.conflicts[i].each
44
- thing = [:transitions, :reductions, :accepting]
45
- num_type = {
46
- transitions: "State",
47
- reductions: "Rule",
48
- accepting: "Rule"
49
- }
50
- h = Hash[thing.zip([transitions, reductions, accepting])]
51
- }}
52
- {{ h.each do |key, value| }}
53
- {{ next unless value.any? }}
54
- <div class="part">
55
- <h4>{{= key }}</h4>
56
- {{ value.each do |token, (_, name)| }}
57
- {{ token_value = grammar.terminals.find { |_| _.name == token } || token }}
58
- <div>
59
- <code>{{= token_value}}: {{= num_type[key] }} {{= name }}</code class="block"></div>
60
- {{ end }}
61
- </div>
62
- {{ end }}
63
- {{ if conflicts.any? }}
64
- <div class="part">
65
- <h4>Conflicts</h4>
66
- {{ conflicts.each do |token, (value, first, second, rule, terminal)| }}
67
- <div class="conflict {{ if value != 0 }}resolved{{ end }}">
68
- <code>{{= token }}: {{= first.join(" ") }}/{{= second.join(" ") }} ({{= rule }} vs {{= terminal }})</code>
69
- </div>
70
- {{ end }}
71
- </div>
72
- {{ end }}
73
- </div>
74
- </li>
75
- {{ end }}
76
- </ul>
77
- </div>
78
- </div>
79
- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
80
- <script src="%{file}.js"></script>
81
- </body>
82
- </html>
1
+ <!DOCTYPE html>
2
+
3
+ <html>
4
+ <head>
5
+ <title>Antelope State Data</title>
6
+
7
+ <meta charset="utf-8">
8
+ <link rel="stylesheet" type="text/css" href="%{file}.css">
9
+ </head>
10
+
11
+ <body>
12
+
13
+ <div class="body">
14
+ <div class="section productions">
15
+ <h2>Productions</h2>
16
+ <ol class="rules section-data">
17
+ {{ grammar.all_productions.each do |prod| }}
18
+ <li>
19
+ <code>{{= prod.label }}: {{= prod.items.join(' ') }}</code>
20
+ <code class="block">{{= prod.block }}</code>
21
+ </li>
22
+ {{ end }}
23
+ </ol>
24
+ </div>
25
+
26
+ <div class="section states">
27
+ <h2>States</h2>
28
+ <ul class="section-data">
29
+ {{ states = grammar.states.to_a }}
30
+ {{ table.each_with_index do |v, i| }}
31
+ <li class="section state">
32
+ {{ state = states[i] }}
33
+ <h3>State %{i}</h3>
34
+ <div class="section-data">
35
+ {{ state.rules.each do |rule| }}
36
+ <pre>{{= rule }}
37
+ {{= "{" << rule.lookahead.to_a.join(", ") << "}" }}</pre>
38
+ {{ end }}
39
+ {{
40
+ transitions = v.each.select { |_, a| a && a[0] == :state }
41
+ reductions = v.each.select { |_, a| a && a[0] == :reduce}
42
+ accepting = v.each.select { |_, a| a && a[0] == :accept}
43
+ conflicts = tableizer.conflicts[i].each
44
+ thing = [:transitions, :reductions, :accepting]
45
+ num_type = {
46
+ transitions: "State",
47
+ reductions: "Rule",
48
+ accepting: "Rule"
49
+ }
50
+ h = Hash[thing.zip([transitions, reductions, accepting])]
51
+ }}
52
+ {{ h.each do |key, value| }}
53
+ {{ next unless value.any? }}
54
+ <div class="part">
55
+ <h4>{{= key }}</h4>
56
+ {{ value.each do |token, (_, name)| }}
57
+ {{ token_value = grammar.terminals.find { |_| _.name == token } || token }}
58
+ <div>
59
+ <code>{{= token_value}}: {{= num_type[key] }} {{= name }}</code class="block"></div>
60
+ {{ end }}
61
+ </div>
62
+ {{ end }}
63
+ {{ if conflicts.any? }}
64
+ <div class="part">
65
+ <h4>Conflicts</h4>
66
+ {{ conflicts.each do |token, (value, first, second, rule, terminal)| }}
67
+ <div class="conflict {{ if value != 0 }}resolved{{ end }}">
68
+ <code>{{= token }}: {{= first.join(" ") }}/{{= second.join(" ") }} ({{= rule }} vs {{= terminal }})</code>
69
+ </div>
70
+ {{ end }}
71
+ </div>
72
+ {{ end }}
73
+ </div>
74
+ </li>
75
+ {{ end }}
76
+ </ul>
77
+ </div>
78
+ </div>
79
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
80
+ <script src="%{file}.js"></script>
81
+ </body>
82
+ </html>
@@ -1,9 +1,9 @@
1
- $(function() {
2
- $(".section").each(function(i, element) {
3
- var $element = $(element);
4
-
5
- $(element).children("h2, h3, h4, h5, h6").on("click", function() {
6
- $(element).children(".section-data").toggleClass("display");
7
- });
8
- });
9
- });
1
+ $(function() {
2
+ $(".section").each(function(i, element) {
3
+ var $element = $(element);
4
+
5
+ $(element).children("h2, h3, h4, h5, h6").on("click", function() {
6
+ $(element).children(".section-data").toggleClass("display");
7
+ });
8
+ });
9
+ });
@@ -0,0 +1,61 @@
1
+ Productions:
2
+ <%
3
+ len = grammar.all_productions.size.to_s.size
4
+ productions = recognizer.states.map(&:rules).inject(:merge).
5
+ select(&:final?).map { |x| [x.to_s(false), x.production.block] }
6
+ body = productions.map { |_| _[0].size }.max
7
+ productions.each do |prod|
8
+ -%>
9
+ <%= sprintf("%-#{body}s", prod[0]) %> <%= prod[1] %>
10
+ <% end -%>
11
+
12
+ <% if unused_symbols.any? -%>
13
+ Symbols unused in grammar:
14
+ <%- unused_symbols.each do |sym| -%>
15
+ <%= sym %>
16
+ <%- end -%>
17
+ <%- end -%>
18
+
19
+ Precedence:
20
+ --- highest
21
+ <% grammar.precedence.each do |pr| -%>
22
+ <%= format("%-8s", pr.type) %> <%= pr.level %>:
23
+ <%= "{" << pr.tokens.to_a.join(", ") << "}" %>
24
+ <%- end -%>
25
+ --- lowest
26
+
27
+ <%
28
+ states = grammar.states.to_a
29
+ table.each_with_index do |v, i|
30
+ state = states[i]
31
+ -%>
32
+ State <%= i %>:
33
+ <%- state.rules.each do |rule| -%>
34
+ <%= rule %>
35
+ {<%= rule.lookahead.to_a.join(", ") %>}
36
+ <%
37
+ end
38
+ transitions = v.each.select { |_, a| a && a[0] == :state }
39
+ reductions = v.each.select { |_, a| a && a[0] == :reduce}
40
+ accepting = v.each.select { |_, a| a && a[0] == :accept}
41
+ thing = [:transitions, :reductions, :accepting]
42
+ num_type = {
43
+ transitions: "State",
44
+ reductions: "Rule",
45
+ accepting: "Rule"
46
+ }
47
+ h = Hash[thing.zip([transitions, reductions, accepting])]
48
+ h.each do |key, value|
49
+ next unless value.any?
50
+ -%>
51
+ <%= key %>:
52
+ <%
53
+ value.each do |token, (_, name)|
54
+ token_value = grammar.terminals.
55
+ find { |_| _.name == token } || token
56
+ -%>
57
+ <%= token_value %>: <%= num_type[key] %> <%= name %>
58
+ <%- end -%>
59
+ <%- end -%>
60
+
61
+ <%- end -%>