neg 1.0.0 → 1.1.0

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.
@@ -2,6 +2,13 @@
2
2
  # neg - CHANGELOG.md
3
3
 
4
4
 
5
+ ## neg - 1.1.0 released 2013-02-28
6
+
7
+ - giving the "right" error on unconsumed input
8
+ - get rid of UnconsumedInputError
9
+ - translator: introduce n.flattened_results
10
+
11
+
5
12
  ## neg - 1.0.0 released 2013-01-16
6
13
 
7
14
  - initial release
data/README.md CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  # neg
3
2
 
4
3
  A neg narser.
@@ -30,11 +29,11 @@ Here is the classical arithmetic example:
30
29
 
31
30
  expression == operation
32
31
 
33
- operator == `+` | `-` | `*` | `/`
34
- operation == value + (operator + value) * 0
35
- value == parenthese | number
36
- parenthese == `(` + expression + `)`
37
- number == `-` * -1 + _('0-9') * 1
32
+ operator == `+` | `-` | `*` | `/`
33
+ operation == value + (operator + value) * 0
34
+ value == parentheses | number
35
+ parentheses == `(` + expression + `)`
36
+ number == `-` * -1 + _('0-9') * 1
38
37
  end
39
38
 
40
39
  tree = ArithParser.parse("1+(2*12)")
@@ -116,7 +115,7 @@ It's a nested assemblage of result nodes.
116
115
  [ :bfalse, [ 0, 1, 1 ], true, 'false', [] ]
117
116
  ```
118
117
 
119
- In case of successful parsing, the succes? == false also get all pruned. In case of failed parsing, they are left in the output parse tree.
118
+ In case of successful parsing, the success? == false also get all pruned. In case of failed parsing, they are left in the output parse tree.
120
119
 
121
120
  A translator turns a raw parse tree into some final result. Look below and at the JSON parser sample in the specs for more information. If the parse failed and a translator is present, a ParseError is raised.
122
121
 
@@ -132,11 +131,11 @@ class CompactArithParser < Neg::Parser
132
131
 
133
132
  expression == operation
134
133
 
135
- operator == `+` | `-` | `*` | `/`
136
- operation == value + (operator + value) * 0
137
- value == parenthese | number
138
- parenthese == `(` + expression + `)`
139
- number == `-` * -1 + _('0-9') * 1
134
+ operator == `+` | `-` | `*` | `/`
135
+ operation == value + (operator + value) * 0
136
+ value == parentheses | number
137
+ parentheses == `(` + expression + `)`
138
+ number == `-` * -1 + _('0-9') * 1
140
139
  end
141
140
 
142
141
  translator do
@@ -146,7 +145,7 @@ class CompactArithParser < Neg::Parser
146
145
  on(:value) { |n| n.results.first }
147
146
 
148
147
  on(:expression) { |n|
149
- results = n.results.flatten(2)
148
+ results = n.flattened_results
150
149
  results.size == 1 ? results.first : results
151
150
  }
152
151
  end
@@ -156,8 +155,12 @@ CompactArithParser.parse("1+2+3")
156
155
  # => [ 1, '+', 2, '+', 3 ]
157
156
  ```
158
157
 
158
+ The original of this parser lies in [spec/sample_arith_spec.rb](spec/sample_arith_spec.rb). Please note that it's very dumb (like everything in neg) and, for example, avoids carefully dealing with operator precedence for its target language.
159
+
159
160
  As said above, when a translator is present and the parsing fails (before the translator kicks in), a ParseError is raised, with fancy methods to navigate the failed parse tree.
160
161
 
162
+ See also the [sample JSON parser](spec/sample_json_parser_spec.rb) and a [tiny toy scheme parser](spec/sample_scheme_spec.rb).
163
+
161
164
 
162
165
  ## presentations
163
166
 
data/TODO.txt CHANGED
@@ -1,17 +1,10 @@
1
1
 
2
- [o] unconsumed input!
3
- [o] ^ 0, 1, [ min, max ]
4
- [o] switch from ^ to * (how * is related to +)
5
- [o] _ (any)
6
- [o] chars
7
- [o] lookahead present/absent
8
- ~ x --> present
9
- ! x --> absent
10
-
11
- [ ] blankslate
12
- [ ] drop UnconsumedInput, replace with regular [ false, ... ] output
13
- [ ] x * '?' / x * '+' / x * '*' as shortcuts
14
- [ ] memoization (only at non-terminal level?)
15
-
16
- [ ] "xxx" instead of `xxx` (trick on the right side)
2
+ [o] investigate translator rule returning [] (json empty array for instance)
3
+ does it get discarded like the others?
4
+ [o] include the on(nil) rule by default?
5
+ [o] raise error (with #error_tree) when translator hits unparsable input
6
+ [o] document ...['name'] in the README
7
+
8
+ [o] verify that the Parslet UnconsumedInput problem doesn't appear in neg
9
+ [o] second look at the blankslate
17
10
 
@@ -27,19 +27,20 @@ module Neg
27
27
 
28
28
  class NegError < StandardError; end
29
29
 
30
- class UnconsumedInputError < NegError; end
31
30
  class ParserError < NegError; end
32
31
 
33
32
  class ParseError < NegError
34
33
 
35
- attr_reader :tree
34
+ attr_reader :tree, :position
36
35
 
37
36
  def initialize(tree)
38
37
 
39
38
  @tree = tree
40
39
  @nodes = list_nodes(tree)
41
40
 
42
- super(deepest_error[3])
41
+ d = deepest_error
42
+ @position = d[1]
43
+ super(d[3])
43
44
  end
44
45
 
45
46
  def errors
@@ -49,15 +50,30 @@ module Neg
49
50
 
50
51
  def deepest_error
51
52
 
52
- errors.inject { |e, n| e[1][0] < n[1][0] ? n : e }
53
+ # let's keep the tree depth (e[5]) for later
54
+
55
+ errors.inject do |eold, enew|
56
+ if eold[1][0] <= enew[1][0]
57
+ enew
58
+ else
59
+ eold
60
+ end
61
+ end
53
62
  end
54
63
 
64
+ def offset; @position[0]; end
65
+ def line; @position[1]; end
66
+ def column; @position[2]; end
67
+
55
68
  protected
56
69
 
57
- def list_nodes(start, accumulator=[])
70
+ def list_nodes(start, depth=0, accumulator=[])
71
+
72
+ start = start.dup
73
+ start << depth
58
74
 
59
75
  accumulator << start
60
- start[4].each { |n| list_nodes(n, accumulator) }
76
+ start[4].each { |n| list_nodes(n, depth + 1, accumulator) }
61
77
 
62
78
  accumulator
63
79
  end
@@ -58,15 +58,26 @@ module Neg
58
58
  pa
59
59
  end
60
60
 
61
+ def self.reduce(result)
62
+
63
+ if result[0] && result[2] && result[3]
64
+ result[4] =
65
+ []
66
+ else
67
+ result[4] =
68
+ result[4].each_with_object([]) { |cr, a| a << reduce(cr) if cr[2] }
69
+ end
70
+
71
+ result
72
+ end
73
+
61
74
  def self.parse(s, opts={})
62
75
 
63
76
  i = Neg::Input(s)
64
77
 
65
78
  result = __send__(@root).parse(i, opts)
66
79
 
67
- raise UnconsumedInputError.new(
68
- "remaining: #{i.remains.inspect}"
69
- ) if result[2] && ( ! i.eoi?)
80
+ result[2] = false if result[2] && ( ! i.eoi?)
70
81
 
71
82
  if @translator && opts[:translate] != false
72
83
  if result[2]
@@ -74,8 +85,10 @@ module Neg
74
85
  else
75
86
  raise ParseError.new(result)
76
87
  end
77
- else
88
+ elsif result[2] == false || opts[:noreduce]
78
89
  result
90
+ else
91
+ reduce(result)
79
92
  end
80
93
  end
81
94
 
@@ -123,10 +136,6 @@ module Neg
123
136
 
124
137
  input.rewind(start) unless success
125
138
 
126
- #if success && children.size == 1 && children.first[1] == start
127
- # return children.first
128
- #end
129
-
130
139
  [ nil, start, success, result, children ]
131
140
  end
132
141
  end
@@ -144,13 +153,13 @@ module Neg
144
153
  @child = pa
145
154
  end
146
155
 
147
- def reduce(children_results)
156
+ def refine(children_results)
148
157
 
149
158
  children_results.collect { |cr|
150
159
  if cr[0] && cr[0].to_s.match(/^_/).nil?
151
160
  false
152
161
  elsif cr[2]
153
- cr[3] ? cr[3] : reduce(cr[4])
162
+ cr[3] ? cr[3] : refine(cr[4])
154
163
  else
155
164
  nil
156
165
  end
@@ -166,11 +175,10 @@ module Neg
166
175
  return r if r[0] == false
167
176
  return r if r[1].is_a?(String)
168
177
 
169
- report = reduce(r[2])
178
+ report = refine(r[2])
179
+ report = report.include?(false) ? nil : report.join
170
180
 
171
- return r if report.include?(false)
172
-
173
- [ true, report.join, opts[:noreduce] ? r[2] : [] ]
181
+ [ true, report, r[2] ]
174
182
  end
175
183
 
176
184
  def parse(input_or_string, opts)
@@ -214,14 +222,28 @@ module Neg
214
222
  rs = []
215
223
 
216
224
  loop do
217
- r = @child.parse(i, opts)
218
- break if ! r[2] && rs.size >= @min && (@max.nil? || rs.size <= @max)
219
- rs << r
220
- break if ! r[2]
221
- break if rs.size == @max
225
+ rs << @child.parse(i, opts)
226
+ break if rs.last[2] == false
222
227
  end
223
228
 
224
- success = (rs.empty? || rs.last[2]) && (rs.size >= @min)
229
+ rs.size.downto(1) do |i|
230
+
231
+ r = rs[i - 1]
232
+
233
+ next if r[2] == false
234
+
235
+ if @max && i > @max
236
+ r[2] = false
237
+ r[3] = "did not expect #{r[3].inspect} (min #{@min} max #{@max})"
238
+ end
239
+ end
240
+
241
+ trs = rs.take_while { |r| r[2] == true }
242
+ rs = trs + [ rs.find { |r| r[2] == false } ]
243
+
244
+ success = trs.size >= @min && (@max.nil? || trs.size <= @max)
245
+
246
+ i.rewind(rs.last[1]) if success && rs.last[2] == false
225
247
 
226
248
  [ success, nil, rs ]
227
249
  end
@@ -40,8 +40,8 @@ module Neg
40
40
  def self.translate(parse_tree)
41
41
 
42
42
  results =
43
- parse_tree[4].each_with_object([]) { |node, a|
44
- catch(nil) { a << translate(node) }
43
+ parse_tree[4].each_with_object([]) { |tree, a|
44
+ catch(nil) { a << translate(tree) } if tree[2]
45
45
  }
46
46
 
47
47
  apply(parse_tree, results)
@@ -70,6 +70,20 @@ module Neg
70
70
  def column; @parse_tree[1][2]; end
71
71
 
72
72
  def result; @parse_tree[3]; end
73
+
74
+ # Useful when the grammar has something of the form:
75
+ #
76
+ # array == `[` + (value + (`,` + value) * 0) * 0 + `]`
77
+ #
78
+ # It flattens the value array.
79
+ #
80
+ # Look at the spec/sample_* files to see it in action.
81
+ #
82
+ def flattened_results
83
+
84
+ f2 = results.flatten(2)
85
+ f2.any? ? [ f2.shift ] + f2.flatten(2) : []
86
+ end
73
87
  end
74
88
  end
75
89
  end
@@ -25,6 +25,6 @@
25
25
 
26
26
  module Neg
27
27
 
28
- VERSION = '1.0.0'
28
+ VERSION = '1.1.0'
29
29
  end
30
30
 
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.platform = Gem::Platform::RUBY
11
11
  s.authors = [ 'John Mettraux' ]
12
12
  s.email = [ 'jmettraux@gmail.com' ]
13
- s.homepage = 'https://github.com/jmettraux/leg'
13
+ s.homepage = 'https://github.com/jmettraux/neg'
14
14
  s.rubyforge_project = 'ruote'
15
15
  s.summary = 'a neg narser'
16
16
 
@@ -0,0 +1,115 @@
1
+
2
+ require 'spec_helper'
3
+
4
+
5
+ describe 'neg and errors' do
6
+
7
+ class BlockParser < Neg::Parser
8
+
9
+ parser do
10
+
11
+ blocks == nl? + block + (nl + block) * 0 + nl?
12
+
13
+ block == sp? + `begin` + sp + _('a-z') + nl + body + sp? + `end`
14
+ body == ((line | block) + nl) * 0
15
+ line == sp + `line`
16
+
17
+ nl == _("\s\n") * 1
18
+ nl? == _("\s\n") * 0
19
+ sp == _(" ") * 1
20
+ sp? == _(" ") * 0
21
+ end
22
+
23
+ translator do
24
+ end
25
+ end
26
+
27
+ it 'parses a single empty block' do
28
+
29
+ BlockParser.parse(%{
30
+ begin a
31
+ end
32
+ })
33
+ end
34
+
35
+ it 'parses nested blocks' do
36
+
37
+ BlockParser.parse(%{
38
+ begin a
39
+ begin b
40
+ end
41
+ end
42
+ })
43
+ end
44
+
45
+ it 'parses successive blocks' do
46
+
47
+ BlockParser.parse(%{
48
+ begin a
49
+ end
50
+ begin b
51
+ end
52
+ })
53
+ end
54
+
55
+ it 'fails gracefully on a missing end (0)' do
56
+
57
+ err = nil
58
+
59
+ begin
60
+ BlockParser.parse(%{
61
+ begin a
62
+ begin b
63
+ end
64
+ })
65
+ rescue => err
66
+ end
67
+
68
+ err.class.should == Neg::ParseError
69
+ err.position.should == [ 53, 5, 6 ]
70
+ err.message.should == 'expected "end", got ""'
71
+ end
72
+
73
+ it 'fails gracefully on a missing end (1)' do
74
+
75
+ err = nil
76
+
77
+ begin
78
+ BlockParser.parse(%{
79
+ begin a
80
+ end
81
+ begin b
82
+ begin c
83
+ end
84
+ })
85
+ rescue => err
86
+ end
87
+
88
+ err.class.should == Neg::ParseError
89
+ err.position.should == [ 81, 7, 6 ]
90
+ err.message.should == 'expected "end", got ""'
91
+ end
92
+
93
+ it 'fails gracefully on a li too much (2)' do
94
+
95
+ err = nil
96
+
97
+ begin
98
+ BlockParser.parse(%{
99
+ begin a
100
+ end
101
+ begin b
102
+ begin c
103
+ li
104
+ end
105
+ end
106
+ })
107
+ rescue => err
108
+ end
109
+
110
+ err.class.should == Neg::ParseError
111
+ err.position.should == [ 75, 6, 12 ]
112
+ err.message.should == 'expected "end", got "li\n"'
113
+ end
114
+ end
115
+
@@ -18,14 +18,15 @@ describe Neg::Parser::RepetitionParser do
18
18
  [ :text, [ 0, 1, 1 ], true, '', [] ]
19
19
  end
20
20
 
21
- it 'fails gracefully' do
22
-
23
- lambda {
24
- parser.parse('xx')
25
- }.should raise_error(
26
- Neg::UnconsumedInputError,
27
- 'remaining: "x"')
28
- end
21
+ #it 'fails gracefully' do
22
+ # lambda {
23
+ # parser.parse('xx')
24
+ # }.should raise_error(
25
+ # Neg::UnconsumedInputError,
26
+ # 'remaining: "x"')
27
+ #end
28
+ #
29
+ # UnconsumedInputError is gone.
29
30
 
30
31
  it 'is rendered correctly via #to_s' do
31
32
 
@@ -57,14 +58,15 @@ describe Neg::Parser::RepetitionParser do
57
58
  [ :text, [ 0, 1, 1 ], true, 'xxx', [] ]
58
59
  end
59
60
 
60
- it 'fails gracefully' do
61
-
62
- lambda {
63
- parser.parse('a')
64
- }.should raise_error(
65
- Neg::UnconsumedInputError,
66
- 'remaining: "a"')
67
- end
61
+ #it 'fails gracefully' do
62
+ # lambda {
63
+ # parser.parse('a')
64
+ # }.should raise_error(
65
+ # Neg::UnconsumedInputError,
66
+ # 'remaining: "a"')
67
+ #end
68
+ #
69
+ # UnconsumedInputError is gone.
68
70
  end
69
71
 
70
72
  context '`x` * 2 (at least 2)' do
@@ -113,12 +115,13 @@ describe Neg::Parser::RepetitionParser do
113
115
  [ nil, [ 2, 1, 3 ], false, 'expected "x", got ""', [] ] ] ]
114
116
  end
115
117
 
116
- it 'fails gracefully (unconsumed input)' do
117
-
118
- lambda {
119
- parser.parse('xxxx')
120
- }.should raise_error(Neg::UnconsumedInputError, 'remaining: "x"')
121
- end
118
+ #it 'fails gracefully (unconsumed input)' do
119
+ # lambda {
120
+ # parser.parse('xxxx')
121
+ # }.should raise_error(Neg::UnconsumedInputError, 'remaining: "x"')
122
+ #end
123
+ #
124
+ # UnconsumedInputError is gone.
122
125
 
123
126
  it 'is rendered correctly via #to_s' do
124
127
 
@@ -33,30 +33,52 @@ describe 'Neg::Parser' do
33
33
  #
34
34
  # not worth the pain for now
35
35
 
36
- describe '.parse' do
36
+ # describe '.parse' do
37
+ #
38
+ # let(:parser) {
39
+ # Class.new(Neg::Parser) do
40
+ # text == `x`
41
+ # end
42
+ # }
43
+ #
44
+ # it 'raises on unconsumed input' do
45
+ #
46
+ # lambda {
47
+ # parser.parse('xy')
48
+ # }.should raise_error(
49
+ # Neg::UnconsumedInputError,
50
+ # 'remaining: "y"')
51
+ # end
52
+ #
53
+ # it 'raises on unconsumed input (...)' do
54
+ #
55
+ # lambda {
56
+ # parser.parse('xyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy')
57
+ # }.should raise_error(
58
+ # Neg::UnconsumedInputError,
59
+ # 'remaining: "yyyyyyy..."')
60
+ # end
61
+ # end
62
+ #
63
+ # UnconsumedInputError is gone.
64
+
65
+ context 'unconsumed input' do
37
66
 
38
67
  let(:parser) {
39
68
  Class.new(Neg::Parser) do
40
- text == `x`
69
+ text == `x` * -1
41
70
  end
42
71
  }
43
72
 
44
- it 'raises on unconsumed input' do
45
-
46
- lambda {
47
- parser.parse('xy')
48
- }.should raise_error(
49
- Neg::UnconsumedInputError,
50
- 'remaining: "y"')
51
- end
52
-
53
- it 'raises on unconsumed input (...)' do
73
+ it 'fails gracefully' do
54
74
 
55
- lambda {
56
- parser.parse('xyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy')
57
- }.should raise_error(
58
- Neg::UnconsumedInputError,
59
- 'remaining: "yyyyyyy..."')
75
+ parser.parse('xx').should ==
76
+ [ :text,
77
+ [ 0, 1, 1 ],
78
+ false,
79
+ 'x',
80
+ [ [ nil, [0, 1, 1], true, 'x', [] ],
81
+ [ nil, [1, 1, 2], false, 'did not expect "x" (min 0 max 1)', [] ] ] ]
60
82
  end
61
83
  end
62
84
  end
@@ -8,11 +8,11 @@ describe 'sample math parser' do
8
8
 
9
9
  expression == operation
10
10
 
11
- operator == `+` | `-` | `*` | `/`
12
- operation == value + (operator + value) * 0
13
- value == parenthese | number
14
- parenthese == `(` + expression + `)`
15
- number == `-` * -1 + _('0-9') * 1
11
+ operator == `+` | `-` | `*` | `/`
12
+ operation == value + (operator + value) * 0
13
+ value == parentheses | number
14
+ parentheses == `(` + expression + `)`
15
+ number == `-` * -1 + _('0-9') * 1
16
16
  end
17
17
 
18
18
  class ArithTranslator < Neg::Translator
@@ -22,7 +22,7 @@ describe 'sample math parser' do
22
22
  on(:value) { |n| n.results.first }
23
23
 
24
24
  on(:expression) { |n|
25
- results = n.results.flatten(2)
25
+ results = n.flattened_results
26
26
  results.size == 1 ? results.first : results
27
27
  }
28
28
  end
@@ -10,11 +10,11 @@ describe 'sample compact arith parser' do
10
10
 
11
11
  expression == operation
12
12
 
13
- operator == `+` | `-` | `*` | `/`
14
- operation == value + (operator + value) * 0
15
- value == parenthese | number
16
- parenthese == `(` + expression + `)`
17
- number == `-` * -1 + _('0-9') * 1
13
+ operator == `+` | `-` | `*` | `/`
14
+ operation == value + (operator + value) * 0
15
+ value == parentheses | number
16
+ parentheses == `(` + expression + `)`
17
+ number == `-` * -1 + _('0-9') * 1
18
18
  end
19
19
 
20
20
  translator do
@@ -40,14 +40,8 @@ describe 'sample JSON parser' do
40
40
  on(:value) { |n| n.results.first.first }
41
41
  on(:spaces?) { throw nil }
42
42
 
43
- on(:object) { |n|
44
- f2 = n.results.flatten(2)
45
- Hash[f2.any? ? [ f2.shift ] + f2.flatten(2) : []]
46
- }
47
- on(:array) { |n|
48
- f2 = n.results.flatten(2)
49
- f2.any? ? [ f2.shift ] + f2.flatten(2) : []
50
- }
43
+ on(:object) { |n| Hash[n.flattened_results] }
44
+ on(:array) { |n| n.flattened_results }
51
45
 
52
46
  on(:string) { |n| eval(n.result) }
53
47
 
@@ -198,8 +192,8 @@ describe 'sample JSON parser' do
198
192
  it 'raises a ParseError on incorrect input' do
199
193
 
200
194
  lambda do
201
- JsonParser.parse("x")
202
- end.should raise_error(Neg::ParseError, 'expected "{", got "x"')
195
+ JsonParser.parse('x')
196
+ end.should raise_error(Neg::ParseError, 'expected "null", got "x"')
203
197
  end
204
198
  end
205
199
 
@@ -0,0 +1,39 @@
1
+
2
+ require 'spec_helper'
3
+
4
+
5
+ describe 'sample scheme parser' do
6
+
7
+ class SchemeParser < Neg::Parser
8
+
9
+ parser do
10
+
11
+ expression == list | atom
12
+
13
+ list == `(` + (expression + (` ` + expression) * 0) * 0 + `)`
14
+ atom == _("^() ") * 1
15
+ end
16
+
17
+ translator do
18
+
19
+ on(:expression) { |n| n.results.first }
20
+ on(:atom) { |n| n.result }
21
+
22
+ on(:list) { |n| n.flattened_results }
23
+ end
24
+ end
25
+
26
+ it 'parses numbers' do
27
+
28
+ SchemeParser.parse("13").should == "13"
29
+ SchemeParser.parse("-13").should == "-13"
30
+ end
31
+
32
+ it 'parses lists' do
33
+
34
+ SchemeParser.parse("()").should == []
35
+ SchemeParser.parse("(a b c)").should == [ 'a', 'b', 'c' ]
36
+ SchemeParser.parse("(a (b c))").should == [ 'a', [ 'b', 'c' ] ]
37
+ end
38
+ end
39
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neg
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-16 00:00:00.000000000 Z
12
+ date: 2013-02-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -51,31 +51,33 @@ extensions: []
51
51
  extra_rdoc_files: []
52
52
  files:
53
53
  - Rakefile
54
- - lib/neg/errors.rb
55
54
  - lib/neg/input.rb
55
+ - lib/neg/errors.rb
56
+ - lib/neg/version.rb
56
57
  - lib/neg/parser.rb
57
58
  - lib/neg/translator.rb
58
- - lib/neg/version.rb
59
59
  - lib/neg.rb
60
- - spec/input_spec.rb
61
- - spec/parser_alternative_spec.rb
62
- - spec/parser_character_spec.rb
63
- - spec/parser_lookahead_parser_spec.rb
60
+ - spec/sample_arith_spec.rb
61
+ - spec/spec_helper.rb
64
62
  - spec/parser_non_terminal_spec.rb
65
- - spec/parser_repetition_spec.rb
63
+ - spec/greedy_spec.rb
64
+ - spec/parser_character_spec.rb
65
+ - spec/parser_string_spec.rb
66
+ - spec/sample_scheme_spec.rb
66
67
  - spec/parser_sequence_spec.rb
68
+ - spec/sample_json_parser_spec.rb
69
+ - spec/parser_alternative_spec.rb
67
70
  - spec/parser_spec.rb
68
- - spec/parser_string_spec.rb
69
- - spec/sample_arith_spec.rb
70
71
  - spec/sample_compact_spec.rb
71
- - spec/sample_json_parser_spec.rb
72
- - spec/spec_helper.rb
72
+ - spec/input_spec.rb
73
+ - spec/parser_lookahead_parser_spec.rb
74
+ - spec/parser_repetition_spec.rb
73
75
  - neg.gemspec
74
- - LICENSE.txt
75
76
  - TODO.txt
76
- - CHANGELOG.md
77
+ - LICENSE.txt
77
78
  - README.md
78
- homepage: https://github.com/jmettraux/leg
79
+ - CHANGELOG.md
80
+ homepage: https://github.com/jmettraux/neg
79
81
  licenses: []
80
82
  post_install_message:
81
83
  rdoc_options: []
@@ -89,7 +91,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
89
91
  version: '0'
90
92
  segments:
91
93
  - 0
92
- hash: -2623637621873378549
94
+ hash: 4523696272151903388
93
95
  required_rubygems_version: !ruby/object:Gem::Requirement
94
96
  none: false
95
97
  requirements:
@@ -98,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
100
  version: '0'
99
101
  segments:
100
102
  - 0
101
- hash: -2623637621873378549
103
+ hash: 4523696272151903388
102
104
  requirements: []
103
105
  rubyforge_project: ruote
104
106
  rubygems_version: 1.8.24