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,216 +1,216 @@
1
- # encoding: utf-8
2
-
3
- require "securerandom"
4
-
5
- module Antelope
6
- module Generation
7
- class Recognizer
8
-
9
- # Defines a rule. A rule has a corresponding production, and a
10
- # position in that production. It also contains extra
11
- # information for other reasons.
12
- class Rule
13
-
14
- # The left-hand side of the rule.
15
- #
16
- # @return [Ace::Token::Nonterminal]
17
- attr_reader :left
18
-
19
- # The right-hand side of the rule.
20
- #
21
- # @return [Array<Ace::Token>]
22
- attr_reader :right
23
-
24
- # The current position inside of the rule.
25
- #
26
- # @return [Numeric]
27
- attr_reader :position
28
-
29
- # The block to be executed on production match.
30
- #
31
- # @deprecated Use {Ace::Production#block} instead.
32
- # @return [String]
33
- attr_reader :block
34
-
35
- # The lookahead set for this specific rule. Contains nothing
36
- # unless {#final?} returns true.
37
- #
38
- # @return [Set<Symbol>]
39
- attr_accessor :lookahead
40
-
41
- # The id for this rule. Initialy, this is set to a string of
42
- # hexadecimal characters; after construction of all states,
43
- # however, it is a number.
44
- #
45
- # @return [String, Numeric]
46
- attr_accessor :id
47
-
48
- # The precedence for this rule.
49
- #
50
- # @return [Ace::Precedence]
51
- attr_accessor :precedence
52
-
53
- # The associated production.
54
- #
55
- # @return [Ace::Production]
56
- attr_reader :production
57
-
58
- include Comparable
59
-
60
- # Initialize the rule.
61
- #
62
- # @param production [Ace::Production] the production
63
- # that this rule is based off of.
64
- # @param position [Numeric] the position that this rule is in
65
- # the production.
66
- # @param inherited [nil] do not use.
67
- def initialize(production, position, inherited = false)
68
- @left = production.label.dup
69
- @position = position
70
- @lookahead = Set.new
71
- @precedence = production.prec
72
- @production = production
73
- @block = production.block
74
- @id = SecureRandom.hex
75
-
76
- if inherited
77
- @left, @right = inherited
78
- else
79
- @right = production.items.map(&:dup)
80
- end
81
- end
82
-
83
- # Give a nice representation of the rule as a string.
84
- #
85
- # @return [String]
86
- def inspect
87
- "#<#{self.class} id=#{id} left=#{left} " \
88
- "right=[#{right.join(" ")}] position=#{position}>"
89
- end
90
-
91
- # Give a nicer representation of the rule as a string. Shows
92
- # the id of the rule, the precedence, and the actual
93
- # production; if the given argument is true, it will show a
94
- # dot to show the position of the rule.
95
- #
96
- # @param dot [Boolean] show the current position of the rule.
97
- # @return [String]
98
- def to_s(dot = true)
99
- "#{id}/#{precedence.type.to_s[0]}#{precedence.level}: " \
100
- "#{left} → #{right[0, position].join(" ")}" \
101
- "#{" • " if dot}#{right[position..-1].join(" ")}"
102
- end
103
-
104
- # Returns the active token. If there is no active token, it
105
- # returns a blank {Ace::Token}.
106
- #
107
- # @return [Ace::Token]
108
- def active
109
- right[position] or Ace::Token.new(nil)
110
- end
111
-
112
- # Creates the rule after this one by incrementing the position
113
- # by one. {#succ?} should be called to make sure that this
114
- # rule exists.
115
- #
116
- # @return [Rule]
117
- def succ
118
- Rule.new(production, position + 1, [left, right])
119
- end
120
-
121
- # Checks to see if a rule can exist after this one; i.e. the
122
- # position is not equal to the size of the right side of the
123
- # rule.
124
- #
125
- # @return [Boolean]
126
- def succ?
127
- right.size > position
128
- end
129
-
130
- # Checks to see if this is the final rule, as in no rule can
131
- # exist after this one; i.e. the position is equal to the
132
- # size of the right side.
133
- #
134
- # @return [Boolean]
135
- def final?
136
- !succ?
137
- end
138
-
139
- # The complete opposite of {#final?} - it checks to see if
140
- # this is the first rule, as in no rule can exist before this
141
- # one; i.e. the position is zero.
142
- #
143
- # @return [Boolean]
144
- def start?
145
- position.zero?
146
- end
147
-
148
- # Compares this rule to another object. If the other object
149
- # is not a rule, it delegates the comparison. Otherwise, it
150
- # converts both this and the other rule into arrays and
151
- # compares the result.
152
- #
153
- # @param other [Object] the object to compare.
154
- # @return [Numeric]
155
- def <=>(other)
156
- if other.is_a? Rule
157
- to_a <=> other.to_a
158
- else
159
- super
160
- end
161
- end
162
-
163
- def ==(other)
164
- hash == other.hash if other.respond_to?(:hash)
165
- end
166
-
167
- alias_method :eql?, :==
168
-
169
- # Fuzzily compares this object to another object. If the
170
- # other object is not a rule, it delegates the comparison.
171
- # Otherwise, it fuzzily compares the left and right sides.
172
- #
173
- # @param other [Object] the object to compare.
174
- # @return [Numeric]
175
- def ===(other)
176
- if other.is_a? Rule
177
- left === other.left and right.size == other.right.size and
178
- right.each_with_index.
179
- all? { |e, i| e === other.right[i] }
180
- else
181
- super
182
- end
183
- end
184
-
185
- # Produces a clone of the rule; any modifications made to the
186
- # contents of that rule do not reflect the contents of this
187
- # rule.
188
- #
189
- # @return [Rule]
190
- def clone
191
- Rule.new(production, position)
192
- end
193
-
194
- # Generates a hash for this class.
195
- #
196
- # @note This is not intended for use. It is only defined to be
197
- # compatible with Hashs (and by extension, Sets).
198
- # @private
199
- # @return [Object]
200
- def hash
201
- @_hash ||= to_a.hash
202
- end
203
-
204
- # Creates an array representation of this class.
205
- #
206
- # @note This is not intended for use. It is only defined to
207
- # make equality checking easier, and to create a hash.
208
- # @private
209
- # @return [Array<(Ace::Token::Nonterminal, Array<Ace::Token>, Numeric)>]
210
- def to_a
211
- @_array ||= [left, right, position]
212
- end
213
- end
214
- end
215
- end
216
- end
1
+ # encoding: utf-8
2
+
3
+ require "securerandom"
4
+
5
+ module Antelope
6
+ module Generation
7
+ class Recognizer
8
+
9
+ # Defines a rule. A rule has a corresponding production, and a
10
+ # position in that production. It also contains extra
11
+ # information for other reasons.
12
+ class Rule
13
+
14
+ # The left-hand side of the rule.
15
+ #
16
+ # @return [Ace::Token::Nonterminal]
17
+ attr_reader :left
18
+
19
+ # The right-hand side of the rule.
20
+ #
21
+ # @return [Array<Ace::Token>]
22
+ attr_reader :right
23
+
24
+ # The current position inside of the rule.
25
+ #
26
+ # @return [Numeric]
27
+ attr_reader :position
28
+
29
+ # The block to be executed on production match.
30
+ #
31
+ # @deprecated Use {Ace::Production#block} instead.
32
+ # @return [String]
33
+ attr_reader :block
34
+
35
+ # The lookahead set for this specific rule. Contains nothing
36
+ # unless {#final?} returns true.
37
+ #
38
+ # @return [Set<Symbol>]
39
+ attr_accessor :lookahead
40
+
41
+ # The id for this rule. Initialy, this is set to a string of
42
+ # hexadecimal characters; after construction of all states,
43
+ # however, it is a number.
44
+ #
45
+ # @return [String, Numeric]
46
+ attr_accessor :id
47
+
48
+ # The precedence for this rule.
49
+ #
50
+ # @return [Ace::Precedence]
51
+ attr_accessor :precedence
52
+
53
+ # The associated production.
54
+ #
55
+ # @return [Ace::Production]
56
+ attr_reader :production
57
+
58
+ include Comparable
59
+
60
+ # Initialize the rule.
61
+ #
62
+ # @param production [Ace::Production] the production
63
+ # that this rule is based off of.
64
+ # @param position [Numeric] the position that this rule is in
65
+ # the production.
66
+ # @param inherited [nil] do not use.
67
+ def initialize(production, position, inherited = false)
68
+ @left = production.label.dup
69
+ @position = position
70
+ @lookahead = Set.new
71
+ @precedence = production.prec
72
+ @production = production
73
+ @block = production.block
74
+ @id = "%10x" % object_id
75
+
76
+ if inherited
77
+ @left, @right = inherited
78
+ else
79
+ @right = production.items.map(&:dup)
80
+ end
81
+ end
82
+
83
+ # Give a nice representation of the rule as a string.
84
+ #
85
+ # @return [String]
86
+ def inspect
87
+ "#<#{self.class} id=#{id} left=#{left} " \
88
+ "right=[#{right.join(" ")}] position=#{position}>"
89
+ end
90
+
91
+ # Give a nicer representation of the rule as a string. Shows
92
+ # the id of the rule, the precedence, and the actual
93
+ # production; if the given argument is true, it will show a
94
+ # dot to show the position of the rule.
95
+ #
96
+ # @param dot [Boolean] show the current position of the rule.
97
+ # @return [String]
98
+ def to_s(dot = true)
99
+ "#{id}/#{precedence.type.to_s[0]}#{precedence.level}: " \
100
+ "#{left} → #{right[0, position].join(" ")}" \
101
+ "#{" • " if dot}#{right[position..-1].join(" ")}"
102
+ end
103
+
104
+ # Returns the active token. If there is no active token, it
105
+ # returns a blank {Ace::Token}.
106
+ #
107
+ # @return [Ace::Token]
108
+ def active
109
+ right[position] or Ace::Token.new(nil)
110
+ end
111
+
112
+ # Creates the rule after this one by incrementing the position
113
+ # by one. {#succ?} should be called to make sure that this
114
+ # rule exists.
115
+ #
116
+ # @return [Rule]
117
+ def succ
118
+ Rule.new(production, position + 1, [left, right])
119
+ end
120
+
121
+ # Checks to see if a rule can exist after this one; i.e. the
122
+ # position is not equal to the size of the right side of the
123
+ # rule.
124
+ #
125
+ # @return [Boolean]
126
+ def succ?
127
+ right.size > position
128
+ end
129
+
130
+ # Checks to see if this is the final rule, as in no rule can
131
+ # exist after this one; i.e. the position is equal to the
132
+ # size of the right side.
133
+ #
134
+ # @return [Boolean]
135
+ def final?
136
+ !succ?
137
+ end
138
+
139
+ # The complete opposite of {#final?} - it checks to see if
140
+ # this is the first rule, as in no rule can exist before this
141
+ # one; i.e. the position is zero.
142
+ #
143
+ # @return [Boolean]
144
+ def start?
145
+ position.zero?
146
+ end
147
+
148
+ # Compares this rule to another object. If the other object
149
+ # is not a rule, it delegates the comparison. Otherwise, it
150
+ # converts both this and the other rule into arrays and
151
+ # compares the result.
152
+ #
153
+ # @param other [Object] the object to compare.
154
+ # @return [Numeric]
155
+ def <=>(other)
156
+ if other.is_a? Rule
157
+ to_a <=> other.to_a
158
+ else
159
+ super
160
+ end
161
+ end
162
+
163
+ def ==(other)
164
+ hash == other.hash if other.respond_to?(:hash)
165
+ end
166
+
167
+ alias_method :eql?, :==
168
+
169
+ # Fuzzily compares this object to another object. If the
170
+ # other object is not a rule, it delegates the comparison.
171
+ # Otherwise, it fuzzily compares the left and right sides.
172
+ #
173
+ # @param other [Object] the object to compare.
174
+ # @return [Numeric]
175
+ def ===(other)
176
+ if other.is_a? Rule
177
+ left === other.left and right.size == other.right.size and
178
+ right.each_with_index.
179
+ all? { |e, i| e === other.right[i] }
180
+ else
181
+ super
182
+ end
183
+ end
184
+
185
+ # Produces a clone of the rule; any modifications made to the
186
+ # contents of that rule do not reflect the contents of this
187
+ # rule.
188
+ #
189
+ # @return [Rule]
190
+ def clone
191
+ Rule.new(production, position)
192
+ end
193
+
194
+ # Generates a hash for this class.
195
+ #
196
+ # @note This is not intended for use. It is only defined to be
197
+ # compatible with Hashs (and by extension, Sets).
198
+ # @private
199
+ # @return [Object]
200
+ def hash
201
+ @_hash ||= to_a.hash
202
+ end
203
+
204
+ # Creates an array representation of this class.
205
+ #
206
+ # @note This is not intended for use. It is only defined to
207
+ # make equality checking easier, and to create a hash.
208
+ # @private
209
+ # @return [Array<(Ace::Token::Nonterminal, Array<Ace::Token>, Numeric)>]
210
+ def to_a
211
+ @_array ||= [left, right, position]
212
+ end
213
+ end
214
+ end
215
+ end
216
+ end