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.
- checksums.yaml +4 -4
- data/.gitignore +25 -25
- data/.rspec +3 -3
- data/.travis.yml +10 -10
- data/.yardopts +7 -7
- data/CONTRIBUTING.md +50 -38
- data/GENERATORS.md +180 -124
- data/Gemfile +7 -7
- data/LICENSE.txt +22 -22
- data/README.md +240 -104
- data/Rakefile +2 -2
- data/TODO.md +58 -58
- data/antelope.gemspec +29 -28
- data/bin/antelope +7 -7
- data/examples/deterministic.ace +35 -35
- data/examples/example.ace +52 -51
- data/examples/example.ace.err +192 -192
- data/examples/example.ace.inf +432 -432
- data/examples/example.ate +70 -70
- data/examples/example.ate.err +192 -192
- data/examples/example.ate.inf +432 -432
- data/examples/liquidscript.ace +233 -233
- data/examples/simple.ace +22 -22
- data/lib/antelope/ace/compiler.rb +334 -334
- data/lib/antelope/ace/errors.rb +30 -30
- 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 +178 -178
- data/lib/antelope/ace/scanner/third.rb +27 -27
- data/lib/antelope/ace/scanner.rb +144 -144
- data/lib/antelope/ace.rb +47 -47
- data/lib/antelope/cli.rb +60 -60
- data/lib/antelope/errors.rb +25 -25
- data/lib/antelope/generation/constructor/first.rb +86 -86
- data/lib/antelope/generation/constructor/follow.rb +105 -105
- data/lib/antelope/generation/constructor/nullable.rb +64 -64
- data/lib/antelope/generation/constructor.rb +127 -127
- 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 +129 -129
- data/lib/antelope/generation/recognizer.rb +177 -177
- data/lib/antelope/generation/tableizer.rb +176 -176
- data/lib/antelope/generation.rb +15 -15
- data/lib/antelope/generator/base/coerce.rb +115 -0
- data/lib/antelope/generator/base/extra.rb +50 -0
- data/lib/antelope/generator/base.rb +134 -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 -34
- data/lib/antelope/generator/group.rb +60 -57
- data/lib/antelope/generator/html.rb +51 -51
- data/lib/antelope/generator/info.rb +47 -47
- data/lib/antelope/generator/null.rb +18 -18
- data/lib/antelope/generator/output.rb +17 -17
- data/lib/antelope/generator/ruby.rb +112 -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.erb +40 -0
- data/lib/antelope/generator/templates/html/antelope.css +53 -1
- data/lib/antelope/generator/templates/html/antelope.html +82 -1
- data/lib/antelope/generator/templates/html/antelope.js +9 -1
- data/lib/antelope/generator/templates/html/css.ant +53 -53
- data/lib/antelope/generator/templates/html/html.ant +82 -82
- data/lib/antelope/generator/templates/html/js.ant +9 -9
- data/lib/antelope/generator/templates/info.erb +61 -0
- data/lib/antelope/generator/templates/{ruby.ant → ruby.erb} +171 -178
- data/lib/antelope/generator.rb +62 -66
- data/lib/antelope/grammar/generation.rb +76 -76
- data/lib/antelope/grammar/loading.rb +84 -84
- data/lib/antelope/grammar/precedence.rb +59 -59
- data/lib/antelope/grammar/precedences.rb +64 -64
- data/lib/antelope/grammar/production.rb +56 -56
- data/lib/antelope/grammar/productions.rb +154 -154
- data/lib/antelope/grammar/symbols.rb +64 -64
- data/lib/antelope/grammar/token/epsilon.rb +23 -23
- data/lib/antelope/grammar/token/error.rb +24 -24
- data/lib/antelope/grammar/token/nonterminal.rb +15 -15
- data/lib/antelope/grammar/token/terminal.rb +15 -15
- data/lib/antelope/grammar/token.rb +231 -231
- data/lib/antelope/grammar.rb +68 -68
- data/lib/antelope/version.rb +6 -6
- data/lib/antelope.rb +18 -19
- data/optimizations.txt +42 -42
- data/spec/antelope/ace/compiler_spec.rb +60 -60
- data/spec/antelope/ace/scanner_spec.rb +27 -27
- data/spec/antelope/generation/constructor_spec.rb +131 -131
- 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 +14 -14
- data/subl/Ace (Ruby).JSON-tmLanguage +94 -94
- data/subl/Ace (Ruby).tmLanguage +153 -153
- metadata +22 -11
- data/lib/antelope/generator/templates/error.ant +0 -34
- data/lib/antelope/generator/templates/info.ant +0 -53
- data/lib/antelope/template/compiler.rb +0 -78
- data/lib/antelope/template/errors.rb +0 -9
- data/lib/antelope/template/scanner.rb +0 -109
- data/lib/antelope/template.rb +0 -64
- data/spec/antelope/template_spec.rb +0 -50
@@ -1,84 +1,84 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Antelope
|
4
|
-
class Grammar
|
5
|
-
# Handles loading to and from files and strings.
|
6
|
-
module Loading
|
7
|
-
# Defines class methods on the grammar.
|
8
|
-
module ClassMethods
|
9
|
-
# Loads a grammar from a file. Assumes the output
|
10
|
-
# directory and name from the file name.
|
11
|
-
#
|
12
|
-
# @param file_name [String] the file name.
|
13
|
-
# @return [Grammar]
|
14
|
-
# @see #from_string
|
15
|
-
def from_file(file_name)
|
16
|
-
ext = File.extname(file_name)
|
17
|
-
case ext
|
18
|
-
when ".rb", ".ate"
|
19
|
-
from_dsl_file(file_name)
|
20
|
-
when ".ace"
|
21
|
-
from_ace_file(file_name)
|
22
|
-
else
|
23
|
-
raise ArgumentError, "Unexpected file extension #{ext},"\
|
24
|
-
" expected one of .rb, .ate, or .ace"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def from_dsl_file(file_name)
|
29
|
-
body = File.read(file_name)
|
30
|
-
output = File.dirname(file_name)
|
31
|
-
from_dsl_string(file_name, output, body)
|
32
|
-
end
|
33
|
-
|
34
|
-
def from_ace_file(file_name)
|
35
|
-
body = File.read(file_name)
|
36
|
-
output = File.dirname(file_name)
|
37
|
-
name = File.basename(file_name)
|
38
|
-
from_ace_string(name, output, body)
|
39
|
-
end
|
40
|
-
|
41
|
-
# Loads a grammar from a string. First runs the scanner and
|
42
|
-
# compiler over the string, and then instantiates a new
|
43
|
-
# Grammar from the resultant.
|
44
|
-
#
|
45
|
-
# @param file [String] the path of the grammar. This is
|
46
|
-
# used for eval.
|
47
|
-
# @param output [String] the output directory.
|
48
|
-
# @param string [String] the grammar body.
|
49
|
-
# @return [Grammar]
|
50
|
-
# @see DSL::Compiler
|
51
|
-
def from_dsl_string(file, output, string)
|
52
|
-
eval(string, TOPLEVEL_BINDING, file, 0)
|
53
|
-
grammar = Antelope.grammar
|
54
|
-
compiler = DSL::Compiler.compile(grammar[1], &grammar[2])
|
55
|
-
new(File.basename(file), output, compiler)
|
56
|
-
end
|
57
|
-
|
58
|
-
# Loads a grammar from a string. First runs the scanner and
|
59
|
-
# compiler over the string, and then instantiates a new
|
60
|
-
# Grammar from the resultant.
|
61
|
-
#
|
62
|
-
# @param name [String] the name of the grammar.
|
63
|
-
# @param output [String] the output directory.
|
64
|
-
# @param string [String] the grammar body.
|
65
|
-
# @return [Grammar]
|
66
|
-
# @see Ace::Scanner
|
67
|
-
# @see Ace::Compiler
|
68
|
-
def from_ace_string(name, output, string)
|
69
|
-
scanner = Ace::Scanner.scan(string, name)
|
70
|
-
compiler = Ace::Compiler.compile(scanner)
|
71
|
-
new(name, output, compiler)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# Extends the grammar with the class methods.
|
76
|
-
#
|
77
|
-
# @param receiver [Grammar]
|
78
|
-
# @see ClassMethods
|
79
|
-
def self.included(receiver)
|
80
|
-
receiver.extend ClassMethods
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Antelope
|
4
|
+
class Grammar
|
5
|
+
# Handles loading to and from files and strings.
|
6
|
+
module Loading
|
7
|
+
# Defines class methods on the grammar.
|
8
|
+
module ClassMethods
|
9
|
+
# Loads a grammar from a file. Assumes the output
|
10
|
+
# directory and name from the file name.
|
11
|
+
#
|
12
|
+
# @param file_name [String] the file name.
|
13
|
+
# @return [Grammar]
|
14
|
+
# @see #from_string
|
15
|
+
def from_file(file_name)
|
16
|
+
ext = File.extname(file_name)
|
17
|
+
case ext
|
18
|
+
when ".rb", ".ate"
|
19
|
+
from_dsl_file(file_name)
|
20
|
+
when ".ace"
|
21
|
+
from_ace_file(file_name)
|
22
|
+
else
|
23
|
+
raise ArgumentError, "Unexpected file extension #{ext},"\
|
24
|
+
" expected one of .rb, .ate, or .ace"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def from_dsl_file(file_name)
|
29
|
+
body = File.read(file_name)
|
30
|
+
output = File.dirname(file_name)
|
31
|
+
from_dsl_string(file_name, output, body)
|
32
|
+
end
|
33
|
+
|
34
|
+
def from_ace_file(file_name)
|
35
|
+
body = File.read(file_name)
|
36
|
+
output = File.dirname(file_name)
|
37
|
+
name = File.basename(file_name)
|
38
|
+
from_ace_string(name, output, body)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Loads a grammar from a string. First runs the scanner and
|
42
|
+
# compiler over the string, and then instantiates a new
|
43
|
+
# Grammar from the resultant.
|
44
|
+
#
|
45
|
+
# @param file [String] the path of the grammar. This is
|
46
|
+
# used for eval.
|
47
|
+
# @param output [String] the output directory.
|
48
|
+
# @param string [String] the grammar body.
|
49
|
+
# @return [Grammar]
|
50
|
+
# @see DSL::Compiler
|
51
|
+
def from_dsl_string(file, output, string)
|
52
|
+
eval(string, TOPLEVEL_BINDING, file, 0)
|
53
|
+
grammar = Antelope.grammar
|
54
|
+
compiler = DSL::Compiler.compile(grammar[1], &grammar[2])
|
55
|
+
new(File.basename(file), output, compiler)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Loads a grammar from a string. First runs the scanner and
|
59
|
+
# compiler over the string, and then instantiates a new
|
60
|
+
# Grammar from the resultant.
|
61
|
+
#
|
62
|
+
# @param name [String] the name of the grammar.
|
63
|
+
# @param output [String] the output directory.
|
64
|
+
# @param string [String] the grammar body.
|
65
|
+
# @return [Grammar]
|
66
|
+
# @see Ace::Scanner
|
67
|
+
# @see Ace::Compiler
|
68
|
+
def from_ace_string(name, output, string)
|
69
|
+
scanner = Ace::Scanner.scan(string, name)
|
70
|
+
compiler = Ace::Compiler.compile(scanner)
|
71
|
+
new(name, output, compiler)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Extends the grammar with the class methods.
|
76
|
+
#
|
77
|
+
# @param receiver [Grammar]
|
78
|
+
# @see ClassMethods
|
79
|
+
def self.included(receiver)
|
80
|
+
receiver.extend ClassMethods
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -1,59 +1,59 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Antelope
|
4
|
-
class Grammar
|
5
|
-
# Defines a precedence. A precedence has a type, tokens, and a
|
6
|
-
# level.
|
7
|
-
Precedence = Struct.new(:type, :tokens, :level) do
|
8
|
-
# @!attribute [rw] type
|
9
|
-
# The type of precedence level. This should be one of
|
10
|
-
# `:left`, `:right`, or `:nonassoc`.
|
11
|
-
#
|
12
|
-
# @return [Symbol] the type.
|
13
|
-
# @!attribute [rw] tokens
|
14
|
-
# An set of tokens that are on this specific precedence
|
15
|
-
# level. The tokens are identified as symbols. The special
|
16
|
-
# symbol, `:_`, represents any token.
|
17
|
-
#
|
18
|
-
# @return [Set<Symbol>] the tokens on this level.
|
19
|
-
# @!attribute [rw] level
|
20
|
-
# The level we're on. The higher the level, the higher the
|
21
|
-
# precedence.
|
22
|
-
|
23
|
-
include Comparable
|
24
|
-
|
25
|
-
# Compares the other object to this object. If the other object
|
26
|
-
# isn't a {Precedence}, it returns nil. If the other
|
27
|
-
# precedence isn't on the same level as this one, then the
|
28
|
-
# levels are compared and the result of that is returned. If
|
29
|
-
# it is, however, the type is checked; if this precedence is
|
30
|
-
# left associative, then it returns 1 (it is greater than the
|
31
|
-
# other); if this precedence is right associative, then it
|
32
|
-
# returns -1 (it is less than the other); if this precedence is
|
33
|
-
# nonassociative, it returns 0 (it is equal to the other).
|
34
|
-
#
|
35
|
-
# @param other [Object] the object to compare to this one.
|
36
|
-
# @return [Numeric?]
|
37
|
-
def <=>(other)
|
38
|
-
return nil unless other.is_a? Precedence
|
39
|
-
if level != other.level
|
40
|
-
level <=> other.level
|
41
|
-
elsif type == :left
|
42
|
-
1
|
43
|
-
elsif type == :right
|
44
|
-
-1
|
45
|
-
else
|
46
|
-
0
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# Converts the precedence into a representative string, denoting
|
51
|
-
# the type and the level.
|
52
|
-
#
|
53
|
-
# @return [String]
|
54
|
-
def to_s
|
55
|
-
"#{type.to_s[0]}#{level}"
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Antelope
|
4
|
+
class Grammar
|
5
|
+
# Defines a precedence. A precedence has a type, tokens, and a
|
6
|
+
# level.
|
7
|
+
Precedence = Struct.new(:type, :tokens, :level) do
|
8
|
+
# @!attribute [rw] type
|
9
|
+
# The type of precedence level. This should be one of
|
10
|
+
# `:left`, `:right`, or `:nonassoc`.
|
11
|
+
#
|
12
|
+
# @return [Symbol] the type.
|
13
|
+
# @!attribute [rw] tokens
|
14
|
+
# An set of tokens that are on this specific precedence
|
15
|
+
# level. The tokens are identified as symbols. The special
|
16
|
+
# symbol, `:_`, represents any token.
|
17
|
+
#
|
18
|
+
# @return [Set<Symbol>] the tokens on this level.
|
19
|
+
# @!attribute [rw] level
|
20
|
+
# The level we're on. The higher the level, the higher the
|
21
|
+
# precedence.
|
22
|
+
|
23
|
+
include Comparable
|
24
|
+
|
25
|
+
# Compares the other object to this object. If the other object
|
26
|
+
# isn't a {Precedence}, it returns nil. If the other
|
27
|
+
# precedence isn't on the same level as this one, then the
|
28
|
+
# levels are compared and the result of that is returned. If
|
29
|
+
# it is, however, the type is checked; if this precedence is
|
30
|
+
# left associative, then it returns 1 (it is greater than the
|
31
|
+
# other); if this precedence is right associative, then it
|
32
|
+
# returns -1 (it is less than the other); if this precedence is
|
33
|
+
# nonassociative, it returns 0 (it is equal to the other).
|
34
|
+
#
|
35
|
+
# @param other [Object] the object to compare to this one.
|
36
|
+
# @return [Numeric?]
|
37
|
+
def <=>(other)
|
38
|
+
return nil unless other.is_a? Precedence
|
39
|
+
if level != other.level
|
40
|
+
level <=> other.level
|
41
|
+
elsif type == :left
|
42
|
+
1
|
43
|
+
elsif type == :right
|
44
|
+
-1
|
45
|
+
else
|
46
|
+
0
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Converts the precedence into a representative string, denoting
|
51
|
+
# the type and the level.
|
52
|
+
#
|
53
|
+
# @return [String]
|
54
|
+
def to_s
|
55
|
+
"#{type.to_s[0]}#{level}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -1,64 +1,64 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require "set"
|
4
|
-
|
5
|
-
module Antelope
|
6
|
-
class Grammar
|
7
|
-
# Manages precedence for tokens.
|
8
|
-
module Precedences
|
9
|
-
# Accesses the generated precedence list. Lazily generates
|
10
|
-
# the precedence rules on the go, and then caches it.
|
11
|
-
#
|
12
|
-
# @return [Array<Ace::Precedence>]
|
13
|
-
def precedence
|
14
|
-
@_precedence ||= generate_precedence
|
15
|
-
end
|
16
|
-
|
17
|
-
# Finds a precedence rule for a given token. If no direct
|
18
|
-
# rule is defined for that token, it will check for a rule
|
19
|
-
# defined for the special symbol, `:_`. By default, there
|
20
|
-
# is always a rule defined for `:_`.
|
21
|
-
#
|
22
|
-
# @param token [Ace::Token, Symbol]
|
23
|
-
# @return [Ace::Precedence]
|
24
|
-
def precedence_for(token)
|
25
|
-
token = token.name if token.is_a?(Token)
|
26
|
-
|
27
|
-
prec = precedence.
|
28
|
-
detect { |pr| pr.tokens.include?(token) } ||
|
29
|
-
precedence.
|
30
|
-
detect { |pr| pr.tokens.include?(:_) }
|
31
|
-
|
32
|
-
prec
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
# Generates the precedence rules. Loops through the compiler
|
38
|
-
# given precedence settings, and then adds two default
|
39
|
-
# precedence rules; one for `:$` (level 0, nonassoc), and one
|
40
|
-
# for `:_` (level 1, nonassoc).
|
41
|
-
#
|
42
|
-
# @return [Array<Ace::Precedence>]
|
43
|
-
def generate_precedence
|
44
|
-
size = @compiler.options[:prec].size + 1
|
45
|
-
index = 0
|
46
|
-
precedence = []
|
47
|
-
|
48
|
-
while index < size - 1
|
49
|
-
prec = @compiler.options[:prec][index]
|
50
|
-
precedence <<
|
51
|
-
Precedence.new(prec[0], prec[1..-1].to_set,
|
52
|
-
size - index)
|
53
|
-
index += 1
|
54
|
-
end
|
55
|
-
|
56
|
-
precedence <<
|
57
|
-
Precedence.new(:nonassoc, [:$end].to_set, 0) <<
|
58
|
-
Precedence.new(:nonassoc, [:_].to_set, 1)
|
59
|
-
precedence.sort_by(&:level).reverse
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "set"
|
4
|
+
|
5
|
+
module Antelope
|
6
|
+
class Grammar
|
7
|
+
# Manages precedence for tokens.
|
8
|
+
module Precedences
|
9
|
+
# Accesses the generated precedence list. Lazily generates
|
10
|
+
# the precedence rules on the go, and then caches it.
|
11
|
+
#
|
12
|
+
# @return [Array<Ace::Precedence>]
|
13
|
+
def precedence
|
14
|
+
@_precedence ||= generate_precedence
|
15
|
+
end
|
16
|
+
|
17
|
+
# Finds a precedence rule for a given token. If no direct
|
18
|
+
# rule is defined for that token, it will check for a rule
|
19
|
+
# defined for the special symbol, `:_`. By default, there
|
20
|
+
# is always a rule defined for `:_`.
|
21
|
+
#
|
22
|
+
# @param token [Ace::Token, Symbol]
|
23
|
+
# @return [Ace::Precedence]
|
24
|
+
def precedence_for(token)
|
25
|
+
token = token.name if token.is_a?(Token)
|
26
|
+
|
27
|
+
prec = precedence.
|
28
|
+
detect { |pr| pr.tokens.include?(token) } ||
|
29
|
+
precedence.
|
30
|
+
detect { |pr| pr.tokens.include?(:_) }
|
31
|
+
|
32
|
+
prec
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Generates the precedence rules. Loops through the compiler
|
38
|
+
# given precedence settings, and then adds two default
|
39
|
+
# precedence rules; one for `:$` (level 0, nonassoc), and one
|
40
|
+
# for `:_` (level 1, nonassoc).
|
41
|
+
#
|
42
|
+
# @return [Array<Ace::Precedence>]
|
43
|
+
def generate_precedence
|
44
|
+
size = @compiler.options[:prec].size + 1
|
45
|
+
index = 0
|
46
|
+
precedence = []
|
47
|
+
|
48
|
+
while index < size - 1
|
49
|
+
prec = @compiler.options[:prec][index]
|
50
|
+
precedence <<
|
51
|
+
Precedence.new(prec[0], prec[1..-1].to_set,
|
52
|
+
size - index)
|
53
|
+
index += 1
|
54
|
+
end
|
55
|
+
|
56
|
+
precedence <<
|
57
|
+
Precedence.new(:nonassoc, [:$end].to_set, 0) <<
|
58
|
+
Precedence.new(:nonassoc, [:_].to_set, 1)
|
59
|
+
precedence.sort_by(&:level).reverse
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -1,56 +1,56 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Antelope
|
4
|
-
class Grammar
|
5
|
-
# Defines a production.
|
6
|
-
Production = Struct.new(:label, :items, :block, :prec, :id) do
|
7
|
-
# @!attribute [rw] label
|
8
|
-
# The label (or left-hand side) of the production. This
|
9
|
-
# should be a nonterminal.
|
10
|
-
#
|
11
|
-
# @return [Symbol]
|
12
|
-
# @!attribute [rw] items
|
13
|
-
# The body (or right-hand side) of the production. This can
|
14
|
-
# be array of terminals and nonterminals.
|
15
|
-
#
|
16
|
-
# @return [Array<Token>]
|
17
|
-
# @!attribute [rw] block
|
18
|
-
# The block of code to be executed when the production's right
|
19
|
-
# hand side is reduced.
|
20
|
-
#
|
21
|
-
# @return [String]
|
22
|
-
# @!attribute [rw] prec
|
23
|
-
# The precedence declaration for the production.
|
24
|
-
#
|
25
|
-
# @return [Ace::Precedence]
|
26
|
-
# @!attribute [rw] id
|
27
|
-
# The ID of the production. The starting production always
|
28
|
-
# has an ID of 0.
|
29
|
-
#
|
30
|
-
# @return [Numeric]
|
31
|
-
|
32
|
-
# Creates a new production from a hash. The hash's keys
|
33
|
-
# correspond to the attributes on this class.
|
34
|
-
#
|
35
|
-
# @param hash [Hash<(Symbol, Object)>]
|
36
|
-
def self.from_hash(hash)
|
37
|
-
new(hash[:label] || hash['label'],
|
38
|
-
hash[:items] || hash['items'],
|
39
|
-
hash[:block] || hash['block'],
|
40
|
-
hash[:prec] || hash['prec'],
|
41
|
-
hash[:id] || hash['id'])
|
42
|
-
end
|
43
|
-
|
44
|
-
# Create a new version of the production with duplicated values.
|
45
|
-
#
|
46
|
-
# @return [Production]
|
47
|
-
def clone
|
48
|
-
Production.new(label.dup,
|
49
|
-
items.map(&:dup),
|
50
|
-
block.dup,
|
51
|
-
prec.dup,
|
52
|
-
id)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Antelope
|
4
|
+
class Grammar
|
5
|
+
# Defines a production.
|
6
|
+
Production = Struct.new(:label, :items, :block, :prec, :id) do
|
7
|
+
# @!attribute [rw] label
|
8
|
+
# The label (or left-hand side) of the production. This
|
9
|
+
# should be a nonterminal.
|
10
|
+
#
|
11
|
+
# @return [Symbol]
|
12
|
+
# @!attribute [rw] items
|
13
|
+
# The body (or right-hand side) of the production. This can
|
14
|
+
# be array of terminals and nonterminals.
|
15
|
+
#
|
16
|
+
# @return [Array<Token>]
|
17
|
+
# @!attribute [rw] block
|
18
|
+
# The block of code to be executed when the production's right
|
19
|
+
# hand side is reduced.
|
20
|
+
#
|
21
|
+
# @return [String]
|
22
|
+
# @!attribute [rw] prec
|
23
|
+
# The precedence declaration for the production.
|
24
|
+
#
|
25
|
+
# @return [Ace::Precedence]
|
26
|
+
# @!attribute [rw] id
|
27
|
+
# The ID of the production. The starting production always
|
28
|
+
# has an ID of 0.
|
29
|
+
#
|
30
|
+
# @return [Numeric]
|
31
|
+
|
32
|
+
# Creates a new production from a hash. The hash's keys
|
33
|
+
# correspond to the attributes on this class.
|
34
|
+
#
|
35
|
+
# @param hash [Hash<(Symbol, Object)>]
|
36
|
+
def self.from_hash(hash)
|
37
|
+
new(hash[:label] || hash['label'],
|
38
|
+
hash[:items] || hash['items'],
|
39
|
+
hash[:block] || hash['block'],
|
40
|
+
hash[:prec] || hash['prec'],
|
41
|
+
hash[:id] || hash['id'])
|
42
|
+
end
|
43
|
+
|
44
|
+
# Create a new version of the production with duplicated values.
|
45
|
+
#
|
46
|
+
# @return [Production]
|
47
|
+
def clone
|
48
|
+
Production.new(label.dup,
|
49
|
+
items.map(&:dup),
|
50
|
+
block.dup,
|
51
|
+
prec.dup,
|
52
|
+
id)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|