whittle 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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