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.
- checksums.yaml +4 -4
- data/.gitignore +25 -23
- data/.rspec +3 -3
- data/.travis.yml +10 -9
- data/.yardopts +7 -7
- data/CONTRIBUTING.md +38 -38
- data/GENERATORS.md +124 -124
- data/Gemfile +7 -7
- data/LICENSE.txt +22 -22
- data/README.md +104 -104
- data/Rakefile +2 -2
- data/TODO.md +58 -58
- data/antelope.gemspec +28 -28
- data/bin/antelope +7 -7
- data/examples/deterministic.ace +35 -35
- data/examples/example.ace +51 -50
- data/examples/example.err +192 -0
- data/examples/{example.output → example.inf} +384 -385
- data/examples/liquidscript.ace +233 -162
- data/examples/simple.ace +22 -22
- data/lib/antelope/ace/compiler.rb +334 -334
- data/lib/antelope/ace/errors.rb +48 -48
- data/lib/antelope/ace/grammar/generation.rb +80 -80
- data/lib/antelope/ace/grammar/loading.rb +53 -53
- data/lib/antelope/ace/grammar/precedences.rb +68 -65
- data/lib/antelope/ace/grammar/productions.rb +156 -150
- data/lib/antelope/ace/grammar/symbols.rb +66 -66
- data/lib/antelope/ace/grammar.rb +69 -69
- data/lib/antelope/ace/precedence.rb +61 -61
- data/lib/antelope/ace/production.rb +57 -57
- data/lib/antelope/ace/scanner/argument.rb +57 -57
- data/lib/antelope/ace/scanner/first.rb +89 -89
- data/lib/antelope/ace/scanner/second.rb +177 -177
- data/lib/antelope/ace/scanner/third.rb +27 -27
- data/lib/antelope/ace/scanner.rb +134 -134
- data/lib/antelope/ace/token/epsilon.rb +24 -24
- data/lib/antelope/ace/token/error.rb +26 -26
- data/lib/antelope/ace/token/nonterminal.rb +17 -17
- data/lib/antelope/ace/token/terminal.rb +17 -17
- data/lib/antelope/ace/token.rb +238 -238
- data/lib/antelope/ace.rb +53 -53
- data/lib/antelope/cli.rb +55 -55
- data/lib/antelope/errors.rb +8 -8
- data/lib/antelope/generation/constructor/first.rb +88 -88
- data/lib/antelope/generation/constructor/follow.rb +103 -103
- data/lib/antelope/generation/constructor/nullable.rb +64 -64
- data/lib/antelope/generation/constructor.rb +126 -126
- data/lib/antelope/generation/errors.rb +17 -17
- data/lib/antelope/generation/null.rb +13 -13
- data/lib/antelope/generation/recognizer/rule.rb +216 -216
- data/lib/antelope/generation/recognizer/state.rb +130 -130
- data/lib/antelope/generation/recognizer.rb +180 -180
- data/lib/antelope/generation/tableizer.rb +175 -154
- data/lib/antelope/generation.rb +15 -15
- data/lib/antelope/generator/base.rb +264 -264
- data/lib/antelope/generator/c.rb +11 -11
- data/lib/antelope/generator/c_header.rb +105 -105
- data/lib/antelope/generator/c_source.rb +39 -39
- data/lib/antelope/generator/error.rb +34 -0
- data/lib/antelope/generator/group.rb +57 -57
- data/lib/antelope/generator/html.rb +51 -0
- data/lib/antelope/generator/info.rb +47 -0
- data/lib/antelope/generator/null.rb +18 -18
- data/lib/antelope/generator/output.rb +17 -49
- data/lib/antelope/generator/ruby.rb +79 -79
- data/lib/antelope/generator/templates/c_header.ant +36 -36
- data/lib/antelope/generator/templates/c_source.ant +202 -202
- data/lib/antelope/generator/templates/error.ant +33 -0
- data/lib/antelope/generator/templates/html/antelope.css +1 -0
- data/lib/antelope/generator/templates/html/antelope.html +1 -0
- data/lib/antelope/generator/templates/html/antelope.js +1 -0
- data/lib/antelope/generator/templates/html/css.ant +53 -0
- data/lib/antelope/generator/templates/html/html.ant +82 -0
- data/lib/antelope/generator/templates/html/js.ant +9 -0
- data/lib/antelope/generator/templates/info.ant +53 -0
- data/lib/antelope/generator/templates/ruby.ant +178 -146
- data/lib/antelope/generator.rb +66 -63
- data/lib/antelope/template/compiler.rb +78 -78
- data/lib/antelope/template/errors.rb +9 -9
- data/lib/antelope/template/scanner.rb +109 -109
- data/lib/antelope/template.rb +65 -60
- data/lib/antelope/version.rb +6 -6
- data/lib/antelope.rb +13 -13
- data/optimizations.txt +42 -0
- data/spec/antelope/ace/compiler_spec.rb +60 -60
- data/spec/antelope/ace/scanner_spec.rb +27 -27
- data/spec/antelope/constructor_spec.rb +133 -136
- data/spec/antelope/template_spec.rb +50 -49
- data/spec/fixtures/simple.ace +22 -22
- data/spec/spec_helper.rb +39 -39
- data/spec/support/benchmark_helper.rb +5 -5
- data/spec/support/grammar_helper.rb +15 -15
- data/subl/Ace (Ruby).JSON-tmLanguage +94 -94
- data/subl/Ace (Ruby).tmLanguage +153 -153
- metadata +17 -6
- data/lib/antelope/generator/templates/output.ant +0 -68
data/lib/antelope/ace/errors.rb
CHANGED
@@ -1,48 +1,48 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Antelope
|
4
|
-
module Ace
|
5
|
-
|
6
|
-
# Defines an error that can occur within the Ace module. All
|
7
|
-
# errors that are raised within the Ace module are subclasses of
|
8
|
-
# this.
|
9
|
-
class Error < Antelope::Error
|
10
|
-
end
|
11
|
-
|
12
|
-
# Used primarily in the {Compiler}, this is raised when the
|
13
|
-
# version requirement of the Ace file doesn't match the running
|
14
|
-
# version of Ace.
|
15
|
-
class IncompatibleVersionError < Error
|
16
|
-
end
|
17
|
-
|
18
|
-
# Used primarily in the {Scanner}, this is raised when an input
|
19
|
-
# is malformed. The message should contain a snippet of the input
|
20
|
-
# which caused the error.
|
21
|
-
class SyntaxError < Error
|
22
|
-
end
|
23
|
-
|
24
|
-
# This is used primarily in the {Grammar}; if a rule references a
|
25
|
-
# token (a nonterminal or a terminal) that was not previously
|
26
|
-
# defined, this is raised.
|
27
|
-
class UndefinedTokenError < Error
|
28
|
-
end
|
29
|
-
|
30
|
-
# Primarily used in the {Compiler}, if a scanner token appears
|
31
|
-
# that should not be in the current state, this is raised.
|
32
|
-
class InvalidStateError < Error
|
33
|
-
end
|
34
|
-
|
35
|
-
# Primarily used in the {Grammar} (specifically
|
36
|
-
# {Grammar::Generation}), if the grammar could not determine the
|
37
|
-
# generator to use for the generation, it raises this.
|
38
|
-
class NoTypeError < Error
|
39
|
-
end
|
40
|
-
|
41
|
-
# Primarily used in the {Compiler}, it is raised if it encounters
|
42
|
-
# a directive it cannot handle. This is more to warn the
|
43
|
-
# developer that a directive they wrote may not be accepted by any
|
44
|
-
# generator.
|
45
|
-
class NoDirectiveError < Error
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Antelope
|
4
|
+
module Ace
|
5
|
+
|
6
|
+
# Defines an error that can occur within the Ace module. All
|
7
|
+
# errors that are raised within the Ace module are subclasses of
|
8
|
+
# this.
|
9
|
+
class Error < Antelope::Error
|
10
|
+
end
|
11
|
+
|
12
|
+
# Used primarily in the {Compiler}, this is raised when the
|
13
|
+
# version requirement of the Ace file doesn't match the running
|
14
|
+
# version of Ace.
|
15
|
+
class IncompatibleVersionError < Error
|
16
|
+
end
|
17
|
+
|
18
|
+
# Used primarily in the {Scanner}, this is raised when an input
|
19
|
+
# is malformed. The message should contain a snippet of the input
|
20
|
+
# which caused the error.
|
21
|
+
class SyntaxError < Error
|
22
|
+
end
|
23
|
+
|
24
|
+
# This is used primarily in the {Grammar}; if a rule references a
|
25
|
+
# token (a nonterminal or a terminal) that was not previously
|
26
|
+
# defined, this is raised.
|
27
|
+
class UndefinedTokenError < Error
|
28
|
+
end
|
29
|
+
|
30
|
+
# Primarily used in the {Compiler}, if a scanner token appears
|
31
|
+
# that should not be in the current state, this is raised.
|
32
|
+
class InvalidStateError < Error
|
33
|
+
end
|
34
|
+
|
35
|
+
# Primarily used in the {Grammar} (specifically
|
36
|
+
# {Grammar::Generation}), if the grammar could not determine the
|
37
|
+
# generator to use for the generation, it raises this.
|
38
|
+
class NoTypeError < Error
|
39
|
+
end
|
40
|
+
|
41
|
+
# Primarily used in the {Compiler}, it is raised if it encounters
|
42
|
+
# a directive it cannot handle. This is more to warn the
|
43
|
+
# developer that a directive they wrote may not be accepted by any
|
44
|
+
# generator.
|
45
|
+
class NoDirectiveError < Error
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,80 +1,80 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Antelope
|
4
|
-
module Ace
|
5
|
-
class Grammar
|
6
|
-
|
7
|
-
# The default modifiers for generation. It's not really
|
8
|
-
# recommended to (heh) modify this; however, adding your own
|
9
|
-
# modifier is always acceptable.
|
10
|
-
DEFAULT_MODIFIERS = [
|
11
|
-
[:recognizer, Generation::Recognizer ],
|
12
|
-
[:constructor, Generation::Constructor],
|
13
|
-
[:tableizer, Generation::Tableizer ]
|
14
|
-
].freeze
|
15
|
-
|
16
|
-
# Handles the generation of output for the grammar.
|
17
|
-
module Generation
|
18
|
-
|
19
|
-
# Generates the output. First, it runs through every given
|
20
|
-
# modifier, and instintates it. It then calls every modifier,
|
21
|
-
# turns it into a hash, and passes that hash to each of the
|
22
|
-
# given generators.
|
23
|
-
#
|
24
|
-
# @param options [Hash] options.
|
25
|
-
# @param generators [Array<Generator>] a list of generators
|
26
|
-
# to use in generation.
|
27
|
-
# @param modifiers [Array<Array<(Symbol, #call)>>] a list of
|
28
|
-
# modifiers to apply to the grammar.
|
29
|
-
# @return [void]
|
30
|
-
def generate(options = {},
|
31
|
-
generators = :guess,
|
32
|
-
modifiers = DEFAULT_MODIFIERS)
|
33
|
-
mods = modifiers.map(&:last).
|
34
|
-
map { |x| x.new(self) }
|
35
|
-
mods.each do |mod|
|
36
|
-
puts "Running mod #{mod.class}..." if options[:verbose]
|
37
|
-
mod.call
|
38
|
-
end
|
39
|
-
hash = Hash[modifiers.map(&:first).zip(mods)]
|
40
|
-
# This is when we'd generate
|
41
|
-
|
42
|
-
find_generators(generators, options).each do |gen|
|
43
|
-
puts "Running generator #{gen}..." if options[:verbose]
|
44
|
-
gen.new(self, hash).generate
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
# Find the corresponding generators. If the first argument
|
51
|
-
# isn't `:guess`, it returns the first argument. Otherwise,
|
52
|
-
# it tries to "intelligently guess" by checking the type from
|
53
|
-
# the options _or_ the compiler. If it is unable to find the
|
54
|
-
# type, it will raise a {NoTypeError}.
|
55
|
-
#
|
56
|
-
# @raise [NoTypeError] if it could not determine the type of
|
57
|
-
# the generator.
|
58
|
-
# @param generators [Symbol, Array<Generator>]
|
59
|
-
# @param options [Hash]
|
60
|
-
# @return [Array<Generator>]
|
61
|
-
def find_generators(generators, options)
|
62
|
-
return generators unless generators == :guess
|
63
|
-
|
64
|
-
generators = [Generator::Output]
|
65
|
-
|
66
|
-
# command line precedence...
|
67
|
-
type = options[:type] || options["type"] ||
|
68
|
-
compiler.options.fetch(:type)
|
69
|
-
|
70
|
-
generators << Generator.generators.fetch(type)
|
71
|
-
|
72
|
-
generators
|
73
|
-
|
74
|
-
rescue KeyError
|
75
|
-
raise NoTypeError, "Undefined type #{type}"
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Antelope
|
4
|
+
module Ace
|
5
|
+
class Grammar
|
6
|
+
|
7
|
+
# The default modifiers for generation. It's not really
|
8
|
+
# recommended to (heh) modify this; however, adding your own
|
9
|
+
# modifier is always acceptable.
|
10
|
+
DEFAULT_MODIFIERS = [
|
11
|
+
[:recognizer, Generation::Recognizer ],
|
12
|
+
[:constructor, Generation::Constructor],
|
13
|
+
[:tableizer, Generation::Tableizer ]
|
14
|
+
].freeze
|
15
|
+
|
16
|
+
# Handles the generation of output for the grammar.
|
17
|
+
module Generation
|
18
|
+
|
19
|
+
# Generates the output. First, it runs through every given
|
20
|
+
# modifier, and instintates it. It then calls every modifier,
|
21
|
+
# turns it into a hash, and passes that hash to each of the
|
22
|
+
# given generators.
|
23
|
+
#
|
24
|
+
# @param options [Hash] options.
|
25
|
+
# @param generators [Array<Generator>] a list of generators
|
26
|
+
# to use in generation.
|
27
|
+
# @param modifiers [Array<Array<(Symbol, #call)>>] a list of
|
28
|
+
# modifiers to apply to the grammar.
|
29
|
+
# @return [void]
|
30
|
+
def generate(options = {},
|
31
|
+
generators = :guess,
|
32
|
+
modifiers = DEFAULT_MODIFIERS)
|
33
|
+
mods = modifiers.map(&:last).
|
34
|
+
map { |x| x.new(self) }
|
35
|
+
mods.each do |mod|
|
36
|
+
puts "Running mod #{mod.class}..." if options[:verbose]
|
37
|
+
mod.call
|
38
|
+
end
|
39
|
+
hash = Hash[modifiers.map(&:first).zip(mods)]
|
40
|
+
# This is when we'd generate
|
41
|
+
|
42
|
+
find_generators(generators, options).each do |gen|
|
43
|
+
puts "Running generator #{gen}..." if options[:verbose]
|
44
|
+
gen.new(self, hash).generate
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# Find the corresponding generators. If the first argument
|
51
|
+
# isn't `:guess`, it returns the first argument. Otherwise,
|
52
|
+
# it tries to "intelligently guess" by checking the type from
|
53
|
+
# the options _or_ the compiler. If it is unable to find the
|
54
|
+
# type, it will raise a {NoTypeError}.
|
55
|
+
#
|
56
|
+
# @raise [NoTypeError] if it could not determine the type of
|
57
|
+
# the generator.
|
58
|
+
# @param generators [Symbol, Array<Generator>]
|
59
|
+
# @param options [Hash]
|
60
|
+
# @return [Array<Generator>]
|
61
|
+
def find_generators(generators, options)
|
62
|
+
return generators unless generators == :guess
|
63
|
+
|
64
|
+
generators = [Generator::Output]
|
65
|
+
|
66
|
+
# command line precedence...
|
67
|
+
type = options[:type] || options["type"] ||
|
68
|
+
compiler.options.fetch(:type)
|
69
|
+
|
70
|
+
generators << Generator.generators.fetch(type)
|
71
|
+
|
72
|
+
generators
|
73
|
+
|
74
|
+
rescue KeyError
|
75
|
+
raise NoTypeError, "Undefined type #{type}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -1,53 +1,53 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Antelope
|
4
|
-
module Ace
|
5
|
-
class Grammar
|
6
|
-
|
7
|
-
# Handles loading to and from files and strings.
|
8
|
-
module Loading
|
9
|
-
|
10
|
-
# Defines class methods on the grammar.
|
11
|
-
module ClassMethods
|
12
|
-
|
13
|
-
# Loads a grammar from a file. Assumes the output
|
14
|
-
# directory and name from the file name.
|
15
|
-
#
|
16
|
-
# @param file_name [String] the file name.
|
17
|
-
# @return [Grammar]
|
18
|
-
# @see #from_string
|
19
|
-
def from_file(file_name)
|
20
|
-
body = File.read(file_name)
|
21
|
-
output = File.dirname(file_name)
|
22
|
-
name = File.basename(file_name).gsub(/\.[A-Za-z]+/, "")
|
23
|
-
from_string(name, output, body)
|
24
|
-
end
|
25
|
-
|
26
|
-
# Loads a grammar from a string. First runs the scanner and
|
27
|
-
# compiler over the string, and then instantiates a new
|
28
|
-
# Grammar from the resultant.
|
29
|
-
#
|
30
|
-
# @param name [String] the name of the grammar.
|
31
|
-
# @param output [String] the output directory.
|
32
|
-
# @param string [String] the grammar body.
|
33
|
-
# @return [Grammar]
|
34
|
-
# @see Ace::Scanner
|
35
|
-
# @see Ace::Compiler
|
36
|
-
def from_string(name, output, string)
|
37
|
-
scanner = Ace::Scanner.scan(string, name)
|
38
|
-
compiler = Ace::Compiler.compile(scanner)
|
39
|
-
new(name, output, compiler)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# Extends the grammar with the class methods.
|
44
|
-
#
|
45
|
-
# @param receiver [Grammar]
|
46
|
-
# @see ClassMethods
|
47
|
-
def self.included(receiver)
|
48
|
-
receiver.extend ClassMethods
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Antelope
|
4
|
+
module Ace
|
5
|
+
class Grammar
|
6
|
+
|
7
|
+
# Handles loading to and from files and strings.
|
8
|
+
module Loading
|
9
|
+
|
10
|
+
# Defines class methods on the grammar.
|
11
|
+
module ClassMethods
|
12
|
+
|
13
|
+
# Loads a grammar from a file. Assumes the output
|
14
|
+
# directory and name from the file name.
|
15
|
+
#
|
16
|
+
# @param file_name [String] the file name.
|
17
|
+
# @return [Grammar]
|
18
|
+
# @see #from_string
|
19
|
+
def from_file(file_name)
|
20
|
+
body = File.read(file_name)
|
21
|
+
output = File.dirname(file_name)
|
22
|
+
name = File.basename(file_name).gsub(/\.[A-Za-z]+/, "")
|
23
|
+
from_string(name, output, body)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Loads a grammar from a string. First runs the scanner and
|
27
|
+
# compiler over the string, and then instantiates a new
|
28
|
+
# Grammar from the resultant.
|
29
|
+
#
|
30
|
+
# @param name [String] the name of the grammar.
|
31
|
+
# @param output [String] the output directory.
|
32
|
+
# @param string [String] the grammar body.
|
33
|
+
# @return [Grammar]
|
34
|
+
# @see Ace::Scanner
|
35
|
+
# @see Ace::Compiler
|
36
|
+
def from_string(name, output, string)
|
37
|
+
scanner = Ace::Scanner.scan(string, name)
|
38
|
+
compiler = Ace::Compiler.compile(scanner)
|
39
|
+
new(name, output, compiler)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Extends the grammar with the class methods.
|
44
|
+
#
|
45
|
+
# @param receiver [Grammar]
|
46
|
+
# @see ClassMethods
|
47
|
+
def self.included(receiver)
|
48
|
+
receiver.extend ClassMethods
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -1,65 +1,68 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require "set"
|
4
|
-
|
5
|
-
module Antelope
|
6
|
-
module Ace
|
7
|
-
class Grammar
|
8
|
-
|
9
|
-
# Manages precedence for tokens.
|
10
|
-
module Precedences
|
11
|
-
|
12
|
-
# Accesses the generated precedence list. Lazily generates
|
13
|
-
# the precedence rules on the go, and then caches it.
|
14
|
-
#
|
15
|
-
# @return [Array<Ace::Precedence>]
|
16
|
-
def precedence
|
17
|
-
@_precedence ||= generate_precedence
|
18
|
-
end
|
19
|
-
|
20
|
-
# Finds a precedence rule for a given token. If no direct
|
21
|
-
# rule is defined for that token, it will check for a rule
|
22
|
-
# defined for the special symbol, `:_`. By default, there
|
23
|
-
# is always a rule defined for `:_`.
|
24
|
-
#
|
25
|
-
# @param token [Ace::Token, Symbol]
|
26
|
-
# @return [Ace::Precedence]
|
27
|
-
def precedence_for(token)
|
28
|
-
token = token.name if token.is_a?(Token)
|
29
|
-
|
30
|
-
prec = precedence.
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
precedence
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "set"
|
4
|
+
|
5
|
+
module Antelope
|
6
|
+
module Ace
|
7
|
+
class Grammar
|
8
|
+
|
9
|
+
# Manages precedence for tokens.
|
10
|
+
module Precedences
|
11
|
+
|
12
|
+
# Accesses the generated precedence list. Lazily generates
|
13
|
+
# the precedence rules on the go, and then caches it.
|
14
|
+
#
|
15
|
+
# @return [Array<Ace::Precedence>]
|
16
|
+
def precedence
|
17
|
+
@_precedence ||= generate_precedence
|
18
|
+
end
|
19
|
+
|
20
|
+
# Finds a precedence rule for a given token. If no direct
|
21
|
+
# rule is defined for that token, it will check for a rule
|
22
|
+
# defined for the special symbol, `:_`. By default, there
|
23
|
+
# is always a rule defined for `:_`.
|
24
|
+
#
|
25
|
+
# @param token [Ace::Token, Symbol]
|
26
|
+
# @return [Ace::Precedence]
|
27
|
+
def precedence_for(token)
|
28
|
+
token = token.name if token.is_a?(Token)
|
29
|
+
|
30
|
+
prec = precedence.
|
31
|
+
detect { |pr| pr.tokens.include?(token) } ||
|
32
|
+
precedence.
|
33
|
+
detect { |pr| pr.tokens.include?(:_) }
|
34
|
+
|
35
|
+
prec
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# Generates the precedence rules. Loops through the compiler
|
41
|
+
# given precedence settings, and then adds two default
|
42
|
+
# precedence rules; one for `:$` (level 0, nonassoc), and one
|
43
|
+
# for `:_` (level 1, nonassoc).
|
44
|
+
#
|
45
|
+
# @return [Array<Ace::Precedence>]
|
46
|
+
def generate_precedence
|
47
|
+
size = @compiler.options[:prec].size + 1
|
48
|
+
index = 0
|
49
|
+
precedence = []
|
50
|
+
|
51
|
+
while index < size - 1
|
52
|
+
prec = @compiler.options[:prec][index]
|
53
|
+
precedence <<
|
54
|
+
Ace::Precedence.new(prec[0], prec[1..-1].to_set,
|
55
|
+
size - index)
|
56
|
+
index += 1
|
57
|
+
end
|
58
|
+
|
59
|
+
precedence <<
|
60
|
+
Ace::Precedence.new(:nonassoc, [:$end].to_set, 0) <<
|
61
|
+
Ace::Precedence.new(:nonassoc, [:_].to_set, 1)
|
62
|
+
precedence.sort_by(&:level).reverse
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|