antelope 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +25 -25
  3. data/.rspec +3 -3
  4. data/.travis.yml +10 -10
  5. data/.yardopts +7 -7
  6. data/CONTRIBUTING.md +50 -38
  7. data/GENERATORS.md +180 -124
  8. data/Gemfile +7 -7
  9. data/LICENSE.txt +22 -22
  10. data/README.md +240 -104
  11. data/Rakefile +2 -2
  12. data/TODO.md +58 -58
  13. data/antelope.gemspec +29 -28
  14. data/bin/antelope +7 -7
  15. data/examples/deterministic.ace +35 -35
  16. data/examples/example.ace +52 -51
  17. data/examples/example.ace.err +192 -192
  18. data/examples/example.ace.inf +432 -432
  19. data/examples/example.ate +70 -70
  20. data/examples/example.ate.err +192 -192
  21. data/examples/example.ate.inf +432 -432
  22. data/examples/liquidscript.ace +233 -233
  23. data/examples/simple.ace +22 -22
  24. data/lib/antelope/ace/compiler.rb +334 -334
  25. data/lib/antelope/ace/errors.rb +30 -30
  26. data/lib/antelope/ace/scanner/argument.rb +57 -57
  27. data/lib/antelope/ace/scanner/first.rb +89 -89
  28. data/lib/antelope/ace/scanner/second.rb +178 -178
  29. data/lib/antelope/ace/scanner/third.rb +27 -27
  30. data/lib/antelope/ace/scanner.rb +144 -144
  31. data/lib/antelope/ace.rb +47 -47
  32. data/lib/antelope/cli.rb +60 -60
  33. data/lib/antelope/errors.rb +25 -25
  34. data/lib/antelope/generation/constructor/first.rb +86 -86
  35. data/lib/antelope/generation/constructor/follow.rb +105 -105
  36. data/lib/antelope/generation/constructor/nullable.rb +64 -64
  37. data/lib/antelope/generation/constructor.rb +127 -127
  38. data/lib/antelope/generation/errors.rb +17 -17
  39. data/lib/antelope/generation/null.rb +13 -13
  40. data/lib/antelope/generation/recognizer/rule.rb +216 -216
  41. data/lib/antelope/generation/recognizer/state.rb +129 -129
  42. data/lib/antelope/generation/recognizer.rb +177 -177
  43. data/lib/antelope/generation/tableizer.rb +176 -176
  44. data/lib/antelope/generation.rb +15 -15
  45. data/lib/antelope/generator/base/coerce.rb +115 -0
  46. data/lib/antelope/generator/base/extra.rb +50 -0
  47. data/lib/antelope/generator/base.rb +134 -264
  48. data/lib/antelope/generator/c.rb +11 -11
  49. data/lib/antelope/generator/c_header.rb +105 -105
  50. data/lib/antelope/generator/c_source.rb +39 -39
  51. data/lib/antelope/generator/error.rb +34 -34
  52. data/lib/antelope/generator/group.rb +60 -57
  53. data/lib/antelope/generator/html.rb +51 -51
  54. data/lib/antelope/generator/info.rb +47 -47
  55. data/lib/antelope/generator/null.rb +18 -18
  56. data/lib/antelope/generator/output.rb +17 -17
  57. data/lib/antelope/generator/ruby.rb +112 -79
  58. data/lib/antelope/generator/templates/c_header.ant +36 -36
  59. data/lib/antelope/generator/templates/c_source.ant +202 -202
  60. data/lib/antelope/generator/templates/error.erb +40 -0
  61. data/lib/antelope/generator/templates/html/antelope.css +53 -1
  62. data/lib/antelope/generator/templates/html/antelope.html +82 -1
  63. data/lib/antelope/generator/templates/html/antelope.js +9 -1
  64. data/lib/antelope/generator/templates/html/css.ant +53 -53
  65. data/lib/antelope/generator/templates/html/html.ant +82 -82
  66. data/lib/antelope/generator/templates/html/js.ant +9 -9
  67. data/lib/antelope/generator/templates/info.erb +61 -0
  68. data/lib/antelope/generator/templates/{ruby.ant → ruby.erb} +171 -178
  69. data/lib/antelope/generator.rb +62 -66
  70. data/lib/antelope/grammar/generation.rb +76 -76
  71. data/lib/antelope/grammar/loading.rb +84 -84
  72. data/lib/antelope/grammar/precedence.rb +59 -59
  73. data/lib/antelope/grammar/precedences.rb +64 -64
  74. data/lib/antelope/grammar/production.rb +56 -56
  75. data/lib/antelope/grammar/productions.rb +154 -154
  76. data/lib/antelope/grammar/symbols.rb +64 -64
  77. data/lib/antelope/grammar/token/epsilon.rb +23 -23
  78. data/lib/antelope/grammar/token/error.rb +24 -24
  79. data/lib/antelope/grammar/token/nonterminal.rb +15 -15
  80. data/lib/antelope/grammar/token/terminal.rb +15 -15
  81. data/lib/antelope/grammar/token.rb +231 -231
  82. data/lib/antelope/grammar.rb +68 -68
  83. data/lib/antelope/version.rb +6 -6
  84. data/lib/antelope.rb +18 -19
  85. data/optimizations.txt +42 -42
  86. data/spec/antelope/ace/compiler_spec.rb +60 -60
  87. data/spec/antelope/ace/scanner_spec.rb +27 -27
  88. data/spec/antelope/generation/constructor_spec.rb +131 -131
  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 +14 -14
  93. data/subl/Ace (Ruby).JSON-tmLanguage +94 -94
  94. data/subl/Ace (Ruby).tmLanguage +153 -153
  95. metadata +22 -11
  96. data/lib/antelope/generator/templates/error.ant +0 -34
  97. data/lib/antelope/generator/templates/info.ant +0 -53
  98. data/lib/antelope/template/compiler.rb +0 -78
  99. data/lib/antelope/template/errors.rb +0 -9
  100. data/lib/antelope/template/scanner.rb +0 -109
  101. data/lib/antelope/template.rb +0 -64
  102. data/spec/antelope/template_spec.rb +0 -50
@@ -1,84 +1,84 @@
1
- # encoding: utf-8
2
-
3
- module Antelope
4
- class Grammar
5
- # Handles loading to and from files and strings.
6
- module Loading
7
- # Defines class methods on the grammar.
8
- module ClassMethods
9
- # Loads a grammar from a file. Assumes the output
10
- # directory and name from the file name.
11
- #
12
- # @param file_name [String] the file name.
13
- # @return [Grammar]
14
- # @see #from_string
15
- def from_file(file_name)
16
- ext = File.extname(file_name)
17
- case ext
18
- when ".rb", ".ate"
19
- from_dsl_file(file_name)
20
- when ".ace"
21
- from_ace_file(file_name)
22
- else
23
- raise ArgumentError, "Unexpected file extension #{ext},"\
24
- " expected one of .rb, .ate, or .ace"
25
- end
26
- end
27
-
28
- def from_dsl_file(file_name)
29
- body = File.read(file_name)
30
- output = File.dirname(file_name)
31
- from_dsl_string(file_name, output, body)
32
- end
33
-
34
- def from_ace_file(file_name)
35
- body = File.read(file_name)
36
- output = File.dirname(file_name)
37
- name = File.basename(file_name)
38
- from_ace_string(name, output, body)
39
- end
40
-
41
- # Loads a grammar from a string. First runs the scanner and
42
- # compiler over the string, and then instantiates a new
43
- # Grammar from the resultant.
44
- #
45
- # @param file [String] the path of the grammar. This is
46
- # used for eval.
47
- # @param output [String] the output directory.
48
- # @param string [String] the grammar body.
49
- # @return [Grammar]
50
- # @see DSL::Compiler
51
- def from_dsl_string(file, output, string)
52
- eval(string, TOPLEVEL_BINDING, file, 0)
53
- grammar = Antelope.grammar
54
- compiler = DSL::Compiler.compile(grammar[1], &grammar[2])
55
- new(File.basename(file), output, compiler)
56
- end
57
-
58
- # Loads a grammar from a string. First runs the scanner and
59
- # compiler over the string, and then instantiates a new
60
- # Grammar from the resultant.
61
- #
62
- # @param name [String] the name of the grammar.
63
- # @param output [String] the output directory.
64
- # @param string [String] the grammar body.
65
- # @return [Grammar]
66
- # @see Ace::Scanner
67
- # @see Ace::Compiler
68
- def from_ace_string(name, output, string)
69
- scanner = Ace::Scanner.scan(string, name)
70
- compiler = Ace::Compiler.compile(scanner)
71
- new(name, output, compiler)
72
- end
73
- end
74
-
75
- # Extends the grammar with the class methods.
76
- #
77
- # @param receiver [Grammar]
78
- # @see ClassMethods
79
- def self.included(receiver)
80
- receiver.extend ClassMethods
81
- end
82
- end
83
- end
84
- end
1
+ # encoding: utf-8
2
+
3
+ module Antelope
4
+ class Grammar
5
+ # Handles loading to and from files and strings.
6
+ module Loading
7
+ # Defines class methods on the grammar.
8
+ module ClassMethods
9
+ # Loads a grammar from a file. Assumes the output
10
+ # directory and name from the file name.
11
+ #
12
+ # @param file_name [String] the file name.
13
+ # @return [Grammar]
14
+ # @see #from_string
15
+ def from_file(file_name)
16
+ ext = File.extname(file_name)
17
+ case ext
18
+ when ".rb", ".ate"
19
+ from_dsl_file(file_name)
20
+ when ".ace"
21
+ from_ace_file(file_name)
22
+ else
23
+ raise ArgumentError, "Unexpected file extension #{ext},"\
24
+ " expected one of .rb, .ate, or .ace"
25
+ end
26
+ end
27
+
28
+ def from_dsl_file(file_name)
29
+ body = File.read(file_name)
30
+ output = File.dirname(file_name)
31
+ from_dsl_string(file_name, output, body)
32
+ end
33
+
34
+ def from_ace_file(file_name)
35
+ body = File.read(file_name)
36
+ output = File.dirname(file_name)
37
+ name = File.basename(file_name)
38
+ from_ace_string(name, output, body)
39
+ end
40
+
41
+ # Loads a grammar from a string. First runs the scanner and
42
+ # compiler over the string, and then instantiates a new
43
+ # Grammar from the resultant.
44
+ #
45
+ # @param file [String] the path of the grammar. This is
46
+ # used for eval.
47
+ # @param output [String] the output directory.
48
+ # @param string [String] the grammar body.
49
+ # @return [Grammar]
50
+ # @see DSL::Compiler
51
+ def from_dsl_string(file, output, string)
52
+ eval(string, TOPLEVEL_BINDING, file, 0)
53
+ grammar = Antelope.grammar
54
+ compiler = DSL::Compiler.compile(grammar[1], &grammar[2])
55
+ new(File.basename(file), output, compiler)
56
+ end
57
+
58
+ # Loads a grammar from a string. First runs the scanner and
59
+ # compiler over the string, and then instantiates a new
60
+ # Grammar from the resultant.
61
+ #
62
+ # @param name [String] the name of the grammar.
63
+ # @param output [String] the output directory.
64
+ # @param string [String] the grammar body.
65
+ # @return [Grammar]
66
+ # @see Ace::Scanner
67
+ # @see Ace::Compiler
68
+ def from_ace_string(name, output, string)
69
+ scanner = Ace::Scanner.scan(string, name)
70
+ compiler = Ace::Compiler.compile(scanner)
71
+ new(name, output, compiler)
72
+ end
73
+ end
74
+
75
+ # Extends the grammar with the class methods.
76
+ #
77
+ # @param receiver [Grammar]
78
+ # @see ClassMethods
79
+ def self.included(receiver)
80
+ receiver.extend ClassMethods
81
+ end
82
+ end
83
+ end
84
+ end
@@ -1,59 +1,59 @@
1
- # encoding: utf-8
2
-
3
- module Antelope
4
- class Grammar
5
- # Defines a precedence. A precedence has a type, tokens, and a
6
- # level.
7
- Precedence = Struct.new(:type, :tokens, :level) do
8
- # @!attribute [rw] type
9
- # The type of precedence level. This should be one of
10
- # `:left`, `:right`, or `:nonassoc`.
11
- #
12
- # @return [Symbol] the type.
13
- # @!attribute [rw] tokens
14
- # An set of tokens that are on this specific precedence
15
- # level. The tokens are identified as symbols. The special
16
- # symbol, `:_`, represents any token.
17
- #
18
- # @return [Set<Symbol>] the tokens on this level.
19
- # @!attribute [rw] level
20
- # The level we're on. The higher the level, the higher the
21
- # precedence.
22
-
23
- include Comparable
24
-
25
- # Compares the other object to this object. If the other object
26
- # isn't a {Precedence}, it returns nil. If the other
27
- # precedence isn't on the same level as this one, then the
28
- # levels are compared and the result of that is returned. If
29
- # it is, however, the type is checked; if this precedence is
30
- # left associative, then it returns 1 (it is greater than the
31
- # other); if this precedence is right associative, then it
32
- # returns -1 (it is less than the other); if this precedence is
33
- # nonassociative, it returns 0 (it is equal to the other).
34
- #
35
- # @param other [Object] the object to compare to this one.
36
- # @return [Numeric?]
37
- def <=>(other)
38
- return nil unless other.is_a? Precedence
39
- if level != other.level
40
- level <=> other.level
41
- elsif type == :left
42
- 1
43
- elsif type == :right
44
- -1
45
- else
46
- 0
47
- end
48
- end
49
-
50
- # Converts the precedence into a representative string, denoting
51
- # the type and the level.
52
- #
53
- # @return [String]
54
- def to_s
55
- "#{type.to_s[0]}#{level}"
56
- end
57
- end
58
- end
59
- end
1
+ # encoding: utf-8
2
+
3
+ module Antelope
4
+ class Grammar
5
+ # Defines a precedence. A precedence has a type, tokens, and a
6
+ # level.
7
+ Precedence = Struct.new(:type, :tokens, :level) do
8
+ # @!attribute [rw] type
9
+ # The type of precedence level. This should be one of
10
+ # `:left`, `:right`, or `:nonassoc`.
11
+ #
12
+ # @return [Symbol] the type.
13
+ # @!attribute [rw] tokens
14
+ # An set of tokens that are on this specific precedence
15
+ # level. The tokens are identified as symbols. The special
16
+ # symbol, `:_`, represents any token.
17
+ #
18
+ # @return [Set<Symbol>] the tokens on this level.
19
+ # @!attribute [rw] level
20
+ # The level we're on. The higher the level, the higher the
21
+ # precedence.
22
+
23
+ include Comparable
24
+
25
+ # Compares the other object to this object. If the other object
26
+ # isn't a {Precedence}, it returns nil. If the other
27
+ # precedence isn't on the same level as this one, then the
28
+ # levels are compared and the result of that is returned. If
29
+ # it is, however, the type is checked; if this precedence is
30
+ # left associative, then it returns 1 (it is greater than the
31
+ # other); if this precedence is right associative, then it
32
+ # returns -1 (it is less than the other); if this precedence is
33
+ # nonassociative, it returns 0 (it is equal to the other).
34
+ #
35
+ # @param other [Object] the object to compare to this one.
36
+ # @return [Numeric?]
37
+ def <=>(other)
38
+ return nil unless other.is_a? Precedence
39
+ if level != other.level
40
+ level <=> other.level
41
+ elsif type == :left
42
+ 1
43
+ elsif type == :right
44
+ -1
45
+ else
46
+ 0
47
+ end
48
+ end
49
+
50
+ # Converts the precedence into a representative string, denoting
51
+ # the type and the level.
52
+ #
53
+ # @return [String]
54
+ def to_s
55
+ "#{type.to_s[0]}#{level}"
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,64 +1,64 @@
1
- # encoding: utf-8
2
-
3
- require "set"
4
-
5
- module Antelope
6
- class Grammar
7
- # Manages precedence for tokens.
8
- module Precedences
9
- # Accesses the generated precedence list. Lazily generates
10
- # the precedence rules on the go, and then caches it.
11
- #
12
- # @return [Array<Ace::Precedence>]
13
- def precedence
14
- @_precedence ||= generate_precedence
15
- end
16
-
17
- # Finds a precedence rule for a given token. If no direct
18
- # rule is defined for that token, it will check for a rule
19
- # defined for the special symbol, `:_`. By default, there
20
- # is always a rule defined for `:_`.
21
- #
22
- # @param token [Ace::Token, Symbol]
23
- # @return [Ace::Precedence]
24
- def precedence_for(token)
25
- token = token.name if token.is_a?(Token)
26
-
27
- prec = precedence.
28
- detect { |pr| pr.tokens.include?(token) } ||
29
- precedence.
30
- detect { |pr| pr.tokens.include?(:_) }
31
-
32
- prec
33
- end
34
-
35
- private
36
-
37
- # Generates the precedence rules. Loops through the compiler
38
- # given precedence settings, and then adds two default
39
- # precedence rules; one for `:$` (level 0, nonassoc), and one
40
- # for `:_` (level 1, nonassoc).
41
- #
42
- # @return [Array<Ace::Precedence>]
43
- def generate_precedence
44
- size = @compiler.options[:prec].size + 1
45
- index = 0
46
- precedence = []
47
-
48
- while index < size - 1
49
- prec = @compiler.options[:prec][index]
50
- precedence <<
51
- Precedence.new(prec[0], prec[1..-1].to_set,
52
- size - index)
53
- index += 1
54
- end
55
-
56
- precedence <<
57
- Precedence.new(:nonassoc, [:$end].to_set, 0) <<
58
- Precedence.new(:nonassoc, [:_].to_set, 1)
59
- precedence.sort_by(&:level).reverse
60
- end
61
-
62
- end
63
- end
64
- end
1
+ # encoding: utf-8
2
+
3
+ require "set"
4
+
5
+ module Antelope
6
+ class Grammar
7
+ # Manages precedence for tokens.
8
+ module Precedences
9
+ # Accesses the generated precedence list. Lazily generates
10
+ # the precedence rules on the go, and then caches it.
11
+ #
12
+ # @return [Array<Ace::Precedence>]
13
+ def precedence
14
+ @_precedence ||= generate_precedence
15
+ end
16
+
17
+ # Finds a precedence rule for a given token. If no direct
18
+ # rule is defined for that token, it will check for a rule
19
+ # defined for the special symbol, `:_`. By default, there
20
+ # is always a rule defined for `:_`.
21
+ #
22
+ # @param token [Ace::Token, Symbol]
23
+ # @return [Ace::Precedence]
24
+ def precedence_for(token)
25
+ token = token.name if token.is_a?(Token)
26
+
27
+ prec = precedence.
28
+ detect { |pr| pr.tokens.include?(token) } ||
29
+ precedence.
30
+ detect { |pr| pr.tokens.include?(:_) }
31
+
32
+ prec
33
+ end
34
+
35
+ private
36
+
37
+ # Generates the precedence rules. Loops through the compiler
38
+ # given precedence settings, and then adds two default
39
+ # precedence rules; one for `:$` (level 0, nonassoc), and one
40
+ # for `:_` (level 1, nonassoc).
41
+ #
42
+ # @return [Array<Ace::Precedence>]
43
+ def generate_precedence
44
+ size = @compiler.options[:prec].size + 1
45
+ index = 0
46
+ precedence = []
47
+
48
+ while index < size - 1
49
+ prec = @compiler.options[:prec][index]
50
+ precedence <<
51
+ Precedence.new(prec[0], prec[1..-1].to_set,
52
+ size - index)
53
+ index += 1
54
+ end
55
+
56
+ precedence <<
57
+ Precedence.new(:nonassoc, [:$end].to_set, 0) <<
58
+ Precedence.new(:nonassoc, [:_].to_set, 1)
59
+ precedence.sort_by(&:level).reverse
60
+ end
61
+
62
+ end
63
+ end
64
+ end
@@ -1,56 +1,56 @@
1
- # encoding: utf-8
2
-
3
- module Antelope
4
- class Grammar
5
- # Defines a production.
6
- Production = Struct.new(:label, :items, :block, :prec, :id) do
7
- # @!attribute [rw] label
8
- # The label (or left-hand side) of the production. This
9
- # should be a nonterminal.
10
- #
11
- # @return [Symbol]
12
- # @!attribute [rw] items
13
- # The body (or right-hand side) of the production. This can
14
- # be array of terminals and nonterminals.
15
- #
16
- # @return [Array<Token>]
17
- # @!attribute [rw] block
18
- # The block of code to be executed when the production's right
19
- # hand side is reduced.
20
- #
21
- # @return [String]
22
- # @!attribute [rw] prec
23
- # The precedence declaration for the production.
24
- #
25
- # @return [Ace::Precedence]
26
- # @!attribute [rw] id
27
- # The ID of the production. The starting production always
28
- # has an ID of 0.
29
- #
30
- # @return [Numeric]
31
-
32
- # Creates a new production from a hash. The hash's keys
33
- # correspond to the attributes on this class.
34
- #
35
- # @param hash [Hash<(Symbol, Object)>]
36
- def self.from_hash(hash)
37
- new(hash[:label] || hash['label'],
38
- hash[:items] || hash['items'],
39
- hash[:block] || hash['block'],
40
- hash[:prec] || hash['prec'],
41
- hash[:id] || hash['id'])
42
- end
43
-
44
- # Create a new version of the production with duplicated values.
45
- #
46
- # @return [Production]
47
- def clone
48
- Production.new(label.dup,
49
- items.map(&:dup),
50
- block.dup,
51
- prec.dup,
52
- id)
53
- end
54
- end
55
- end
56
- end
1
+ # encoding: utf-8
2
+
3
+ module Antelope
4
+ class Grammar
5
+ # Defines a production.
6
+ Production = Struct.new(:label, :items, :block, :prec, :id) do
7
+ # @!attribute [rw] label
8
+ # The label (or left-hand side) of the production. This
9
+ # should be a nonterminal.
10
+ #
11
+ # @return [Symbol]
12
+ # @!attribute [rw] items
13
+ # The body (or right-hand side) of the production. This can
14
+ # be array of terminals and nonterminals.
15
+ #
16
+ # @return [Array<Token>]
17
+ # @!attribute [rw] block
18
+ # The block of code to be executed when the production's right
19
+ # hand side is reduced.
20
+ #
21
+ # @return [String]
22
+ # @!attribute [rw] prec
23
+ # The precedence declaration for the production.
24
+ #
25
+ # @return [Ace::Precedence]
26
+ # @!attribute [rw] id
27
+ # The ID of the production. The starting production always
28
+ # has an ID of 0.
29
+ #
30
+ # @return [Numeric]
31
+
32
+ # Creates a new production from a hash. The hash's keys
33
+ # correspond to the attributes on this class.
34
+ #
35
+ # @param hash [Hash<(Symbol, Object)>]
36
+ def self.from_hash(hash)
37
+ new(hash[:label] || hash['label'],
38
+ hash[:items] || hash['items'],
39
+ hash[:block] || hash['block'],
40
+ hash[:prec] || hash['prec'],
41
+ hash[:id] || hash['id'])
42
+ end
43
+
44
+ # Create a new version of the production with duplicated values.
45
+ #
46
+ # @return [Production]
47
+ def clone
48
+ Production.new(label.dup,
49
+ items.map(&:dup),
50
+ block.dup,
51
+ prec.dup,
52
+ id)
53
+ end
54
+ end
55
+ end
56
+ end