antelope 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -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 [Grammar::Token::Nonterminal]
17
- attr_reader :left
18
-
19
- # The right-hand side of the rule.
20
- #
21
- # @return [Array<Grammar::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 {Grammar::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 [Grammar::Precedence]
51
- attr_accessor :precedence
52
-
53
- # The associated production.
54
- #
55
- # @return [Grammar::Production]
56
- attr_reader :production
57
-
58
- include Comparable
59
-
60
- # Initialize the rule.
61
- #
62
- # @param production [Grammar::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 = format('%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 {Grammar::Token}.
106
- #
107
- # @return [Grammar::Token]
108
- def active
109
- right[position] || Grammar::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 && right.size == other.right.size &&
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<(Grammar::Token::Nonterminal, Array<Grammar::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 [Grammar::Token::Nonterminal]
17
+ attr_reader :left
18
+
19
+ # The right-hand side of the rule.
20
+ #
21
+ # @return [Array<Grammar::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 {Grammar::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 [Grammar::Precedence]
51
+ attr_accessor :precedence
52
+
53
+ # The associated production.
54
+ #
55
+ # @return [Grammar::Production]
56
+ attr_reader :production
57
+
58
+ include Comparable
59
+
60
+ # Initialize the rule.
61
+ #
62
+ # @param production [Grammar::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 = format('%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 {Grammar::Token}.
106
+ #
107
+ # @return [Grammar::Token]
108
+ def active
109
+ right[position] || Grammar::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 && right.size == other.right.size &&
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<(Grammar::Token::Nonterminal, Array<Grammar::Token>, Numeric)>]
210
+ def to_a
211
+ @_array ||= [left, right, position]
212
+ end
213
+ end
214
+ end
215
+ end
216
+ end