antelope 0.3.2 → 0.4.0
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.
- checksums.yaml +4 -4
- data/.gitignore +25 -25
- data/.rspec +3 -3
- data/.travis.yml +10 -10
- data/.yardopts +7 -7
- data/CONTRIBUTING.md +50 -38
- data/GENERATORS.md +180 -124
- data/Gemfile +7 -7
- data/LICENSE.txt +22 -22
- data/README.md +240 -104
- data/Rakefile +2 -2
- data/TODO.md +58 -58
- data/antelope.gemspec +29 -28
- data/bin/antelope +7 -7
- data/examples/deterministic.ace +35 -35
- data/examples/example.ace +52 -51
- data/examples/example.ace.err +192 -192
- data/examples/example.ace.inf +432 -432
- data/examples/example.ate +70 -70
- data/examples/example.ate.err +192 -192
- data/examples/example.ate.inf +432 -432
- data/examples/liquidscript.ace +233 -233
- data/examples/simple.ace +22 -22
- data/lib/antelope/ace/compiler.rb +334 -334
- data/lib/antelope/ace/errors.rb +30 -30
- data/lib/antelope/ace/scanner/argument.rb +57 -57
- data/lib/antelope/ace/scanner/first.rb +89 -89
- data/lib/antelope/ace/scanner/second.rb +178 -178
- data/lib/antelope/ace/scanner/third.rb +27 -27
- data/lib/antelope/ace/scanner.rb +144 -144
- data/lib/antelope/ace.rb +47 -47
- data/lib/antelope/cli.rb +60 -60
- data/lib/antelope/errors.rb +25 -25
- data/lib/antelope/generation/constructor/first.rb +86 -86
- data/lib/antelope/generation/constructor/follow.rb +105 -105
- data/lib/antelope/generation/constructor/nullable.rb +64 -64
- data/lib/antelope/generation/constructor.rb +127 -127
- data/lib/antelope/generation/errors.rb +17 -17
- data/lib/antelope/generation/null.rb +13 -13
- data/lib/antelope/generation/recognizer/rule.rb +216 -216
- data/lib/antelope/generation/recognizer/state.rb +129 -129
- data/lib/antelope/generation/recognizer.rb +177 -177
- data/lib/antelope/generation/tableizer.rb +176 -176
- data/lib/antelope/generation.rb +15 -15
- data/lib/antelope/generator/base/coerce.rb +115 -0
- data/lib/antelope/generator/base/extra.rb +50 -0
- data/lib/antelope/generator/base.rb +134 -264
- data/lib/antelope/generator/c.rb +11 -11
- data/lib/antelope/generator/c_header.rb +105 -105
- data/lib/antelope/generator/c_source.rb +39 -39
- data/lib/antelope/generator/error.rb +34 -34
- data/lib/antelope/generator/group.rb +60 -57
- data/lib/antelope/generator/html.rb +51 -51
- data/lib/antelope/generator/info.rb +47 -47
- data/lib/antelope/generator/null.rb +18 -18
- data/lib/antelope/generator/output.rb +17 -17
- data/lib/antelope/generator/ruby.rb +112 -79
- data/lib/antelope/generator/templates/c_header.ant +36 -36
- data/lib/antelope/generator/templates/c_source.ant +202 -202
- data/lib/antelope/generator/templates/error.erb +40 -0
- data/lib/antelope/generator/templates/html/antelope.css +53 -1
- data/lib/antelope/generator/templates/html/antelope.html +82 -1
- data/lib/antelope/generator/templates/html/antelope.js +9 -1
- data/lib/antelope/generator/templates/html/css.ant +53 -53
- data/lib/antelope/generator/templates/html/html.ant +82 -82
- data/lib/antelope/generator/templates/html/js.ant +9 -9
- data/lib/antelope/generator/templates/info.erb +61 -0
- data/lib/antelope/generator/templates/{ruby.ant → ruby.erb} +171 -178
- data/lib/antelope/generator.rb +62 -66
- data/lib/antelope/grammar/generation.rb +76 -76
- data/lib/antelope/grammar/loading.rb +84 -84
- data/lib/antelope/grammar/precedence.rb +59 -59
- data/lib/antelope/grammar/precedences.rb +64 -64
- data/lib/antelope/grammar/production.rb +56 -56
- data/lib/antelope/grammar/productions.rb +154 -154
- data/lib/antelope/grammar/symbols.rb +64 -64
- data/lib/antelope/grammar/token/epsilon.rb +23 -23
- data/lib/antelope/grammar/token/error.rb +24 -24
- data/lib/antelope/grammar/token/nonterminal.rb +15 -15
- data/lib/antelope/grammar/token/terminal.rb +15 -15
- data/lib/antelope/grammar/token.rb +231 -231
- data/lib/antelope/grammar.rb +68 -68
- data/lib/antelope/version.rb +6 -6
- data/lib/antelope.rb +18 -19
- data/optimizations.txt +42 -42
- data/spec/antelope/ace/compiler_spec.rb +60 -60
- data/spec/antelope/ace/scanner_spec.rb +27 -27
- data/spec/antelope/generation/constructor_spec.rb +131 -131
- data/spec/fixtures/simple.ace +22 -22
- data/spec/spec_helper.rb +39 -39
- data/spec/support/benchmark_helper.rb +5 -5
- data/spec/support/grammar_helper.rb +14 -14
- data/subl/Ace (Ruby).JSON-tmLanguage +94 -94
- data/subl/Ace (Ruby).tmLanguage +153 -153
- metadata +22 -11
- data/lib/antelope/generator/templates/error.ant +0 -34
- data/lib/antelope/generator/templates/info.ant +0 -53
- data/lib/antelope/template/compiler.rb +0 -78
- data/lib/antelope/template/errors.rb +0 -9
- data/lib/antelope/template/scanner.rb +0 -109
- data/lib/antelope/template.rb +0 -64
- data/spec/antelope/template_spec.rb +0 -50
data/lib/antelope/ace/errors.rb
CHANGED
@@ -1,30 +1,30 @@
|
|
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 {Scanner}, this is raised when an input
|
13
|
-
# is malformed. The message should contain a snippet of the input
|
14
|
-
# which caused the error.
|
15
|
-
class SyntaxError < Error
|
16
|
-
end
|
17
|
-
|
18
|
-
# Primarily used in the {Compiler}, if a scanner token appears
|
19
|
-
# that should not be in the current state, this is raised.
|
20
|
-
class InvalidStateError < Error
|
21
|
-
end
|
22
|
-
|
23
|
-
# Primarily used in the {Compiler}, it is raised if it encounters
|
24
|
-
# a directive it cannot handle. This is more to warn the
|
25
|
-
# developer that a directive they wrote may not be accepted by any
|
26
|
-
# generator.
|
27
|
-
class NoDirectiveError < Error
|
28
|
-
end
|
29
|
-
end
|
30
|
-
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 {Scanner}, this is raised when an input
|
13
|
+
# is malformed. The message should contain a snippet of the input
|
14
|
+
# which caused the error.
|
15
|
+
class SyntaxError < Error
|
16
|
+
end
|
17
|
+
|
18
|
+
# Primarily used in the {Compiler}, if a scanner token appears
|
19
|
+
# that should not be in the current state, this is raised.
|
20
|
+
class InvalidStateError < Error
|
21
|
+
end
|
22
|
+
|
23
|
+
# Primarily used in the {Compiler}, it is raised if it encounters
|
24
|
+
# a directive it cannot handle. This is more to warn the
|
25
|
+
# developer that a directive they wrote may not be accepted by any
|
26
|
+
# generator.
|
27
|
+
class NoDirectiveError < Error
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,57 +1,57 @@
|
|
1
|
-
module Antelope
|
2
|
-
module Ace
|
3
|
-
class Scanner
|
4
|
-
|
5
|
-
# Represents an argument to a directive. It encapsulates a
|
6
|
-
# string object, which is the value of the argument.
|
7
|
-
class Argument < String
|
8
|
-
|
9
|
-
# Initialize the argument.
|
10
|
-
#
|
11
|
-
# @param type [Symbol] the type of argument it is; it can be
|
12
|
-
# a `:block`, `:text`, or `:caret`. The type is defined by
|
13
|
-
# the encapsulating characters. If the encapsulating
|
14
|
-
# characters are `{` and `}`, it's a `:block`; if they are
|
15
|
-
# `<` and `>`, it's a `:caret`; otherwise, it's a `:text`.
|
16
|
-
# @param value [String] the value of the argument.
|
17
|
-
def initialize(type, value)
|
18
|
-
@type = type
|
19
|
-
super(value)
|
20
|
-
end
|
21
|
-
|
22
|
-
# If this argument is type `:block`.
|
23
|
-
#
|
24
|
-
# @return [Boolean]
|
25
|
-
# @see type?
|
26
|
-
def block?
|
27
|
-
type? :block
|
28
|
-
end
|
29
|
-
|
30
|
-
# If this argument is type `:text`.
|
31
|
-
#
|
32
|
-
# @return [Boolean]
|
33
|
-
# @see type?
|
34
|
-
def text?
|
35
|
-
type? :text
|
36
|
-
end
|
37
|
-
|
38
|
-
# If this argument is type `:caret`.
|
39
|
-
#
|
40
|
-
# @return [Boolean]
|
41
|
-
# @see type?
|
42
|
-
def caret?
|
43
|
-
type? :caret
|
44
|
-
end
|
45
|
-
|
46
|
-
# Checks to see if any of the given arguments match the type
|
47
|
-
# of this argument.
|
48
|
-
#
|
49
|
-
# @param inc [Array<Symbol>]
|
50
|
-
# @return [Boolean]
|
51
|
-
def type?(*inc)
|
52
|
-
inc.include?(@type)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
1
|
+
module Antelope
|
2
|
+
module Ace
|
3
|
+
class Scanner
|
4
|
+
|
5
|
+
# Represents an argument to a directive. It encapsulates a
|
6
|
+
# string object, which is the value of the argument.
|
7
|
+
class Argument < String
|
8
|
+
|
9
|
+
# Initialize the argument.
|
10
|
+
#
|
11
|
+
# @param type [Symbol] the type of argument it is; it can be
|
12
|
+
# a `:block`, `:text`, or `:caret`. The type is defined by
|
13
|
+
# the encapsulating characters. If the encapsulating
|
14
|
+
# characters are `{` and `}`, it's a `:block`; if they are
|
15
|
+
# `<` and `>`, it's a `:caret`; otherwise, it's a `:text`.
|
16
|
+
# @param value [String] the value of the argument.
|
17
|
+
def initialize(type, value)
|
18
|
+
@type = type
|
19
|
+
super(value)
|
20
|
+
end
|
21
|
+
|
22
|
+
# If this argument is type `:block`.
|
23
|
+
#
|
24
|
+
# @return [Boolean]
|
25
|
+
# @see type?
|
26
|
+
def block?
|
27
|
+
type? :block
|
28
|
+
end
|
29
|
+
|
30
|
+
# If this argument is type `:text`.
|
31
|
+
#
|
32
|
+
# @return [Boolean]
|
33
|
+
# @see type?
|
34
|
+
def text?
|
35
|
+
type? :text
|
36
|
+
end
|
37
|
+
|
38
|
+
# If this argument is type `:caret`.
|
39
|
+
#
|
40
|
+
# @return [Boolean]
|
41
|
+
# @see type?
|
42
|
+
def caret?
|
43
|
+
type? :caret
|
44
|
+
end
|
45
|
+
|
46
|
+
# Checks to see if any of the given arguments match the type
|
47
|
+
# of this argument.
|
48
|
+
#
|
49
|
+
# @param inc [Array<Symbol>]
|
50
|
+
# @return [Boolean]
|
51
|
+
def type?(*inc)
|
52
|
+
inc.include?(@type)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -1,89 +1,89 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Antelope
|
4
|
-
module Ace
|
5
|
-
class Scanner
|
6
|
-
|
7
|
-
# Scans the first section of the file. This contains directives and
|
8
|
-
# small blocks that can be copied directly into the body of the output.
|
9
|
-
# The blocks are formatted as `%{ ... %}`; however, the ending tag _must_
|
10
|
-
# be on its own line. The directive is formatted as `%<name> <value>`,
|
11
|
-
# with `<name>` being the key, and `<value>` being the value. The value
|
12
|
-
# can be a piece of straight-up text (no quotes), or it can be quoted.
|
13
|
-
# There can be any number of values to a directive.
|
14
|
-
module First
|
15
|
-
|
16
|
-
# Scans until the first content boundry. If it encounters anything but
|
17
|
-
# a block or a directive (or whitespace), it will raise an error.
|
18
|
-
#
|
19
|
-
# @raise [SyntaxError] if it encounters anything but whitespace, a
|
20
|
-
# block, or a directive.
|
21
|
-
# @return [void]
|
22
|
-
def scan_first_part
|
23
|
-
until @scanner.check(CONTENT_BOUNDRY)
|
24
|
-
scan_first_copy || scan_first_directive ||
|
25
|
-
scan_whitespace || scan_comment || error!
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# Scans for a block. It is called `copy` instead of `block` because
|
30
|
-
# contents of the block is _copied_ directly into the body.
|
31
|
-
#
|
32
|
-
# @return [Boolean] if it matched.
|
33
|
-
def scan_first_copy
|
34
|
-
if @scanner.scan(/%{([\s\S]+?)\n\s*%}/)
|
35
|
-
tokens << [:copy, @scanner[1]]
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# Scans a directive. A directive has one _name_, and any number of
|
40
|
-
# arguments. Every argument is a _value_. The name can be any
|
41
|
-
# combinations of alphabetical characters, underscores, and dashes;
|
42
|
-
# the value can be word characters, or a quote-delimited string.
|
43
|
-
# It emits a `:directive` token with the directive (Sring) as an
|
44
|
-
# argument, and the passed arguments (Array<String>).
|
45
|
-
#
|
46
|
-
# @return [Boolean] if it matched.
|
47
|
-
def scan_first_directive
|
48
|
-
if @scanner.scan(/%(#{IDENTIFIER}) ?/)
|
49
|
-
directive = @scanner[1]
|
50
|
-
arguments = scan_first_directive_arguments
|
51
|
-
|
52
|
-
tokens << [:directive, directive, arguments]
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# Scan the arguments for a directive. It keeps attempting to
|
57
|
-
# scan arguments until the first newline that was not in a
|
58
|
-
# block. Arguments can be blocks, carets, or text; blocks are
|
59
|
-
# encapsulated with `{` and `}`, carets are encapsulated with
|
60
|
-
# `<` and `>`, and text is encapsulated with quotes or
|
61
|
-
# nothing.
|
62
|
-
#
|
63
|
-
# @return [Array<Argument>]
|
64
|
-
def scan_first_directive_arguments
|
65
|
-
arguments = []
|
66
|
-
until @scanner.check(/\n/)
|
67
|
-
if @scanner.scan(/\{/)
|
68
|
-
argument =
|
69
|
-
Argument.new(:block, _scan_block[1..-2])
|
70
|
-
elsif @scanner.scan(/</)
|
71
|
-
@scanner.scan(/((?:\\>|[^>])*)\>/)
|
72
|
-
argument =
|
73
|
-
Argument.new(:caret, @scanner[1])
|
74
|
-
else
|
75
|
-
@scanner.scan(/#{VALUE}/x) or error!
|
76
|
-
argument = Argument.new(:text,
|
77
|
-
@scanner[2] || @scanner[3])
|
78
|
-
end
|
79
|
-
|
80
|
-
arguments.push(argument)
|
81
|
-
@scanner.scan(/ */)
|
82
|
-
end
|
83
|
-
|
84
|
-
arguments
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Antelope
|
4
|
+
module Ace
|
5
|
+
class Scanner
|
6
|
+
|
7
|
+
# Scans the first section of the file. This contains directives and
|
8
|
+
# small blocks that can be copied directly into the body of the output.
|
9
|
+
# The blocks are formatted as `%{ ... %}`; however, the ending tag _must_
|
10
|
+
# be on its own line. The directive is formatted as `%<name> <value>`,
|
11
|
+
# with `<name>` being the key, and `<value>` being the value. The value
|
12
|
+
# can be a piece of straight-up text (no quotes), or it can be quoted.
|
13
|
+
# There can be any number of values to a directive.
|
14
|
+
module First
|
15
|
+
|
16
|
+
# Scans until the first content boundry. If it encounters anything but
|
17
|
+
# a block or a directive (or whitespace), it will raise an error.
|
18
|
+
#
|
19
|
+
# @raise [SyntaxError] if it encounters anything but whitespace, a
|
20
|
+
# block, or a directive.
|
21
|
+
# @return [void]
|
22
|
+
def scan_first_part
|
23
|
+
until @scanner.check(CONTENT_BOUNDRY)
|
24
|
+
scan_first_copy || scan_first_directive ||
|
25
|
+
scan_whitespace || scan_comment || error!
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Scans for a block. It is called `copy` instead of `block` because
|
30
|
+
# contents of the block is _copied_ directly into the body.
|
31
|
+
#
|
32
|
+
# @return [Boolean] if it matched.
|
33
|
+
def scan_first_copy
|
34
|
+
if @scanner.scan(/%{([\s\S]+?)\n\s*%}/)
|
35
|
+
tokens << [:copy, @scanner[1]]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Scans a directive. A directive has one _name_, and any number of
|
40
|
+
# arguments. Every argument is a _value_. The name can be any
|
41
|
+
# combinations of alphabetical characters, underscores, and dashes;
|
42
|
+
# the value can be word characters, or a quote-delimited string.
|
43
|
+
# It emits a `:directive` token with the directive (Sring) as an
|
44
|
+
# argument, and the passed arguments (Array<String>).
|
45
|
+
#
|
46
|
+
# @return [Boolean] if it matched.
|
47
|
+
def scan_first_directive
|
48
|
+
if @scanner.scan(/%(#{IDENTIFIER}) ?/)
|
49
|
+
directive = @scanner[1]
|
50
|
+
arguments = scan_first_directive_arguments
|
51
|
+
|
52
|
+
tokens << [:directive, directive, arguments]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Scan the arguments for a directive. It keeps attempting to
|
57
|
+
# scan arguments until the first newline that was not in a
|
58
|
+
# block. Arguments can be blocks, carets, or text; blocks are
|
59
|
+
# encapsulated with `{` and `}`, carets are encapsulated with
|
60
|
+
# `<` and `>`, and text is encapsulated with quotes or
|
61
|
+
# nothing.
|
62
|
+
#
|
63
|
+
# @return [Array<Argument>]
|
64
|
+
def scan_first_directive_arguments
|
65
|
+
arguments = []
|
66
|
+
until @scanner.check(/\n/)
|
67
|
+
if @scanner.scan(/\{/)
|
68
|
+
argument =
|
69
|
+
Argument.new(:block, _scan_block[1..-2])
|
70
|
+
elsif @scanner.scan(/</)
|
71
|
+
@scanner.scan(/((?:\\>|[^>])*)\>/)
|
72
|
+
argument =
|
73
|
+
Argument.new(:caret, @scanner[1])
|
74
|
+
else
|
75
|
+
@scanner.scan(/#{VALUE}/x) or error!
|
76
|
+
argument = Argument.new(:text,
|
77
|
+
@scanner[2] || @scanner[3])
|
78
|
+
end
|
79
|
+
|
80
|
+
arguments.push(argument)
|
81
|
+
@scanner.scan(/ */)
|
82
|
+
end
|
83
|
+
|
84
|
+
arguments
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|