neg 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,65 @@
1
+
2
+ require 'spec_helper'
3
+
4
+
5
+ describe Neg::Parser::SequenceParser do
6
+
7
+ class SeqParser < Neg::Parser
8
+ text == `x` + `y`
9
+ end
10
+
11
+ it 'parses' do
12
+
13
+ SeqParser.parse('xy').should ==
14
+ [ :text, true, [ 0, 1, 1 ], [
15
+ [ nil, true, [ 0, 1, 1 ], 'x' ],
16
+ [ nil, true, [ 1, 1, 2 ], 'y' ] ] ]
17
+ end
18
+
19
+ it 'fails gracefully' do
20
+
21
+ SeqParser.parse('xx').should ==
22
+ [ :text, false, [ 0, 1, 1 ], [
23
+ [ nil, true, [ 0, 1, 1 ], 'x' ],
24
+ [ nil, false, [ 1, 1, 2 ], 'expected "y", got "x"' ] ] ]
25
+ end
26
+
27
+ it 'goes beyond two elements' do
28
+
29
+ parser = Class.new(Neg::Parser) do
30
+ text == `x` + `y` + `z`
31
+ end
32
+
33
+ text = parser.text
34
+
35
+ text.class.should ==
36
+ Neg::Parser::NonTerminalParser
37
+ text.child.children.collect(&:class).should ==
38
+ [ Neg::Parser::StringParser ] * 3
39
+ end
40
+
41
+ it 'backtracks correctly' do
42
+
43
+ parser = Class.new(Neg::Parser) do
44
+ word == poodle | pool
45
+ poodle == `poo` + `dle`
46
+ pool == `poo` + `l`
47
+ end
48
+
49
+ parser.parse('pool').should ==
50
+ [ :word,
51
+ true,
52
+ [ 0, 1, 1 ],
53
+ [ [ :poodle,
54
+ false,
55
+ [ 0, 1, 1 ],
56
+ [ [ nil, true, [ 0, 1, 1 ], "poo" ],
57
+ [ nil, false, [ 3, 1, 4 ], "expected \"dle\", got \"l\"" ] ] ],
58
+ [ :pool,
59
+ true,
60
+ [ 0, 1, 1],
61
+ [ [ nil, true, [ 0, 1, 1 ], "poo" ],
62
+ [ nil, true, [ 3, 1, 4 ], "l" ] ] ] ] ]
63
+ end
64
+ end
65
+
@@ -0,0 +1,48 @@
1
+
2
+ require 'spec_helper'
3
+
4
+
5
+ describe 'Neg::Parser' do
6
+
7
+ describe 'using parentheses' do
8
+
9
+ it 'influences precedence' do
10
+
11
+ parser = Class.new(Neg::Parser) do
12
+ t0 == `x` + `y` | `z`
13
+ t1 == (`x` | `y`) + `z`
14
+ end
15
+
16
+ parser.t0.to_s.should == 't0 == ((`x` + `y`) | `z`)'
17
+ parser.t1.to_s.should == 't1 == ((`x` | `y`) + `z`)'
18
+ end
19
+ end
20
+
21
+ describe '.parse' do
22
+
23
+ let(:parser) {
24
+ Class.new(Neg::Parser) do
25
+ text == `x`
26
+ end
27
+ }
28
+
29
+ it 'raises on unconsumed input' do
30
+
31
+ lambda {
32
+ parser.parse('xy')
33
+ }.should raise_error(
34
+ Neg::UnconsumedInputError,
35
+ 'remaining: "y"')
36
+ end
37
+
38
+ it 'raises on unconsumed input (...)' do
39
+
40
+ lambda {
41
+ parser.parse('xyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy')
42
+ }.should raise_error(
43
+ Neg::UnconsumedInputError,
44
+ 'remaining: "yyyyyyy..."')
45
+ end
46
+ end
47
+ end
48
+
@@ -0,0 +1,41 @@
1
+
2
+ require 'spec_helper'
3
+
4
+
5
+ describe Neg::Parser::StringParser do
6
+
7
+ context 'standalone' do
8
+
9
+ it 'parses' do
10
+
11
+ parser = Neg::Parser::StringParser.new('xxx')
12
+
13
+ parser.parse('xxx').should ==
14
+ [ nil, true, [ 0, 1, 1 ], 'xxx' ]
15
+ end
16
+
17
+ it 'fails gracefully' do
18
+
19
+ parser = Neg::Parser::StringParser.new('xxx')
20
+
21
+ parser.parse('yyy').should ==
22
+ [ nil, false, [ 0, 1, 1 ], 'expected "xxx", got "yyy"' ]
23
+ end
24
+ end
25
+
26
+ context 'within Neg::Parser' do
27
+
28
+ let(:parser) {
29
+ Class.new(Neg::Parser) do
30
+ root == `x`
31
+ end
32
+ }
33
+
34
+ it 'parses an exact string' do
35
+
36
+ parser.parse('x').should ==
37
+ [ :root, true, [ 0, 1, 1 ], 'x' ]
38
+ end
39
+ end
40
+ end
41
+
@@ -0,0 +1,83 @@
1
+
2
+ require 'spec_helper'
3
+
4
+
5
+ describe 'sample JSON parser' do
6
+
7
+ class JsonParser < Neg::Parser
8
+
9
+ #rule(:spaces) { match('\s').repeat(1) }
10
+ #rule(:spaces?) { spaces.maybe }
11
+
12
+ #rule(:comma) { spaces? >> str(',') >> spaces? }
13
+ #rule(:digit) { match('[0-9]') }
14
+
15
+ #rule(:number) {
16
+ # (
17
+ # str('-').maybe >> (
18
+ # str('0') | (match('[1-9]') >> digit.repeat)
19
+ # ) >> (
20
+ # str('.') >> digit.repeat(1)
21
+ # ).maybe >> (
22
+ # match('[eE]') >> (str('+') | str('-')).maybe >> digit.repeat(1)
23
+ # ).maybe
24
+ # ).as(:number)
25
+ #}
26
+
27
+ #rule(:array) {
28
+ # str('[') >> spaces? >>
29
+ # (value >> (comma >> value).repeat).maybe.as(:array) >>
30
+ # spaces? >> str(']')
31
+ #}
32
+
33
+ #rule(:object) {
34
+ # str('{') >> spaces? >>
35
+ # (entry >> (comma >> entry).repeat).maybe.as(:object) >>
36
+ # spaces? >> str('}')
37
+ #}
38
+
39
+ #rule(:entry) {
40
+ # (
41
+ # string.as(:key) >> spaces? >>
42
+ # str(':') >> spaces? >>
43
+ # value.as(:val)
44
+ # ).as(:entry)
45
+ #}
46
+
47
+ #rule(:attribute) { (entry | value).as(:attribute) }
48
+
49
+ json == spaces? + value + spaces?
50
+
51
+ value == string | number | object | array | btrue | bfalse | null
52
+
53
+ btrue == `true`
54
+ bfalse == `false`
55
+ null == `null`
56
+
57
+ # TODO: continue here with "string"
58
+
59
+ #rule(:string) {
60
+ # str('"') >> (
61
+ # str('\\') >> any | str('"').absent? >> any
62
+ # ).repeat.as(:string) >> str('"')
63
+ #}
64
+
65
+ #rule(:value) {
66
+ # string | number |
67
+ # object | array |
68
+ # str('true').as(:true) | str('false').as(:false) |
69
+ # str('null').as(:null)
70
+ #}
71
+
72
+ #rule(:top) { spaces? >> value >> spaces? }
73
+ #root(:top)
74
+ end
75
+
76
+ it 'flips burgers' do
77
+
78
+ puts '-' * 80
79
+ puts JsonParser
80
+ puts '-' * 80
81
+ end
82
+ end
83
+
@@ -0,0 +1,20 @@
1
+
2
+ $:.unshift(File.expand_path('../../lib', __FILE__))
3
+
4
+ require 'neg'
5
+
6
+
7
+ class Neg::Parser::CompositeParser
8
+
9
+ attr_reader :children
10
+ end
11
+
12
+ class Neg::Parser::NonTerminalParser
13
+
14
+ attr_reader :child
15
+ end
16
+
17
+
18
+ #RSpec.configure do |config|
19
+ #end
20
+
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: neg
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - John Mettraux
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 2.9.0
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 2.9.0
46
+ description: not a peg parser, just a neg narser
47
+ email:
48
+ - jmettraux@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - Rakefile
54
+ - lib/neg/input.rb
55
+ - lib/neg/parser.rb
56
+ - lib/neg/version.rb
57
+ - lib/neg.rb
58
+ - spec/input_spec.rb
59
+ - spec/parser_alternative_spec.rb
60
+ - spec/parser_character_spec.rb
61
+ - spec/parser_non_terminal_spec.rb
62
+ - spec/parser_repetition_spec.rb
63
+ - spec/parser_sequence_spec.rb
64
+ - spec/parser_spec.rb
65
+ - spec/parser_string_spec.rb
66
+ - spec/sample_json_parser_spec.rb
67
+ - spec/spec_helper.rb
68
+ - neg.gemspec
69
+ - LICENSE.txt
70
+ - TODO.txt
71
+ - CHANGELOG.md
72
+ - README.md
73
+ homepage: https://github.com/jmettraux/leg
74
+ licenses: []
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ! '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project: ruote
93
+ rubygems_version: 1.8.24
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: a neg narser
97
+ test_files: []