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,64 +1,64 @@
1
- # encoding: utf-8
2
-
3
- module Antelope
4
- module Generation
5
- class Constructor
6
-
7
- # Contains the methods to determine if an object is nullable.
8
- module Nullable
9
-
10
- # Initialize.
11
- def initialize
12
- @nullifying = Set.new
13
- end
14
-
15
- # Determine if a given token is nullable. This is how the
16
- # method should behave:
17
- #
18
- # nullable?(ϵ) == true # if ϵ is the epsilon token
19
- # nullable?(x) == false # if x is a terminal
20
- # nullable?(αβ) == nullable?(α) && nullable?(β)
21
- # nullable?(A) == nullable?(a_1) || nullable?(a_2) || ... nullable?(a_n)
22
- # # if A is a nonterminal and a_1, a_2, ..., a_n are all
23
- # # of the right-hand sides of its productions
24
- #
25
- # @param token [Ace::Token, Array<Ace::Token>] the token to
26
- # check.
27
- # @return [Boolean] if the token can reduce to ϵ.
28
- def nullable?(token)
29
- case token
30
- when Ace::Token::Nonterminal
31
- nullifying(token) do
32
- productions = grammar.productions[token.name]
33
- !!productions.any? { |prod| nullable?(prod[:items]) }
34
- end
35
- when Array
36
- token.dup.delete_if { |tok|
37
- @nullifying.include?(tok) }.all? { |tok| nullable?(tok) }
38
- when Ace::Token::Epsilon
39
- true
40
- when Ace::Token::Terminal
41
- false
42
- else
43
- incorrect_argument! token, Ace::Token, Array
44
- end
45
- end
46
-
47
- private
48
-
49
- # Helps keep track of the nonterminals we're checking for
50
- # nullability. This helps prevent recursion.
51
- #
52
- # @param tok [Ace::Token::Nonterminal]
53
- # @yield once.
54
- # @return [Boolean]
55
- def nullifying(tok)
56
- @nullifying << tok
57
- out = yield
58
- @nullifying.delete tok
59
- out
60
- end
61
- end
62
- end
63
- end
64
- end
1
+ # encoding: utf-8
2
+
3
+ module Antelope
4
+ module Generation
5
+ class Constructor
6
+
7
+ # Contains the methods to determine if an object is nullable.
8
+ module Nullable
9
+
10
+ # Initialize.
11
+ def initialize
12
+ @nullifying = Set.new
13
+ end
14
+
15
+ # Determine if a given token is nullable. This is how the
16
+ # method should behave:
17
+ #
18
+ # nullable?(ϵ) == true # if ϵ is the epsilon token
19
+ # nullable?(x) == false # if x is a terminal
20
+ # nullable?(αβ) == nullable?(α) && nullable?(β)
21
+ # nullable?(A) == nullable?(a_1) || nullable?(a_2) || ... nullable?(a_n)
22
+ # # if A is a nonterminal and a_1, a_2, ..., a_n are all
23
+ # # of the right-hand sides of its productions
24
+ #
25
+ # @param token [Ace::Token, Array<Ace::Token>] the token to
26
+ # check.
27
+ # @return [Boolean] if the token can reduce to ϵ.
28
+ def nullable?(token)
29
+ case token
30
+ when Ace::Token::Nonterminal
31
+ nullifying(token) do
32
+ productions = grammar.productions[token.name]
33
+ !!productions.any? { |prod| nullable?(prod[:items]) }
34
+ end
35
+ when Array
36
+ token.dup.delete_if { |tok|
37
+ @nullifying.include?(tok) }.all? { |tok| nullable?(tok) }
38
+ when Ace::Token::Epsilon
39
+ true
40
+ when Ace::Token::Terminal
41
+ false
42
+ else
43
+ incorrect_argument! token, Ace::Token, Array
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ # Helps keep track of the nonterminals we're checking for
50
+ # nullability. This helps prevent recursion.
51
+ #
52
+ # @param tok [Ace::Token::Nonterminal]
53
+ # @yield once.
54
+ # @return [Boolean]
55
+ def nullifying(tok)
56
+ @nullifying << tok
57
+ out = yield
58
+ @nullifying.delete tok
59
+ out
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,126 +1,126 @@
1
- # encoding: utf-8
2
-
3
- require "set"
4
- require "antelope/generation/constructor/nullable"
5
- require "antelope/generation/constructor/first"
6
- require "antelope/generation/constructor/follow"
7
-
8
- module Antelope
9
- module Generation
10
-
11
- # Constructs the lookahead sets for all of the rules in the
12
- # grammar.
13
- class Constructor
14
-
15
- include Nullable
16
- include First
17
- include Follow
18
-
19
- # The grammar.
20
- #
21
- # @return [Ace::Grammar]
22
- attr_reader :grammar
23
-
24
- # The augmented productions generated by the constructor.
25
- #
26
- # @return [Set<Ace::Production>]
27
- attr_reader :productions
28
-
29
- # Initialize.
30
- #
31
- # @param grammar [Ace::Grammar] the grammar.
32
- def initialize(grammar)
33
- @productions = Set.new
34
- @grammar = grammar
35
- super()
36
- end
37
-
38
- # Performs the construction. First, it goes through every state
39
- # and augments the state. It then goes through every rule and
40
- # augments it.
41
- #
42
- # @return [void]
43
- # @see #augment_state
44
- # @see #augment_rule
45
- def call
46
- grammar.states.each do |state|
47
- augment_state(state)
48
- end.each do |state|
49
- augment_rules(state)
50
- end
51
- end
52
-
53
- # Augments the given state. On every rule within that state
54
- # that has a position of zero, it follows the rule throughout
55
- # the DFA until the end; it marks every nonterminal it
56
- # encounters with the transitions it took on that nonterminal.
57
- #
58
- # @param state [Recognizer::State] the state to augment.
59
- # @return [void]
60
- def augment_state(state)
61
- state.rules.select { |x| x.position.zero? }.each do |rule|
62
- production = rule.production.clone
63
- production.items = []
64
-
65
- current_state = state
66
- old_state = state
67
-
68
- production.label.from = state
69
- production.label.to = state.transitions[rule.left.name]
70
-
71
- rule.right.each_with_index do |part, pos|
72
- transition = current_state.transitions[part.name]
73
- new_item = part.dup
74
-
75
- if part.nonterminal?
76
- new_item.from = current_state
77
- new_item.to = transition
78
- end
79
-
80
- production.items << new_item
81
-
82
- old_state = current_state
83
- current_state = transition
84
- end
85
-
86
- productions << production
87
- end
88
- end
89
-
90
- # Augments every final rule. For every rule in the current
91
- # state that has a position of zero, it follows the rule through
92
- # the DFA until the ending state; it then modifies the ending
93
- # state's lookahead set to be the FOLLOW set of the nonterminal
94
- # it reduces to.
95
- #
96
- # @param state [Recognizer::State]
97
- # @return [void]
98
- # @see Follow#follow
99
- def augment_rules(state)
100
- state.rules.select { |x| x.position.zero? }.each do |rule|
101
- current_state = state
102
-
103
- label = rule.left.dup
104
- label.from = state
105
- label.to = state.transitions[label.name]
106
-
107
- rule.right.each do |part|
108
- transition = current_state.transitions[part.name]
109
- current_state = transition
110
- end
111
-
112
- final = current_state.rule_for(rule)
113
-
114
- final.lookahead = Set.new unless final.lookahead
115
- final.lookahead.merge follow(label)
116
- end
117
- end
118
-
119
- private
120
-
121
- def incorrect_argument!(arg, *types)
122
- raise ArgumentError, "Expected one of #{types.join(", ")}, got #{arg.class}"
123
- end
124
- end
125
- end
126
- end
1
+ # encoding: utf-8
2
+
3
+ require "set"
4
+ require "antelope/generation/constructor/nullable"
5
+ require "antelope/generation/constructor/first"
6
+ require "antelope/generation/constructor/follow"
7
+
8
+ module Antelope
9
+ module Generation
10
+
11
+ # Constructs the lookahead sets for all of the rules in the
12
+ # grammar.
13
+ class Constructor
14
+
15
+ include Nullable
16
+ include First
17
+ include Follow
18
+
19
+ # The grammar.
20
+ #
21
+ # @return [Ace::Grammar]
22
+ attr_reader :grammar
23
+
24
+ # The augmented productions generated by the constructor.
25
+ #
26
+ # @return [Set<Ace::Production>]
27
+ attr_reader :productions
28
+
29
+ # Initialize.
30
+ #
31
+ # @param grammar [Ace::Grammar] the grammar.
32
+ def initialize(grammar)
33
+ @productions = Set.new
34
+ @grammar = grammar
35
+ super()
36
+ end
37
+
38
+ # Performs the construction. First, it goes through every state
39
+ # and augments the state. It then goes through every rule and
40
+ # augments it.
41
+ #
42
+ # @return [void]
43
+ # @see #augment_state
44
+ # @see #augment_rule
45
+ def call
46
+ grammar.states.each do |state|
47
+ augment_state(state)
48
+ end.each do |state|
49
+ augment_rules(state)
50
+ end
51
+ end
52
+
53
+ # Augments the given state. On every rule within that state
54
+ # that has a position of zero, it follows the rule throughout
55
+ # the DFA until the end; it marks every nonterminal it
56
+ # encounters with the transitions it took on that nonterminal.
57
+ #
58
+ # @param state [Recognizer::State] the state to augment.
59
+ # @return [void]
60
+ def augment_state(state)
61
+ state.rules.select { |x| x.position.zero? }.each do |rule|
62
+ production = rule.production.clone
63
+ production.items = []
64
+
65
+ current_state = state
66
+ old_state = state
67
+
68
+ production.label.from = state
69
+ production.label.to = state.transitions[rule.left.name]
70
+
71
+ rule.right.each_with_index do |part, pos|
72
+ transition = current_state.transitions[part.name]
73
+ new_item = part.dup
74
+
75
+ if part.nonterminal?
76
+ new_item.from = current_state
77
+ new_item.to = transition
78
+ end
79
+
80
+ production.items << new_item
81
+
82
+ old_state = current_state
83
+ current_state = transition
84
+ end
85
+
86
+ productions << production
87
+ end
88
+ end
89
+
90
+ # Augments every final rule. For every rule in the current
91
+ # state that has a position of zero, it follows the rule through
92
+ # the DFA until the ending state; it then modifies the ending
93
+ # state's lookahead set to be the FOLLOW set of the nonterminal
94
+ # it reduces to.
95
+ #
96
+ # @param state [Recognizer::State]
97
+ # @return [void]
98
+ # @see Follow#follow
99
+ def augment_rules(state)
100
+ state.rules.select { |x| x.position.zero? }.each do |rule|
101
+ current_state = state
102
+
103
+ label = rule.left.dup
104
+ label.from = state
105
+ label.to = state.transitions[label.name]
106
+
107
+ rule.right.each do |part|
108
+ transition = current_state.transitions[part.name]
109
+ current_state = transition
110
+ end
111
+
112
+ final = current_state.rule_for(rule)
113
+
114
+ final.lookahead = Set.new unless final.lookahead
115
+ final.lookahead.merge follow(label)
116
+ end
117
+ end
118
+
119
+ private
120
+
121
+ def incorrect_argument!(arg, *types)
122
+ raise ArgumentError, "Expected one of #{types.join(", ")}, got #{arg.class}"
123
+ end
124
+ end
125
+ end
126
+ end
@@ -1,17 +1,17 @@
1
- # encoding: utf-8
2
-
3
- module Antelope
4
- module Generation
5
-
6
- # Defines an error that can occur within the Generation module.
7
- # All errors that are raised within the Generation module are
8
- # subclasses of this.
9
- class Error < Antelope::Error
10
- end
11
-
12
- # Used mainly in the {Tableizer}, this is raised when a conflict
13
- # could not be resolved.
14
- class UnresolvableConflictError < Error
15
- end
16
- end
17
- end
1
+ # encoding: utf-8
2
+
3
+ module Antelope
4
+ module Generation
5
+
6
+ # Defines an error that can occur within the Generation module.
7
+ # All errors that are raised within the Generation module are
8
+ # subclasses of this.
9
+ class Error < Antelope::Error
10
+ end
11
+
12
+ # Used mainly in the {Tableizer}, this is raised when a conflict
13
+ # could not be resolved.
14
+ class UnresolvableConflictError < Error
15
+ end
16
+ end
17
+ end
@@ -1,13 +1,13 @@
1
- module Antelope
2
- module Generation
3
- class Null
4
-
5
-
6
- def initialize(*)
7
- end
8
-
9
- def call(*)
10
- end
11
- end
12
- end
13
- end
1
+ module Antelope
2
+ module Generation
3
+ class Null
4
+
5
+
6
+ def initialize(*)
7
+ end
8
+
9
+ def call(*)
10
+ end
11
+ end
12
+ end
13
+ end