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,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
- select { |pr| pr.tokens.include?(token) }.first
32
-
33
- unless prec
34
- prec = precedence.
35
- select { |pr| pr.tokens.include?(:_) }.first
36
- end
37
-
38
- prec
39
- end
40
-
41
- private
42
-
43
- # Generates the precedence rules. Loops through the compiler
44
- # given precedence settings, and then adds two default
45
- # precedence rules; one for `:$` (level 0, nonassoc), and one
46
- # for `:_` (level 1, nonassoc).
47
- #
48
- # @return [Array<Ace::Precedence>]
49
- def generate_precedence
50
- size = @compiler.options[:prec].size + 1
51
- precedence = @compiler.options[:prec].
52
- each_with_index.map do |prec, i|
53
- Ace::Precedence.new(prec[0], prec[1..-1].to_set, size - i)
54
- end
55
-
56
- precedence <<
57
- Ace::Precedence.new(:nonassoc, [:$end].to_set, 0) <<
58
- Ace::Precedence.new(:nonassoc, [:_].to_set, 1)
59
- precedence.sort_by { |_| _.level }.reverse
60
- end
61
-
62
- end
63
- end
64
- end
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