antelope 0.2.0 → 0.2.2

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 (96) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +25 -23
  3. data/.rspec +3 -3
  4. data/.travis.yml +10 -9
  5. data/.yardopts +7 -7
  6. data/CONTRIBUTING.md +38 -38
  7. data/GENERATORS.md +124 -124
  8. data/Gemfile +7 -7
  9. data/LICENSE.txt +22 -22
  10. data/README.md +104 -104
  11. data/Rakefile +2 -2
  12. data/TODO.md +58 -58
  13. data/antelope.gemspec +28 -28
  14. data/bin/antelope +7 -7
  15. data/examples/deterministic.ace +35 -35
  16. data/examples/example.ace +51 -50
  17. data/examples/example.err +192 -0
  18. data/examples/{example.output → example.inf} +384 -385
  19. data/examples/liquidscript.ace +233 -162
  20. data/examples/simple.ace +22 -22
  21. data/lib/antelope/ace/compiler.rb +334 -334
  22. data/lib/antelope/ace/errors.rb +48 -48
  23. data/lib/antelope/ace/grammar/generation.rb +80 -80
  24. data/lib/antelope/ace/grammar/loading.rb +53 -53
  25. data/lib/antelope/ace/grammar/precedences.rb +68 -65
  26. data/lib/antelope/ace/grammar/productions.rb +156 -150
  27. data/lib/antelope/ace/grammar/symbols.rb +66 -66
  28. data/lib/antelope/ace/grammar.rb +69 -69
  29. data/lib/antelope/ace/precedence.rb +61 -61
  30. data/lib/antelope/ace/production.rb +57 -57
  31. data/lib/antelope/ace/scanner/argument.rb +57 -57
  32. data/lib/antelope/ace/scanner/first.rb +89 -89
  33. data/lib/antelope/ace/scanner/second.rb +177 -177
  34. data/lib/antelope/ace/scanner/third.rb +27 -27
  35. data/lib/antelope/ace/scanner.rb +134 -134
  36. data/lib/antelope/ace/token/epsilon.rb +24 -24
  37. data/lib/antelope/ace/token/error.rb +26 -26
  38. data/lib/antelope/ace/token/nonterminal.rb +17 -17
  39. data/lib/antelope/ace/token/terminal.rb +17 -17
  40. data/lib/antelope/ace/token.rb +238 -238
  41. data/lib/antelope/ace.rb +53 -53
  42. data/lib/antelope/cli.rb +55 -55
  43. data/lib/antelope/errors.rb +8 -8
  44. data/lib/antelope/generation/constructor/first.rb +88 -88
  45. data/lib/antelope/generation/constructor/follow.rb +103 -103
  46. data/lib/antelope/generation/constructor/nullable.rb +64 -64
  47. data/lib/antelope/generation/constructor.rb +126 -126
  48. data/lib/antelope/generation/errors.rb +17 -17
  49. data/lib/antelope/generation/null.rb +13 -13
  50. data/lib/antelope/generation/recognizer/rule.rb +216 -216
  51. data/lib/antelope/generation/recognizer/state.rb +130 -130
  52. data/lib/antelope/generation/recognizer.rb +180 -180
  53. data/lib/antelope/generation/tableizer.rb +175 -154
  54. data/lib/antelope/generation.rb +15 -15
  55. data/lib/antelope/generator/base.rb +264 -264
  56. data/lib/antelope/generator/c.rb +11 -11
  57. data/lib/antelope/generator/c_header.rb +105 -105
  58. data/lib/antelope/generator/c_source.rb +39 -39
  59. data/lib/antelope/generator/error.rb +34 -0
  60. data/lib/antelope/generator/group.rb +57 -57
  61. data/lib/antelope/generator/html.rb +51 -0
  62. data/lib/antelope/generator/info.rb +47 -0
  63. data/lib/antelope/generator/null.rb +18 -18
  64. data/lib/antelope/generator/output.rb +17 -49
  65. data/lib/antelope/generator/ruby.rb +79 -79
  66. data/lib/antelope/generator/templates/c_header.ant +36 -36
  67. data/lib/antelope/generator/templates/c_source.ant +202 -202
  68. data/lib/antelope/generator/templates/error.ant +33 -0
  69. data/lib/antelope/generator/templates/html/antelope.css +1 -0
  70. data/lib/antelope/generator/templates/html/antelope.html +1 -0
  71. data/lib/antelope/generator/templates/html/antelope.js +1 -0
  72. data/lib/antelope/generator/templates/html/css.ant +53 -0
  73. data/lib/antelope/generator/templates/html/html.ant +82 -0
  74. data/lib/antelope/generator/templates/html/js.ant +9 -0
  75. data/lib/antelope/generator/templates/info.ant +53 -0
  76. data/lib/antelope/generator/templates/ruby.ant +178 -146
  77. data/lib/antelope/generator.rb +66 -63
  78. data/lib/antelope/template/compiler.rb +78 -78
  79. data/lib/antelope/template/errors.rb +9 -9
  80. data/lib/antelope/template/scanner.rb +109 -109
  81. data/lib/antelope/template.rb +65 -60
  82. data/lib/antelope/version.rb +6 -6
  83. data/lib/antelope.rb +13 -13
  84. data/optimizations.txt +42 -0
  85. data/spec/antelope/ace/compiler_spec.rb +60 -60
  86. data/spec/antelope/ace/scanner_spec.rb +27 -27
  87. data/spec/antelope/constructor_spec.rb +133 -136
  88. data/spec/antelope/template_spec.rb +50 -49
  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 +15 -15
  93. data/subl/Ace (Ruby).JSON-tmLanguage +94 -94
  94. data/subl/Ace (Ruby).tmLanguage +153 -153
  95. metadata +17 -6
  96. data/lib/antelope/generator/templates/output.ant +0 -68
@@ -1,154 +1,175 @@
1
- # encoding: utf-8
2
-
3
- module Antelope
4
- module Generation
5
-
6
- # Constructs the table required for the parser.
7
- class Tableizer
8
-
9
- # The grammar that the table is based off of.
10
- #
11
- # @return [Ace::Grammar]
12
- attr_accessor :grammar
13
-
14
- # The table itself.
15
- #
16
- # @return [Array<Hash<(Symbol, Array<(Symbol, Numeric)>)>>]
17
- attr_accessor :table
18
-
19
- # All rules in the grammar.
20
- #
21
- # @return [Hash<(Numeric, Recognizer::Rule)>]
22
- attr_accessor :rules
23
-
24
- attr_reader :conflicts
25
-
26
- # Initialize.
27
- #
28
- # @param grammar [Ace::Grammar]
29
- def initialize(grammar)
30
- @grammar = grammar
31
- end
32
-
33
- # Construct the table, and then check the table for conflicts.
34
- #
35
- # @return [void]
36
- # @see #tablize
37
- # @see #conflictize
38
- def call
39
- tablize
40
- conflictize
41
- defaultize
42
- end
43
-
44
- # Construct a table based on the grammar. The table itself is
45
- # an array whose elements are hashes; the index of the array
46
- # corresponds to the state ID, and the keys of the hashes
47
- # correspond to acceptable tokens. The values of the hashes
48
- # should be an array of arrays (at this point).
49
- #
50
- # @return [void]
51
- def tablize
52
- @table = Array.new(grammar.states.size) do
53
- Hash.new { |h, k| h[k] = [] }
54
- end
55
- @rules = []
56
-
57
- grammar.states.each do |state|
58
- state.transitions.each do |on, to|
59
- table[state.id][on] << [:state, to.id]
60
- end
61
-
62
- state.rules.each do |rule|
63
- @rules[rule.production.id] = rule.production
64
- if rule.final?
65
- rule.lookahead.each do |look|
66
- table[state.id][look.name] <<
67
- [:reduce, rule.production.id]
68
- end
69
-
70
- if rule.production.id.zero?
71
- table[state.id][:$end] =
72
- [[:accept, rule.production.id]]
73
- end
74
- end
75
- end
76
- end
77
-
78
- table
79
- end
80
-
81
- # Resolve any conflicts through precedence, if we can. If we
82
- # can't, let the user know. This makes sure that every value
83
- # of the hashes is a single array.
84
- #
85
- # @raise [UnresolvableConflictError] if a conflict could not be
86
- # resolved using precedence rules.
87
- # @return [void]
88
- def conflictize
89
- @conflicts = Hash.new { |h, k| h[k] = {} }
90
- @table.each_with_index do |v, state|
91
- v.each do |on, data|
92
- if data.size == 1
93
- @table[state][on] = data[0]
94
- next
95
- end
96
-
97
- terminal = grammar.precedence_for(on)
98
-
99
- rule_part, other_part = data.sort_by { |(t, _)| t }
100
-
101
- unless other_part[0] == :state
102
- $stderr.puts \
103
- "Could not determine move for #{on} in state " \
104
- "#{state} (reduce/reduce conflict)"
105
- next
106
- end
107
-
108
- result = @rules[rule_part[1]].prec <=> terminal
109
-
110
- case result
111
- when 0
112
- conflicts[state][on] = [
113
- rule_part, other_part, terminal, @rules[rule_part[1]].prec
114
- ]
115
- $stderr.puts \
116
- "Could not determine move for #{on} in state " \
117
- "#{state} (shift/reduce conflict)"
118
- when 1
119
- @table[state][on] = rule_part
120
- when -1
121
- @table[state][on] = other_part
122
- end
123
- end
124
- end
125
- end
126
-
127
- # Reduce many transitions into a single `$default` transition.
128
- # This only works if there is no `$empty` transition; if there
129
- # is an `$empty` transition, then the `$default` transition is
130
- # set to be the `$empty` transition.
131
- #
132
- # @return [void]
133
- def defaultize
134
- max = @table.map { |s| s.keys.size }.max
135
- @table.each_with_index do |state|
136
- if state.key?(:$empty)
137
- state[:$default] = state[:$empty]
138
- else
139
- common = state.group_by { |k, v| v }.values.
140
- sort_by(&:size).first
141
-
142
- if common.size > (max / 2)
143
- action = common[0][1]
144
-
145
- keys = common.map(&:first)
146
- state.delete_if { |k, _| keys.include?(k) }
147
- state[:$default] = action
148
- end
149
- end
150
- end
151
- end
152
- end
153
- end
154
- end
1
+ # encoding: utf-8
2
+
3
+ module Antelope
4
+ module Generation
5
+
6
+ # Constructs the table required for the parser.
7
+ class Tableizer
8
+
9
+ # The grammar that the table is based off of.
10
+ #
11
+ # @return [Ace::Grammar]
12
+ attr_accessor :grammar
13
+
14
+ # The table itself.
15
+ #
16
+ # @return [Array<Hash<(Symbol, Array<(Symbol, Numeric)>)>>]
17
+ attr_accessor :table
18
+
19
+ # All rules in the grammar.
20
+ #
21
+ # @return [Hash<(Numeric, Recognizer::Rule)>]
22
+ attr_accessor :rules
23
+
24
+ attr_reader :conflicts
25
+
26
+ # Initialize.
27
+ #
28
+ # @param grammar [Ace::Grammar]
29
+ def initialize(grammar)
30
+ @grammar = grammar
31
+ end
32
+
33
+ # Construct the table, and then check the table for conflicts.
34
+ #
35
+ # @return [void]
36
+ # @see #tablize
37
+ # @see #conflictize
38
+ def call
39
+ tablize
40
+ conflictize
41
+ defaultize
42
+ end
43
+
44
+ # Construct a table based on the grammar. The table itself is
45
+ # an array whose elements are hashes; the index of the array
46
+ # corresponds to the state ID, and the keys of the hashes
47
+ # correspond to acceptable tokens. The values of the hashes
48
+ # should be an array of arrays (at this point).
49
+ #
50
+ # @return [void]
51
+ def tablize
52
+ @table = Array.new(grammar.states.size) do
53
+ Hash.new { |h, k| h[k] = [] }
54
+ end
55
+ @rules = []
56
+
57
+ grammar.states.each do |state|
58
+ state.transitions.each do |on, to|
59
+ table[state.id][on] << [:state, to.id]
60
+ end
61
+
62
+ state.rules.each do |rule|
63
+ @rules[rule.production.id] = rule.production
64
+ if rule.final?
65
+ rule.lookahead.each do |look|
66
+ table[state.id][look.name] <<
67
+ [:reduce, rule.production.id]
68
+ end
69
+
70
+ if rule.production.id.zero?
71
+ table[state.id][:$end] =
72
+ [[:accept, rule.production.id]]
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ table
79
+ end
80
+
81
+ # Resolve any conflicts through precedence, if we can. If we
82
+ # can't, let the user know. This makes sure that every value
83
+ # of the hashes is a single array.
84
+ #
85
+ # @raise [UnresolvableConflictError] if a conflict could not be
86
+ # resolved using precedence rules.
87
+ # @return [void]
88
+ def conflictize
89
+ states = grammar.states.to_a.sort_by(&:id)
90
+ @conflicts = Hash.new { |h, k| h[k] = {} }
91
+ @table.each_with_index do |v, state|
92
+ v.each do |on, data|
93
+ if data.size == 1
94
+ @table[state][on] = data[0]
95
+ next
96
+ end
97
+
98
+ terminal = grammar.precedence_for(on)
99
+ rule_part, other_part = data.sort_by { |(t, _)| t }
100
+
101
+ conflict = proc do |result|
102
+ hash = { result: result,
103
+ terminal: terminal,
104
+ prec: @rules[rule_part[1]].prec,
105
+ data: data,
106
+ rules: [], transitions: [] }
107
+
108
+ hash[:rules].concat(data.select { |part|
109
+ part[0] == :reduce || part[0] == :accept
110
+ }.map { |(_, id)|
111
+ states[state].rules.select(&:final?).
112
+ detect { |rule| rule.production.id == id }
113
+ })
114
+ hash[:transitions].concat(data.select { |part|
115
+ part[0] == :state
116
+ }.map { |_|
117
+ states[state].rules.
118
+ detect { |rule| rule.active.name == on }
119
+ })
120
+
121
+ #conflicts[state][on] = [result, rule_part, other_part,
122
+ # terminal, @rules[rule_part[1]].prec]
123
+ conflicts[state][on] = hash
124
+ end
125
+
126
+ unless other_part[0] == :state
127
+ conflict.call(0)
128
+ $stderr.puts \
129
+ "Could not determine move for #{on} in state " \
130
+ "#{state} (reduce/reduce conflict)"
131
+ next
132
+ end
133
+
134
+ result = @rules[rule_part[1]].prec <=> terminal
135
+ conflict.call(result)
136
+
137
+ case result
138
+ when 0
139
+ @table[state][on] = nil
140
+ $stderr.puts \
141
+ "Could not determine move for #{on} in state " \
142
+ "#{state} (shift/reduce conflict)"
143
+ when 1
144
+ @table[state][on] = rule_part
145
+ when -1
146
+ @table[state][on] = other_part
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ # Reduce many transitions into a single `$default` transition.
153
+ # This only works if there is no `$empty` transition; if there
154
+ # is an `$empty` transition, then the `$default` transition is
155
+ # set to be the `$empty` transition.
156
+ #
157
+ # @return [void]
158
+ def defaultize
159
+ max = @table.map { |s| s.keys.size }.max
160
+ @table.each_with_index do |state|
161
+ common = state.group_by { |k, v| v }.values.
162
+ sort_by(&:size).first
163
+
164
+ if common.size > (max / 2)
165
+ action = common[0][1]
166
+
167
+ keys = common.map(&:first)
168
+ state.delete_if { |k, _| keys.include?(k) }
169
+ state[:$default] = action
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
@@ -1,15 +1,15 @@
1
- # encoding: utf-8
2
-
3
- require "antelope/generation/errors"
4
- require "antelope/generation/constructor"
5
- require "antelope/generation/recognizer"
6
- require "antelope/generation/tableizer"
7
- require "antelope/generation/null"
8
-
9
- module Antelope
10
-
11
- # Contains the generation mods.
12
- module Generation
13
-
14
- end
15
- end
1
+ # encoding: utf-8
2
+
3
+ require "antelope/generation/errors"
4
+ require "antelope/generation/constructor"
5
+ require "antelope/generation/recognizer"
6
+ require "antelope/generation/tableizer"
7
+ require "antelope/generation/null"
8
+
9
+ module Antelope
10
+
11
+ # Contains the generation mods.
12
+ module Generation
13
+
14
+ end
15
+ end