whittle 0.0.4 → 0.0.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.
data/lib/whittle/rule.rb CHANGED
@@ -83,6 +83,8 @@ module Whittle
83
83
  end || [self, new_offset].hash
84
84
 
85
85
  if sym.nil?
86
+ assert_reducable!(state, sym)
87
+
86
88
  state[sym] = {
87
89
  :action => :reduce,
88
90
  :rule => self,
@@ -252,5 +254,19 @@ module Whittle
252
254
  end
253
255
  end
254
256
  end
257
+
258
+ def assert_reducable!(instructions, sym)
259
+ if instructions.key?(sym) && !instructions[sym][:rule].equal?(self)
260
+ message = <<-END.gsub(/(^|$)\s+/m, " ")
261
+ Unresolvable conflict found between rules
262
+ `#{name.inspect} := #{components.inspect}`
263
+ and
264
+ `#{instructions[sym][:rule].name.inspect} := #{instructions[sym][:rule].components.inspect}`
265
+ (restructure your grammar to prevent this)
266
+ END
267
+
268
+ raise GrammarError, message
269
+ end
270
+ end
255
271
  end
256
272
  end
@@ -3,5 +3,5 @@
3
3
  # Copyright (c) Chris Corbyn, 2011
4
4
 
5
5
  module Whittle
6
- VERSION = "0.0.4"
6
+ VERSION = "0.0.5"
7
7
  end
@@ -0,0 +1,36 @@
1
+ require "spec_helper"
2
+
3
+ describe "a parser with a reduce-reduce conflict" do
4
+ let(:parser) do
5
+ Class.new(Whittle::Parser) do
6
+ rule(:wsp => /\s+/).skip!
7
+
8
+ rule(:id => /[a-z]+/)
9
+
10
+ rule(:list) do |r|
11
+ r[:list, :id]
12
+ r[:id]
13
+ end
14
+
15
+ rule(:prog) do |r|
16
+ r[:list]
17
+ r[:id] # <- conflicts with :list := [:id]
18
+ end
19
+
20
+ start(:prog)
21
+ end
22
+ end
23
+
24
+ it "raises a GrammarError" do
25
+ expect { parser.new.parse("a b") }.to raise_error(Whittle::GrammarError)
26
+ end
27
+
28
+ it "specifies the rules that conflict" do
29
+ begin
30
+ parser.new.parse("a b")
31
+ rescue Whittle::GrammarError => e
32
+ e.message.should =~ /:prog := \[:id\]/
33
+ e.message.should =~ /:list := \[:id\]/
34
+ end
35
+ end
36
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: whittle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-30 00:00:00.000000000 Z
12
+ date: 2011-12-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70302063205940 !ruby/object:Gem::Requirement
16
+ requirement: &70134349797920 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '2.6'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70302063205940
24
+ version_requirements: *70134349797920
25
25
  description: ! "Write powerful parsers by defining a series of very simple rules\n
26
26
  \ and operations to perform as those rules are matched. Whittle\n
27
27
  \ parsers are written in pure ruby and as such are extremely
@@ -60,6 +60,7 @@ files:
60
60
  - spec/unit/parser/pass_through_parser_spec.rb
61
61
  - spec/unit/parser/precedence_spec.rb
62
62
  - spec/unit/parser/premature_eof_spec.rb
63
+ - spec/unit/parser/reduce_reduce_conflict_spec.rb
63
64
  - spec/unit/parser/self_referential_expr_spec.rb
64
65
  - spec/unit/parser/skipped_tokens_spec.rb
65
66
  - spec/unit/parser/sum_parser_spec.rb
@@ -101,6 +102,7 @@ test_files:
101
102
  - spec/unit/parser/pass_through_parser_spec.rb
102
103
  - spec/unit/parser/precedence_spec.rb
103
104
  - spec/unit/parser/premature_eof_spec.rb
105
+ - spec/unit/parser/reduce_reduce_conflict_spec.rb
104
106
  - spec/unit/parser/self_referential_expr_spec.rb
105
107
  - spec/unit/parser/skipped_tokens_spec.rb
106
108
  - spec/unit/parser/sum_parser_spec.rb