antelope 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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