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