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,105 +1,105 @@
1
- module Antelope
2
- module Generator
3
- class CHeader < Base
4
-
5
- register_as "c-header", "c_header"
6
-
7
- has_directive "union", Array[String, String]
8
- has_directive "api.prefix", String
9
- has_directive "api.push-pull", String
10
- has_directive "api.value.type", String
11
- has_directive "api.token.prefix", String
12
- has_directive "parse-param", Array
13
- has_directive "lex-param", Array
14
- has_directive "param", Array
15
-
16
- def push?
17
- directives.api.push_pull == "push"
18
- end
19
-
20
- def define_stype?
21
- !!directives.union[0] && !directives.api.value.type
22
- end
23
-
24
- def lex_params
25
- params = [directives.lex_param, directives.param].compact.
26
- flatten
27
-
28
- if params.any?
29
- ", " << params.join(", ")
30
- else
31
- ""
32
- end
33
- end
34
-
35
- def parse_params
36
- [directives.parse_param, directives.param].compact.flatten.
37
- join(", ")
38
- end
39
-
40
- def params
41
- if directives.param
42
- directives.param.join(", ")
43
- else
44
- ""
45
- end
46
- end
47
-
48
- def stype
49
- prefix.upcase << if directives.api.value.type
50
- directives.api.value.type
51
- elsif directives.union.size > 1
52
- directives.union[0]
53
- else
54
- "STYPE"
55
- end
56
- end
57
-
58
- def union_body
59
- directives.union.last
60
- end
61
-
62
- def terminal_type
63
- "int" # for now
64
- end
65
-
66
- def token_prefix
67
- if directives.api.token.prefix
68
- directives.api.token.prefix
69
- elsif directives.api.prefix
70
- prefix.upcase
71
- else
72
- ""
73
- end
74
- end
75
-
76
- def prefix
77
- if directives.api.prefix
78
- directives.api.prefix
79
- else
80
- "yy"
81
- end
82
- end
83
-
84
- def upper_prefix
85
- prefix.upcase
86
- end
87
-
88
- def symbols
89
- @_symbols ||= begin
90
- sym = grammar.terminals.map(&:name) + grammar.nonterminals
91
- nums = sym.each_with_index.map { |v, i| [v, i + 257] }
92
- Hash[nums]
93
- end
94
- end
95
-
96
- def guard_name
97
- "#{prefix.upcase}#{file.gsub(/[\W]/, "_").upcase}"
98
- end
99
-
100
- def generate
101
- template "c_header", "#{file}.h"
102
- end
103
- end
104
- end
105
- end
1
+ module Antelope
2
+ module Generator
3
+ class CHeader < Base
4
+
5
+ register_as "c-header", "c_header"
6
+
7
+ has_directive "union", Array[String, String]
8
+ has_directive "api.prefix", String
9
+ has_directive "api.push-pull", String
10
+ has_directive "api.value.type", String
11
+ has_directive "api.token.prefix", String
12
+ has_directive "parse-param", Array
13
+ has_directive "lex-param", Array
14
+ has_directive "param", Array
15
+
16
+ def push?
17
+ directives.api.push_pull == "push"
18
+ end
19
+
20
+ def define_stype?
21
+ !!directives.union[0] && !directives.api.value.type
22
+ end
23
+
24
+ def lex_params
25
+ params = [directives.lex_param, directives.param].compact.
26
+ flatten
27
+
28
+ if params.any?
29
+ ", " << params.join(", ")
30
+ else
31
+ ""
32
+ end
33
+ end
34
+
35
+ def parse_params
36
+ [directives.parse_param, directives.param].compact.flatten.
37
+ join(", ")
38
+ end
39
+
40
+ def params
41
+ if directives.param
42
+ directives.param.join(", ")
43
+ else
44
+ ""
45
+ end
46
+ end
47
+
48
+ def stype
49
+ prefix.upcase << if directives.api.value.type
50
+ directives.api.value.type
51
+ elsif directives.union.size > 1
52
+ directives.union[0]
53
+ else
54
+ "STYPE"
55
+ end
56
+ end
57
+
58
+ def union_body
59
+ directives.union.last
60
+ end
61
+
62
+ def terminal_type
63
+ "int" # for now
64
+ end
65
+
66
+ def token_prefix
67
+ if directives.api.token.prefix
68
+ directives.api.token.prefix
69
+ elsif directives.api.prefix
70
+ prefix.upcase
71
+ else
72
+ ""
73
+ end
74
+ end
75
+
76
+ def prefix
77
+ if directives.api.prefix
78
+ directives.api.prefix
79
+ else
80
+ "yy"
81
+ end
82
+ end
83
+
84
+ def upper_prefix
85
+ prefix.upcase
86
+ end
87
+
88
+ def symbols
89
+ @_symbols ||= begin
90
+ sym = grammar.terminals.map(&:name) + grammar.nonterminals
91
+ nums = sym.each_with_index.map { |v, i| [v, i + 257] }
92
+ Hash[nums]
93
+ end
94
+ end
95
+
96
+ def guard_name
97
+ "#{prefix.upcase}#{file.gsub(/[\W]/, "_").upcase}"
98
+ end
99
+
100
+ def generate
101
+ template "c_header", "#{file}.h"
102
+ end
103
+ end
104
+ end
105
+ end
@@ -1,39 +1,39 @@
1
- module Antelope
2
- module Generator
3
- class CSource < CHeader
4
-
5
- def action_for(state)
6
- out = ""
7
-
8
- grammar.terminals.each do |terminal|
9
- action = state[terminal.name]
10
-
11
- if action.size == 2 && action[0] == :state
12
- out << "#{action[1] + 1}, "
13
- elsif action.size == 2 &&
14
- [:reduce, :accept].include?(action[0])
15
- if $DEBUG
16
- out << "#{prefix.upcase}STATES + #{action[1] + 1}, "
17
- else
18
- out << "#{table.size + action[1] + 1}, "
19
- end
20
- else
21
- out << "0, "
22
- end
23
-
24
- end
25
-
26
- out.chomp(", ")
27
- end
28
-
29
- def cify_block(block)
30
- block.gsub(/\$([0-9]+)/, "#{prefix}vals[\\1]")
31
- .gsub(/\$\$/, "#{prefix}out")
32
- end
33
-
34
- def generate
35
- template "c_source", "#{file}.c"
36
- end
37
- end
38
- end
39
- end
1
+ module Antelope
2
+ module Generator
3
+ class CSource < CHeader
4
+
5
+ def action_for(state)
6
+ out = ""
7
+
8
+ grammar.terminals.each do |terminal|
9
+ action = state[terminal.name]
10
+
11
+ if action.size == 2 && action[0] == :state
12
+ out << "#{action[1] + 1}, "
13
+ elsif action.size == 2 &&
14
+ [:reduce, :accept].include?(action[0])
15
+ if $DEBUG
16
+ out << "#{prefix.upcase}STATES + #{action[1] + 1}, "
17
+ else
18
+ out << "#{table.size + action[1] + 1}, "
19
+ end
20
+ else
21
+ out << "0, "
22
+ end
23
+
24
+ end
25
+
26
+ out.chomp(", ")
27
+ end
28
+
29
+ def cify_block(block)
30
+ block.gsub(/\$([0-9]+)/, "#{prefix}vals[\\1]")
31
+ .gsub(/\$\$/, "#{prefix}out")
32
+ end
33
+
34
+ def generate
35
+ template "c_source", "#{file}.c"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+
3
+ module Antelope
4
+ module Generator
5
+
6
+ # Generates an output file, mainly for debugging. Included always
7
+ # as a generator for a grammar.
8
+ class Error < Base
9
+
10
+ register_as "error"
11
+
12
+ has_directive "output.verbose", Boolean
13
+
14
+ # Defines singleton method for every mod that the grammar passed
15
+ # to the generator.
16
+ #
17
+ # @see Generator#initialize
18
+ def initialize(*)
19
+ super
20
+ mods.each do |k, v|
21
+ define_singleton_method (k) { v }
22
+ end
23
+ end
24
+
25
+ # Actually performs the generation. Uses the template in
26
+ # output.erb, and generates the file `<file>.output`.
27
+ #
28
+ # @return [void]
29
+ def generate
30
+ template "error", "#{file}.err"
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,57 +1,57 @@
1
- module Antelope
2
- module Generator
3
-
4
- # For use to use multiple generators as a bundle. Works exactly
5
- # like a normal generator, i.e. responds to both {.register_as}
6
- # and {#generate}, but also responds to {.register_generator},
7
- # like {Generator}. Any generators registered to the group are
8
- # used to generate the files.
9
- #
10
- # @abtract Subclass and use {.register_generator} to create a
11
- # group generator.
12
- class Group < Base
13
-
14
- extend Generator
15
-
16
- # Initialize the group generator. Calls {Base#initialize}, and
17
- # then instantizes all of the generators in the group.
18
- def initialize(*_)
19
- super
20
-
21
- generators.map! do |gen|
22
- gen.new(*_)
23
- end
24
- end
25
-
26
- # Generates files using the generators contained within this
27
- # group. If it encounters an error in one of the generators, it
28
- # will continue to try to generate the rest of the generators.
29
- # It will then raise the last error given at the end.
30
- #
31
- # @return [void]
32
- def generate
33
- error = nil
34
- generators.map do |gen|
35
- begin
36
- gen.generate
37
- rescue => e
38
- $stderr.puts "Error running #{gen.class}: #{e.message}"
39
- error = e
40
- end
41
- end
42
-
43
- raise error if error
44
- end
45
-
46
- private
47
-
48
- # Retrieve a list of all of the generators that are contained
49
- # within this group.
50
- #
51
- # @return [Array<Generator::Base>]
52
- def generators
53
- @_generators ||= self.class.generators.values
54
- end
55
- end
56
- end
57
- end
1
+ module Antelope
2
+ module Generator
3
+
4
+ # For use to use multiple generators as a bundle. Works exactly
5
+ # like a normal generator, i.e. responds to both {.register_as}
6
+ # and {#generate}, but also responds to {.register_generator},
7
+ # like {Generator}. Any generators registered to the group are
8
+ # used to generate the files.
9
+ #
10
+ # @abtract Subclass and use {.register_generator} to create a
11
+ # group generator.
12
+ class Group < Base
13
+
14
+ extend Generator
15
+
16
+ # Initialize the group generator. Calls {Base#initialize}, and
17
+ # then instantizes all of the generators in the group.
18
+ def initialize(*_)
19
+ super
20
+
21
+ generators.map! do |gen|
22
+ gen.new(*_)
23
+ end
24
+ end
25
+
26
+ # Generates files using the generators contained within this
27
+ # group. If it encounters an error in one of the generators, it
28
+ # will continue to try to generate the rest of the generators.
29
+ # It will then raise the last error given at the end.
30
+ #
31
+ # @return [void]
32
+ def generate
33
+ error = nil
34
+ generators.map do |gen|
35
+ begin
36
+ gen.generate
37
+ rescue => e
38
+ $stderr.puts "Error running #{gen.class}: #{e.message}"
39
+ error = e
40
+ end
41
+ end
42
+
43
+ raise error if error
44
+ end
45
+
46
+ private
47
+
48
+ # Retrieve a list of all of the generators that are contained
49
+ # within this group.
50
+ #
51
+ # @return [Array<Generator::Base>]
52
+ def generators
53
+ @_generators ||= self.class.generators.values
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+
3
+ module Antelope
4
+ module Generator
5
+
6
+ # Generates an output file, mainly for debugging. Included always
7
+ # as a generator for a grammar.
8
+ class HTML < Base
9
+
10
+ register_as "html"
11
+
12
+ has_directive "html.show-lookahead", Boolean
13
+
14
+ # Defines singleton method for every mod that the grammar passed
15
+ # to the generator.
16
+ #
17
+ # @see Generator#initialize
18
+ def initialize(*)
19
+ super
20
+ mods.each do |k, v|
21
+ define_singleton_method (k) { v }
22
+ end
23
+ end
24
+
25
+ def unused_symbols
26
+ @_unused_symbols ||= begin
27
+ used = grammar.all_productions.map(&:items).flatten.uniq
28
+ all = grammar.symbols.map do |s|
29
+ if Symbol === s
30
+ grammar.find_token(s)
31
+ else
32
+ s
33
+ end
34
+ end
35
+
36
+ all - used - [grammar.find_token(:"$start")]
37
+ end
38
+ end
39
+
40
+ # Actually performs the generation. Uses the template in
41
+ # output.erb, and generates the file `<file>.output`.
42
+ #
43
+ # @return [void]
44
+ def generate
45
+ template "html/html", "#{file}.html"
46
+ template "html/css", "#{file}.css"
47
+ template "html/js", "#{file}.js"
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ module Antelope
4
+ module Generator
5
+
6
+ # Generates an output file, mainly for debugging. Included always
7
+ # as a generator for a grammar.
8
+ class Info < Base
9
+
10
+ register_as "info"
11
+
12
+ # Defines singleton method for every mod that the grammar passed
13
+ # to the generator.
14
+ #
15
+ # @see Generator#initialize
16
+ def initialize(*)
17
+ super
18
+ mods.each do |k, v|
19
+ define_singleton_method (k) { v }
20
+ end
21
+ end
22
+
23
+ def unused_symbols
24
+ @_unused_symbols ||= begin
25
+ used = grammar.all_productions.map(&:items).flatten.uniq
26
+ all = grammar.symbols.map do |s|
27
+ if Symbol === s
28
+ grammar.find_token(s)
29
+ else
30
+ s
31
+ end
32
+ end
33
+
34
+ all - used - [grammar.find_token(:"$start")]
35
+ end
36
+ end
37
+
38
+ # Actually performs the generation. Uses the template in
39
+ # output.erb, and generates the file `<file>.output`.
40
+ #
41
+ # @return [void]
42
+ def generate
43
+ template "info", "#{file}.inf"
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,18 +1,18 @@
1
- module Antelope
2
- module Generator
3
-
4
- # Represents a generator that does not generate anything.
5
- class Null < Base
6
-
7
- register_as "null"
8
-
9
- has_directive "null.data"
10
- has_directive "comment"
11
-
12
- # Does nothing.
13
- #
14
- # @return [void]
15
- def generate; end
16
- end
17
- end
18
- end
1
+ module Antelope
2
+ module Generator
3
+
4
+ # Represents a generator that does not generate anything.
5
+ class Null < Base
6
+
7
+ register_as "null"
8
+
9
+ has_directive "null.data"
10
+ has_directive "comment"
11
+
12
+ # Does nothing.
13
+ #
14
+ # @return [void]
15
+ def generate; end
16
+ end
17
+ end
18
+ end
@@ -1,49 +1,17 @@
1
- # encoding: utf-8
2
-
3
- module Antelope
4
- module Generator
5
-
6
- # Generates an output file, mainly for debugging. Included always
7
- # as a generator for a grammar.
8
- class Output < Base
9
-
10
- register_as "output"
11
-
12
- has_directive "output.show-lookahead", Boolean
13
-
14
- # Defines singleton method for every mod that the grammar passed
15
- # to the generator.
16
- #
17
- # @see Generator#initialize
18
- def initialize(*)
19
- super
20
- mods.each do |k, v|
21
- define_singleton_method (k) { v }
22
- end
23
- end
24
-
25
- def unused_symbols
26
- @_unused_symbols ||= begin
27
- used = grammar.all_productions.map(&:items).flatten.uniq
28
- all = grammar.symbols.map do |s|
29
- if Symbol === s
30
- grammar.find_token(s)
31
- else
32
- s
33
- end
34
- end
35
-
36
- all - used - [grammar.find_token(:"$start")]
37
- end
38
- end
39
-
40
- # Actually performs the generation. Uses the template in
41
- # output.erb, and generates the file `<file>.output`.
42
- #
43
- # @return [void]
44
- def generate
45
- template "output", "#{file}.output"
46
- end
47
- end
48
- end
49
- end
1
+ # encoding: utf-8
2
+
3
+ module Antelope
4
+ module Generator
5
+
6
+ # Generates an output file, mainly for debugging. Included always
7
+ # as a generator for a grammar.
8
+ class Output < Group
9
+
10
+ register_as "output"
11
+
12
+ register_generator Info, "info"
13
+ register_generator Error, "error"
14
+
15
+ end
16
+ end
17
+ end