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