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,78 +1,78 @@
1
- module Antelope
2
- class Template
3
- class Compiler
4
-
5
- attr_reader :buffer
6
-
7
- attr_reader :tokens
8
-
9
- def initialize(tokens, buffer_variable = "_out")
10
- @tokens = tokens.dup
11
- @buffer = ""
12
- @buffer_variable = buffer_variable
13
- end
14
-
15
- def compile
16
- merge_text_tokens
17
-
18
- @buffer = "#{@buffer_variable} ||= \"\"\n"
19
-
20
- until @tokens.empty?
21
- token = @tokens.shift
22
- parse_method = "parse_#{token[0]}".intern
23
-
24
- send(parse_method, token[1])
25
- end
26
-
27
- @buffer << "#{@buffer_variable}\n"
28
-
29
- @buffer
30
-
31
- rescue NoMethodError => e
32
-
33
- if e.name == parse_method
34
- raise NoTokenError, "No token #{token[0]} exists"
35
- else
36
- raise
37
- end
38
- end
39
-
40
- private
41
-
42
- def parse_text(value)
43
- buffer << "#{@buffer_variable} << #{value.to_s.inspect}\n"
44
- end
45
-
46
- def parse_tag(value)
47
- value.gsub!(/\A\s*([\s\S]*?)\s*\Z/, "\\1")
48
- buffer << "#{value}\n"
49
- end
50
-
51
- def parse_output_tag(value)
52
- value.gsub!(/\A\s*([\s\S]*?)\s*\Z/, "\\1")
53
- buffer << "#{@buffer_variable} << begin\n " \
54
- "#{value}\nend.to_s\n"
55
- end
56
-
57
- def parse_newline(_)
58
- parse_text("\n")
59
- end
60
-
61
- def parse_comment_tag(_)
62
- end
63
-
64
- def merge_text_tokens
65
- new_tokens = []
66
- @tokens.chunk(&:first).each do |type, tokens|
67
- if type == :text
68
- new_tokens << [:text, tokens.map(&:last).join('')]
69
- else
70
- new_tokens.push(*tokens)
71
- end
72
- end
73
-
74
- @tokens = new_tokens
75
- end
76
- end
77
- end
78
- end
1
+ module Antelope
2
+ class Template
3
+ class Compiler
4
+
5
+ attr_reader :buffer
6
+
7
+ attr_reader :tokens
8
+
9
+ def initialize(tokens, buffer_variable = "_out")
10
+ @tokens = tokens.dup
11
+ @buffer = ""
12
+ @buffer_variable = buffer_variable
13
+ end
14
+
15
+ def compile
16
+ merge_text_tokens
17
+
18
+ @buffer = "\# encoding: utf-8\n#{@buffer_variable} ||= \"\"\n"
19
+
20
+ until @tokens.empty?
21
+ token = @tokens.shift
22
+ parse_method = "parse_#{token[0]}".intern
23
+
24
+ send(parse_method, token[1])
25
+ end
26
+
27
+ @buffer << "#{@buffer_variable}\n"
28
+
29
+ @buffer
30
+
31
+ rescue NoMethodError => e
32
+
33
+ if e.name == parse_method
34
+ raise NoTokenError, "No token #{token[0]} exists"
35
+ else
36
+ raise
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def parse_text(value)
43
+ buffer << "#{@buffer_variable} << #{value.to_s.inspect}\n"
44
+ end
45
+
46
+ def parse_tag(value)
47
+ value.gsub!(/\A([\s\S]*?)\s*\Z/, "\\1")
48
+ buffer << "#{value}\n"
49
+ end
50
+
51
+ def parse_output_tag(value)
52
+ value.gsub!(/\A\s*([\s\S]*?)\s*\Z/, "\\1")
53
+ buffer << "#{@buffer_variable} << begin\n " \
54
+ "#{value}\nend.to_s\n"
55
+ end
56
+
57
+ def parse_newline(_)
58
+ parse_text("\n")
59
+ end
60
+
61
+ def parse_comment_tag(_)
62
+ end
63
+
64
+ def merge_text_tokens
65
+ new_tokens = []
66
+ @tokens.chunk(&:first).each do |type, tokens|
67
+ if type == :text
68
+ new_tokens << [:text, tokens.map(&:last).join('')]
69
+ else
70
+ new_tokens.push(*tokens)
71
+ end
72
+ end
73
+
74
+ @tokens = new_tokens
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,9 +1,9 @@
1
- module Antelope
2
- class Template
3
- class Error < Antelope::Error; end
4
-
5
- class SyntaxError < Error; end
6
-
7
- class NoTokenError < Error; end
8
- end
9
- end
1
+ module Antelope
2
+ class Template
3
+ class Error < Antelope::Error; end
4
+
5
+ class SyntaxError < Error; end
6
+
7
+ class NoTokenError < Error; end
8
+ end
9
+ end
@@ -1,109 +1,109 @@
1
- require 'strscan'
2
-
3
- module Antelope
4
- class Template
5
- class Scanner
6
- attr_reader :scanner
7
-
8
- attr_reader :tokens
9
-
10
- def initialize(input, source = "(template)")
11
- @scanner = StringScanner.new(input)
12
- @source = source
13
- @tokens = nil
14
- @line = 1
15
- end
16
-
17
- def scan
18
-
19
- @tokens ||= begin
20
- @tokens = []
21
- @line = 1
22
- @scanner.pos = 0
23
- until @scanner.eos?
24
- scan_tag || scan_until_tag || scan_until_end
25
- end
26
-
27
- @tokens
28
- end
29
-
30
- rescue SyntaxError => e
31
- start = [@scanner.pos - 8, 0].max
32
- stop = [@scanner.pos + 8, @scanner.string.length].min
33
- snip = @scanner.string[start..stop].inspect
34
- char = @scanner.string[@scanner.pos]
35
- char = if char
36
- char.inspect
37
- else
38
- "EOF"
39
- end
40
-
41
- new_line = "#{@source}:#{@line}:#{@scanner.pos}: "\
42
- "unexpected #{char} (near #{snip})"
43
-
44
- raise e, e.message, [new_line, *e.backtrace]
45
- end
46
-
47
- private
48
-
49
- def scan_until_tag
50
- case
51
- when value = @scanner.scan_until(/(\%|\{|\}|\\|\n)/)
52
- @scanner.pos -= 1
53
- tokens << [:text, value[0..-2]]
54
- end
55
- end
56
-
57
- def scan_until_end
58
- tokens << [:text, @scanner.scan(/.+/m)]
59
- end
60
-
61
- def scan_tag
62
- case
63
- when @scanner.scan(/\\(\{\{|\}\}|\%)/)
64
- tokens << [:text, @scanner[1]]
65
- when @scanner.scan(/\n?\%\{/)
66
- update_line
67
- scan_tag_start(:output_tag, :_, /\}/)
68
- when @scanner.scan(/\n?\%/)
69
- update_line
70
- tokens << [:tag, value]
71
- when @scanner.scan(/\n?\{\{=/)
72
- update_line
73
- scan_tag_start(:output_tag)
74
- when @scanner.scan(/\n?\{\{!/)
75
- update_line
76
- scan_tag_start(:comment_tag)
77
- when @scanner.scan(/\n?\{\{/)
78
- update_line
79
- scan_tag_start(:tag)
80
- when @scanner.scan(/\}\}/)
81
- @scanner.pos -= 2
82
- error!
83
- when @scanner.scan(/\{|\}|\%|\\|\n/)
84
- tokens << [:text, @scanner[0]]
85
- else
86
- false
87
- end
88
- end
89
-
90
- def scan_tag_start(type, online = :_, ending = /\}\}/)
91
- if online == :_
92
- online = @scanner[0][0] == "\n"
93
- end
94
-
95
- value = @scanner.scan_until(ending) or error!
96
- tokens << [type, value[0..-(@scanner[0].length + 1)]]
97
- end
98
-
99
- def error!
100
- raise SyntaxError, "invalid syntax"
101
- end
102
-
103
- def update_line
104
- @line += @scanner[0].count("\n")
105
- end
106
-
107
- end
108
- end
109
- end
1
+ require 'strscan'
2
+
3
+ module Antelope
4
+ class Template
5
+ class Scanner
6
+ attr_reader :scanner
7
+
8
+ attr_reader :tokens
9
+
10
+ def initialize(input, source = "(template)")
11
+ @scanner = StringScanner.new(input)
12
+ @source = source
13
+ @tokens = nil
14
+ @line = 1
15
+ end
16
+
17
+ def scan
18
+
19
+ @tokens ||= begin
20
+ @tokens = []
21
+ @line = 1
22
+ @scanner.pos = 0
23
+ until @scanner.eos?
24
+ scan_tag || scan_until_tag || scan_until_end
25
+ end
26
+
27
+ @tokens
28
+ end
29
+
30
+ rescue SyntaxError => e
31
+ start = [@scanner.pos - 8, 0].max
32
+ stop = [@scanner.pos + 8, @scanner.string.length].min
33
+ snip = @scanner.string[start..stop].inspect
34
+ char = @scanner.string[@scanner.pos]
35
+ char = if char
36
+ char.inspect
37
+ else
38
+ "EOF"
39
+ end
40
+
41
+ new_line = "#{@source}:#{@line}:#{@scanner.pos}: "\
42
+ "unexpected #{char} (near #{snip})"
43
+
44
+ raise e, e.message, [new_line, *e.backtrace]
45
+ end
46
+
47
+ private
48
+
49
+ def scan_until_tag
50
+ case
51
+ when value = @scanner.scan_until(/(\%|\{|\}|\\|\n)/)
52
+ @scanner.pos -= 1
53
+ tokens << [:text, value[0..-2]]
54
+ end
55
+ end
56
+
57
+ def scan_until_end
58
+ tokens << [:text, @scanner.scan(/.+/m)]
59
+ end
60
+
61
+ def scan_tag
62
+ case
63
+ when @scanner.scan(/\\(\{\{|\}\}|\%)/)
64
+ tokens << [:text, @scanner[1]]
65
+ when @scanner.scan(/\%\%/)
66
+ tokens << [:text, "%"]
67
+ when @scanner.scan(/\n?\%\{/)
68
+ update_line
69
+ scan_tag_start(:output_tag, /\}/)
70
+ when @scanner.scan(/(\n|\A)\%/)
71
+ update_line
72
+ #tokens << [:tag]
73
+ scan_tag_start(:tag, /\n/)
74
+ @scanner.pos -= 1
75
+ when @scanner.scan(/\n?\{\{=/)
76
+ update_line
77
+ scan_tag_start(:output_tag)
78
+ when @scanner.scan(/\n?\{\{!/)
79
+ update_line
80
+ scan_tag_start(:comment_tag)
81
+ when @scanner.scan(/\n?\{\{/)
82
+ update_line
83
+ scan_tag_start(:tag)
84
+ when @scanner.scan(/\}\}/)
85
+ @scanner.pos -= 2
86
+ error!
87
+ when @scanner.scan(/\{|\}|\%|\\|\n/)
88
+ tokens << [:text, @scanner[0]]
89
+ else
90
+ false
91
+ end
92
+ end
93
+
94
+ def scan_tag_start(type, ending = /\}\}/)
95
+ value = @scanner.scan_until(ending) or error!
96
+ tokens << [type, value[0..-(@scanner[0].length + 1)]]
97
+ end
98
+
99
+ def error!
100
+ raise SyntaxError, "invalid syntax"
101
+ end
102
+
103
+ def update_line
104
+ @line += @scanner[0].count("\n")
105
+ end
106
+
107
+ end
108
+ end
109
+ end
@@ -1,60 +1,65 @@
1
- require "antelope/template/errors"
2
- require "antelope/template/scanner"
3
- require "antelope/template/compiler"
4
-
5
-
6
- module Antelope
7
- class Template
8
-
9
- NO_SOURCE = Object.new
10
-
11
-
12
- def initialize(input, source = NO_SOURCE)
13
- @input = normalize_input(input)
14
- @source = determine_source(input, source)
15
- end
16
-
17
- def parse
18
- @result ||= begin
19
- scanner = Scanner.new(@input, @source)
20
- compiler = Compiler.new(scanner.scan)
21
- compiler.compile
22
- end
23
- end
24
-
25
- def result(binding = TOPLEVEL_BINDING.dup)
26
- # sue me.
27
- eval(parse, binding, "#{@source}.rb", 0)
28
- end
29
-
30
- alias_method :run, :result
31
- alias_method :call, :result
32
-
33
- private
34
-
35
- def normalize_input(input)
36
- case
37
- when String === input
38
- input
39
- when input.respond_to?(:read)
40
- input.read
41
- when input.respond_to?(:open)
42
- input.open("r") { |f| f.read }
43
- else
44
- raise ArgumentError, "Received #{input.class}, expected " \
45
- "#{String}, #read"
46
- end
47
- end
48
-
49
- def determine_source(input, source)
50
- case
51
- when source != NO_SOURCE
52
- source
53
- when input.respond_to?(:to_path)
54
- input.to_path
55
- else
56
- "(template)"
57
- end
58
- end
59
- end
60
- end
1
+ require "antelope/template/errors"
2
+ require "antelope/template/scanner"
3
+ require "antelope/template/compiler"
4
+
5
+
6
+ module Antelope
7
+ class Template
8
+
9
+ NO_SOURCE = Object.new
10
+
11
+
12
+ def initialize(input, source = NO_SOURCE)
13
+ @input = normalize_input(input)
14
+ @source = determine_source(input, source)
15
+ end
16
+
17
+ def parse
18
+ @result ||= begin
19
+ scanner = Scanner.new(@input, @source)
20
+ compiler = Compiler.new(scanner.scan)
21
+ compiler.compile
22
+ end
23
+ end
24
+
25
+ def result(binding = TOPLEVEL_BINDING.dup)
26
+ # sue me.
27
+ eval(parse, binding, fake_name, 0)
28
+ end
29
+
30
+ alias_method :run, :result
31
+ alias_method :call, :result
32
+
33
+ private
34
+
35
+ def normalize_input(input)
36
+ case
37
+ when String === input
38
+ input
39
+ when input.respond_to?(:read)
40
+ input.read
41
+ when input.respond_to?(:open)
42
+ input.open("r") { |f| f.read }
43
+ else
44
+ raise ArgumentError, "Received #{input.class}, expected " \
45
+ "#{String}, #read"
46
+ end
47
+ end
48
+
49
+ def determine_source(input, source)
50
+ case
51
+ when source != NO_SOURCE
52
+ source
53
+ when input.respond_to?(:to_path)
54
+ input.to_path
55
+ else
56
+ "(template)"
57
+ end
58
+ end
59
+
60
+ def fake_name
61
+ File.join(File.dirname(@source),
62
+ "_#{File.basename(@source, '.*')}.rb")
63
+ end
64
+ end
65
+ end
@@ -1,6 +1,6 @@
1
- # encoding: utf-8
2
-
3
- module Antelope
4
- # The current running version of antelope.
5
- VERSION = "0.2.0".freeze
6
- end
1
+ # encoding: utf-8
2
+
3
+ module Antelope
4
+ # The current running version of antelope.
5
+ VERSION = "0.2.2".freeze
6
+ end
data/lib/antelope.rb CHANGED
@@ -1,13 +1,13 @@
1
- # encoding: utf-8
2
-
3
- require "antelope/errors"
4
- require "antelope/generation"
5
- require "antelope/generator"
6
- require "antelope/version"
7
- require "antelope/ace"
8
- require "antelope/template"
9
-
10
- # Antelope, the compiler compiler.
11
- module Antelope
12
-
13
- end
1
+ # encoding: utf-8
2
+
3
+ require "antelope/errors"
4
+ require "antelope/generation"
5
+ require "antelope/generator"
6
+ require "antelope/version"
7
+ require "antelope/ace"
8
+ require "antelope/template"
9
+
10
+ # Antelope, the compiler compiler.
11
+ module Antelope
12
+
13
+ end
data/optimizations.txt ADDED
@@ -0,0 +1,42 @@
1
+ lib/antelope/ace/grammar/precedences.rb
2
+ Array#select.first is slower than Array#detect. Occured at lines: 31, 35.
3
+ Using each_with_index is slower than while loop. Occured at lines: 51.
4
+
5
+ lib/antelope/ace/grammar/productions.rb
6
+ Using each_with_index is slower than while loop. Occured at lines: 71, 106.
7
+
8
+ lib/antelope/ace/grammar/symbols.rb
9
+ Hash#fetch with second argument is slower than Hash#fetch with block. Occured at lines: 17.
10
+
11
+ lib/antelope/generation/constructor/first.rb
12
+ Using each_with_index is slower than while loop. Occured at lines: 63.
13
+
14
+ lib/antelope/generation/constructor/follow.rb
15
+ Using each_with_index is slower than while loop. Occured at lines: 78.
16
+
17
+ lib/antelope/generation/constructor.rb
18
+ Using each_with_index is slower than while loop. Occured at lines: 71.
19
+
20
+ lib/antelope/generation/recognizer/rule.rb
21
+ Parallel assignment is slower than sequential assignment. Occured at lines: 77.
22
+ Using each_with_index is slower than while loop. Occured at lines: 178.
23
+
24
+ lib/antelope/generation/recognizer/state.rb
25
+ Using each_with_index is slower than while loop. Occured at lines: 123.
26
+
27
+ lib/antelope/generation/recognizer.rb
28
+ Using each_with_index is slower than while loop. Occured at lines: 138.
29
+
30
+ lib/antelope/generation/tableizer.rb
31
+ Using each_with_index is slower than while loop. Occured at lines: 90, 138.
32
+ Parallel assignment is slower than sequential assignment. Occured at lines: 99.
33
+
34
+ lib/antelope/generator/base.rb
35
+ Using each_with_index is slower than while loop. Occured at lines: 124.
36
+
37
+ lib/antelope/generator/c_header.rb
38
+ Using each_with_index is slower than while loop. Occured at lines: 91.
39
+
40
+ lib/antelope/template/compiler.rb
41
+ Don't rescue NoMethodError, rather check with respond_to?. Occured at lines: 40.
42
+