neg 1.0.0 → 1.1.0

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