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.
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,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