antelope 0.1.4 → 0.1.5

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.
@@ -1,10 +1,19 @@
1
1
  Productions:
2
- el "=" r
3
- e → r
4
- lIDENT
5
- l → "*" r
6
- rl
7
- $starte $
2
+ 0 $start(0) e(0:1) $
3
+ 1 e(0:1)l(0:2) "=" r(7:10)
4
+ 2 e(0:1) r(0:3)
5
+ 3 l(0:2)IDENT
6
+ 4 l(0:2) "*" r(5:8)
7
+ 5 r(0:3) l(0:2)
8
+ 5 r(5:8) → l(5:9)
9
+ 3 l(5:9) → IDENT
10
+ 4 l(5:9) → "*" r(5:8)
11
+ 5 r(7:10) → l(7:9)
12
+ 3 l(7:9) → IDENT
13
+ 4 l(7:9) → "*" r(5:8)
14
+
15
+ Nontemrinals:
16
+ ["$start(0)", "e(0:1)", "l(0:2)", "r(0:3)", "r(5:8)", "l(5:9)", "r(7:10)", "l(7:9)"]
8
17
 
9
18
  Precedence:
10
19
  --- highest
@@ -15,18 +24,18 @@ Precedence:
15
24
  --- lowest
16
25
 
17
26
  State 0:
18
- 0/n0: $start(0) → • e(0:1) $
19
- {}
20
- 1/n1: e(0:1) → • l(0:2) "=" r(8:10)
21
- {}
22
- 2/n1: e(0:1) → • r(0:3)
23
- {}
24
- 3/n1: l(0:2) → • IDENT
25
- {}
26
- 4/n1: l(0:2) → • "*" r(5:9)
27
- {}
28
- 5/n1: r(0:3) → • l(0:2)
29
- {}
27
+ 0/n0: $start → • e $
28
+ {} ($start)
29
+ 1/n1: e → • l "=" r
30
+ {} (e)
31
+ 2/n1: e → • r
32
+ {} (e)
33
+ 3/n1: l → • IDENT
34
+ {} (l)
35
+ 4/n1: l → • "*" r
36
+ {} (l)
37
+ 5/n1: r → • l
38
+ {} (r)
30
39
  transitions:
31
40
  e: State 1
32
41
  l: State 2
@@ -36,83 +45,86 @@ Precedence:
36
45
 
37
46
  State 1:
38
47
  6/n0: $start → e • $
39
- {}
48
+ {} ($start)
40
49
  transitions:
41
- $: State 7
50
+ $: State 6
42
51
 
43
52
  State 2:
44
53
  7/n1: e → l • "=" r
45
- {}
46
- 15/n1: r → l •
47
- {$}
54
+ {} (e)
55
+ 8/n1: r → l •
56
+ {$} (r)
48
57
  transitions:
49
- EQUALS: State 8
58
+ EQUALS: State 7
50
59
  reductions:
51
60
  $: Rule 5
52
61
 
53
62
  State 3:
54
63
  9/n1: e → r •
55
- {$}
64
+ {$} (e)
56
65
  reductions:
57
66
  $: Rule 2
58
67
 
59
68
  State 4:
60
69
  10/n1: l → IDENT •
61
- {$}
70
+ {"=", $} (l)
62
71
  reductions:
72
+ EQUALS: Rule 3
63
73
  $: Rule 3
64
74
 
65
75
  State 5:
66
76
  11/n1: l → "*" • r
67
- {}
68
- 12/n1: r(5:9) → • l(5:6)
69
- {}
70
- 13/n1: l(5:6) → • IDENT
71
- {}
72
- 14/n1: l(5:6) → • "*" r(5:9)
73
- {}
77
+ {} (l)
78
+ 12/n1: r → • l
79
+ {} (r)
80
+ 13/n1: l → • IDENT
81
+ {} (l)
82
+ 14/n1: l → • "*" r
83
+ {} (l)
74
84
  transitions:
75
- r: State 9
76
- l: State 6
85
+ r: State 8
86
+ l: State 9
77
87
  IDENT: State 4
78
88
  STAR: State 5
79
89
 
80
90
  State 6:
81
- 15/n1: rl
82
- {$}
83
- reductions:
84
- $: Rule 5
85
-
86
- State 7:
87
- 16/n0: $start → e $ •
88
- {}
91
+ 15/n0: $starte $
92
+ {} ($start)
89
93
  accepting:
90
94
  $: Rule 0
91
95
 
92
- State 8:
93
- 17/n1: e → l "=" • r
94
- {}
95
- 18/n1: r(8:10) → • l(8:6)
96
- {}
97
- 19/n1: l(8:6) → • IDENT
98
- {}
99
- 20/n1: l(8:6) → • "*" r(5:9)
100
- {}
96
+ State 7:
97
+ 16/n1: e → l "=" • r
98
+ {} (e)
99
+ 17/n1: r → • l
100
+ {} (r)
101
+ 18/n1: l → • IDENT
102
+ {} (l)
103
+ 19/n1: l → • "*" r
104
+ {} (l)
101
105
  transitions:
102
106
  r: State 10
103
- l: State 6
107
+ l: State 9
104
108
  IDENT: State 4
105
109
  STAR: State 5
106
110
 
107
- State 9:
108
- 21/n1: l → "*" r •
109
- {$}
111
+ State 8:
112
+ 20/n1: l → "*" r •
113
+ {"=", $} (l)
110
114
  reductions:
115
+ EQUALS: Rule 4
111
116
  $: Rule 4
112
117
 
118
+ State 9:
119
+ 21/n1: r → l •
120
+ {"=", $} (r)
121
+ reductions:
122
+ EQUALS: Rule 5
123
+ $: Rule 5
124
+
113
125
  State 10:
114
126
  22/n1: e → l "=" r •
115
- {$}
127
+ {$} (e)
116
128
  reductions:
117
129
  $: Rule 1
118
130
 
@@ -5,7 +5,6 @@ require "antelope/ace/grammar/productions"
5
5
  require "antelope/ace/grammar/precedences"
6
6
  require "antelope/ace/grammar/loading"
7
7
  require "antelope/ace/grammar/generation"
8
- require "antelope/ace/grammar/production"
9
8
 
10
9
  module Antelope
11
10
  module Ace
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+
3
+ module Antelope
4
+ module Ace
5
+
6
+ # Defines a production.
7
+ class Production < Struct.new(:label, :items, :block, :prec, :id)
8
+ # @!attribute [rw] label
9
+ # The label (or left-hand side) of the production. This
10
+ # should be a nonterminal.
11
+ #
12
+ # @return [Symbol]
13
+ # @!attribute [rw] items
14
+ # The body (or right-hand side) of the production. This can
15
+ # be array of terminals and nonterminals.
16
+ #
17
+ # @return [Array<Token>]
18
+ # @!attribute [rw] block
19
+ # The block of code to be executed when the production's right
20
+ # hand side is reduced.
21
+ #
22
+ # @return [String]
23
+ # @!attribute [rw] prec
24
+ # The precedence declaration for the production.
25
+ #
26
+ # @return [Ace::Precedence]
27
+ # @!attribute [rw] id
28
+ # The ID of the production. The starting production always
29
+ # has an ID of 0.
30
+ #
31
+ # @return [Numeric]
32
+
33
+ # Creates a new production from a hash. The hash's keys
34
+ # correspond to the attributes on this class.
35
+ #
36
+ # @param hash [Hash<(Symbol, Object)>]
37
+ def self.from_hash(hash)
38
+ new(hash[:label] || hash["label"],
39
+ hash[:items] || hash["items"],
40
+ hash[:block] || hash["block"],
41
+ hash[:prec] || hash["prec"],
42
+ hash[:id] || hash["id"])
43
+ end
44
+
45
+ # Create a new version of the production with duplicated values.
46
+ #
47
+ # @return [Production]
48
+ def clone
49
+ Production.new(label.dup,
50
+ items.map(&:dup),
51
+ block.dup,
52
+ prec.dup,
53
+ id)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -110,6 +110,11 @@ module Antelope
110
110
  buf
111
111
  end
112
112
 
113
+ def inspect
114
+ "#<#{self.class} from=#{from.id if from} to=#{to.id if to} " \
115
+ "name=#{name.inspect} value=#{@value.inspect}>"
116
+ end
117
+
113
118
  # Compares this class to any other object. If the other object
114
119
  # is a token, it converts both this class and the other object
115
120
  # to an array and compares the array. Otherwise, it delegates
data/lib/antelope/ace.rb CHANGED
@@ -5,6 +5,7 @@ require "antelope/ace/scanner"
5
5
  require "antelope/ace/compiler"
6
6
  require "antelope/ace/token"
7
7
  require "antelope/ace/precedence"
8
+ require "antelope/ace/production"
8
9
  require "antelope/ace/grammar"
9
10
 
10
11
  module Antelope
@@ -68,16 +68,10 @@ module Antelope
68
68
  # @see Nullable#nullable?
69
69
  def generate_follow_set(token)
70
70
  # Set it to the empty set so we don't end up recursing.
71
- @follows[token] = Set.new
72
-
73
- # This is going to be the output set.
74
- set = Set.new
75
-
76
- productions = grammar.states.map(&:rules).flatten.
77
- inject(Set.new, :merge)
71
+ set = @follows[token] = Set.new
78
72
 
79
73
  productions.each do |rule|
80
- items = rule.right
74
+ items = rule.items
81
75
 
82
76
  # Find all of the positions within the rule that our token
83
77
  # occurs, and then increment that position by one.
@@ -95,7 +89,7 @@ module Antelope
95
89
  if pos == items.size || nullable?(items[pos..-1])
96
90
  # Then add the FOLLOW set of the left-hand side to our
97
91
  # set.
98
- set.merge follow(rule.left)
92
+ set.merge follow(rule.label)
99
93
  end
100
94
  end
101
95
  end
@@ -21,6 +21,9 @@ module Antelope
21
21
  # @return [Ace::Grammar]
22
22
  attr_reader :grammar
23
23
 
24
+ # The augmented productions generated by the constructor.
25
+ #
26
+ # @return [Set<Ace::Production>]
24
27
  attr_reader :productions
25
28
 
26
29
  # Initialize.
@@ -56,22 +59,29 @@ module Antelope
56
59
  # @return [void]
57
60
  def augment_state(state)
58
61
  state.rules.select { |x| x.position.zero? }.each do |rule|
62
+ production = rule.production.clone
63
+ production.items = []
64
+
59
65
  current_state = state
60
66
 
61
- rule.left.from = state
62
- rule.left.to = state.transitions[rule.left.name]
67
+ production.label.from = state
68
+ production.label.to = state.transitions[rule.left.name]
63
69
 
64
70
  rule.right.each_with_index do |part, pos|
65
71
  transition = current_state.transitions[part.name]
72
+ new_item = part.dup
73
+
66
74
  if part.nonterminal?
67
- part.from = current_state
68
- part.to = transition
75
+ new_item.from = current_state
76
+ new_item.to = transition
69
77
  end
70
78
 
79
+ production.items << new_item
80
+
71
81
  current_state = transition
72
82
  end
73
83
 
74
- productions << rule
84
+ productions << production
75
85
  end
76
86
  end
77
87
 
@@ -88,6 +98,10 @@ module Antelope
88
98
  state.rules.select { |x| x.position.zero? }.each do |rule|
89
99
  current_state = state
90
100
 
101
+ label = rule.left.dup
102
+ label.from = state
103
+ label.to = state.transitions[label.name]
104
+
91
105
  rule.right.each do |part|
92
106
  transition = current_state.transitions[part.name]
93
107
  current_state = transition
@@ -95,7 +109,8 @@ module Antelope
95
109
 
96
110
  final = current_state.rule_for(rule)
97
111
 
98
- final.lookahead = follow(rule.left)
112
+ final.lookahead = Set.new unless final.lookahead
113
+ final.lookahead.merge follow(label)
99
114
  end
100
115
  end
101
116
 
@@ -18,8 +18,8 @@ module Antelope
18
18
 
19
19
  # The right-hand side of the rule.
20
20
  #
21
- # @return [Ace::Token]
22
- attr_reader :right
21
+ # @return [Array<Ace::Token>]
22
+ attr_accessor :right
23
23
 
24
24
  # The current position inside of the rule.
25
25
  #
@@ -28,7 +28,7 @@ module Antelope
28
28
 
29
29
  # The block to be executed on production match.
30
30
  #
31
- # @deprecated Use {Ace::Grammar::Production#block} instead.
31
+ # @deprecated Use {Ace::Production#block} instead.
32
32
  # @return [String]
33
33
  attr_reader :block
34
34
 
@@ -52,14 +52,14 @@ module Antelope
52
52
 
53
53
  # The associated production.
54
54
  #
55
- # @return [Ace::Grammar::Production]
55
+ # @return [Ace::Production]
56
56
  attr_reader :production
57
57
 
58
58
  include Comparable
59
59
 
60
60
  # Initialize the rule.
61
61
  #
62
- # @param production [Ace::Grammar::Production] the production
62
+ # @param production [Ace::Production] the production
63
63
  # that this rule is based off of.
64
64
  # @param position [Numeric] the position that this rule is in
65
65
  # the production.
@@ -74,9 +74,9 @@ module Antelope
74
74
  @id = SecureRandom.hex
75
75
 
76
76
  if inherited
77
- @right = inherited
77
+ @left, @right = inherited
78
78
  else
79
- @right = production.items.map(&:dup).freeze
79
+ @right = production.items.map(&:dup)
80
80
  end
81
81
  end
82
82
 
@@ -115,7 +115,7 @@ module Antelope
115
115
  #
116
116
  # @return [Rule]
117
117
  def succ
118
- Rule.new(production, position + 1)
118
+ Rule.new(production, position + 1, [left, right])
119
119
  end
120
120
 
121
121
  # Checks to see if a rule can exist after this one; i.e. the
@@ -175,6 +175,15 @@ module Antelope
175
175
  end
176
176
  end
177
177
 
178
+ # Produces a clone of the rule; any modifications made to the
179
+ # contents of that rule do not reflect the contents of this
180
+ # rule.
181
+ #
182
+ # @return [Rule]
183
+ def clone
184
+ Rule.new(production, position)
185
+ end
186
+
178
187
  # Generates a hash for this class.
179
188
  #
180
189
  # @note This is not intended for use. It is only defined to be
@@ -194,7 +203,7 @@ module Antelope
194
203
  # @private
195
204
  # @return [Array<(Ace::Token::Nonterminal, Array<Ace::Token>, Numeric)>]
196
205
  def to_a
197
- [left, right, position]
206
+ [left, right, position].flatten
198
207
  end
199
208
  end
200
209
  end
@@ -87,7 +87,7 @@ module Antelope
87
87
  # @return [self]
88
88
  def <<(rule)
89
89
  if rule.is_a? State
90
- rule.rules.each { |r| self << r }
90
+ rule.rules.map(&:clone).each { |r| self << r }
91
91
  elsif rule.is_a? Rule
92
92
  rules << rule unless rules.include? rule
93
93
  else
@@ -100,6 +100,15 @@ module Antelope
100
100
 
101
101
  alias_method :push, :<<
102
102
 
103
+ def ===(other)
104
+ return super unless other.is_a? State
105
+
106
+ other_rules = other.rules.to_a
107
+ other.transitions == transitions and
108
+ rules.each_with_index.
109
+ all? { |rule, i| rule === other_rules[i] }
110
+ end
111
+
103
112
  end
104
113
  end
105
114
  end
@@ -93,17 +93,15 @@ module Antelope
93
93
  state.rules.each do |rule|
94
94
  next unless rule.succ?
95
95
  transitional = find_state_for(rule.succ) do |succ|
96
- ns = State.new
97
- ns << succ
96
+ ns = State.new << succ
98
97
  compute_closure(ns)
99
- states << ns
100
98
  @map[succ] = ns
101
- ns
102
99
  end
103
100
 
104
101
  if state.transitions[rule.active.name]
105
102
  state.transitions[rule.active.name].merge! transitional
106
103
  else
104
+ states << transitional
107
105
  state.transitions[rule.active.name] = transitional
108
106
  end
109
107
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Antelope
4
4
  # The current running version of antelope.
5
- VERSION = "0.1.4".freeze
5
+ VERSION = "0.1.5".freeze
6
6
  end
@@ -111,6 +111,10 @@ describe Generation::Constructor do
111
111
  let(:grammar) { with_recognizer }
112
112
  let(:nonterminal) { token(:l, nil, :nonterminal) }
113
113
 
114
+ before do
115
+ subject.productions.merge grammar.productions.values.flatten
116
+ end
117
+
114
118
  it "generates a set" do
115
119
  expect(subject.follow(nonterminal)).to eq [
116
120
  token(:EQUALS, "="),
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: antelope
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Rodi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-23 00:00:00.000000000 Z
11
+ date: 2014-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -126,10 +126,10 @@ files:
126
126
  - lib/antelope/ace/grammar/generation.rb
127
127
  - lib/antelope/ace/grammar/loading.rb
128
128
  - lib/antelope/ace/grammar/precedences.rb
129
- - lib/antelope/ace/grammar/production.rb
130
129
  - lib/antelope/ace/grammar/productions.rb
131
130
  - lib/antelope/ace/grammar/terminals.rb
132
131
  - lib/antelope/ace/precedence.rb
132
+ - lib/antelope/ace/production.rb
133
133
  - lib/antelope/ace/scanner.rb
134
134
  - lib/antelope/ace/scanner/first.rb
135
135
  - lib/antelope/ace/scanner/second.rb
@@ -1,48 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Antelope
4
- module Ace
5
- class Grammar
6
-
7
- # Defines a production.
8
- class Production < Struct.new(:label, :items, :block, :prec, :id)
9
- # @!attribute [rw] label
10
- # The label (or left-hand side) of the production. This
11
- # should be a nonterminal.
12
- #
13
- # @return [Symbol]
14
- # @!attribute [rw] items
15
- # The body (or right-hand side) of the production. This can
16
- # be array of terminals and nonterminals.
17
- #
18
- # @return [Array<Token>]
19
- # @!attribute [rw] block
20
- # The block of code to be executed when the production's right
21
- # hand side is reduced.
22
- #
23
- # @return [String]
24
- # @!attribute [rw] prec
25
- # The precedence declaration for the production.
26
- #
27
- # @return [Ace::Precedence]
28
- # @!attribute [rw] id
29
- # The ID of the production. The starting production always
30
- # has an ID of 0.
31
- #
32
- # @return [Numeric]
33
-
34
- # Creates a new production from a hash. The hash's keys
35
- # correspond to the attributes on this class.
36
- #
37
- # @param hash [Hash<(Symbol, Object)>]
38
- def self.from_hash(hash)
39
- new(hash[:label] || hash["label"],
40
- hash[:items] || hash["items"],
41
- hash[:block] || hash["block"],
42
- hash[:prec] || hash["prec"],
43
- hash[:id] || hash["id"])
44
- end
45
- end
46
- end
47
- end
48
- end