regparsec 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.rdoc +28 -0
- data/VERSION +1 -0
- data/examples/string_parser.rb +24 -0
- data/lib/regparsec.rb +13 -0
- data/lib/regparsec/parser/base.rb +9 -0
- data/lib/regparsec/parser/combinators.rb +139 -0
- data/lib/regparsec/parser/primary_parsers.rb +90 -0
- data/lib/regparsec/parser/state.rb +51 -0
- data/lib/regparsec/regparseable.rb +86 -0
- data/lib/regparsec/regparser.rb +49 -0
- data/lib/regparsec/regparser_delegator.rb +39 -0
- data/lib/regparsec/regparser_helpers.rb +22 -0
- data/lib/regparsec/regparsers.rb +18 -0
- data/lib/regparsec/regular_object.rb +16 -0
- data/lib/regparsec/result.rb +40 -0
- data/lib/regparsec/result/accepted.rb +0 -0
- data/lib/regparsec/result/invalid.rb +0 -0
- data/lib/regparsec/result/success.rb +0 -0
- data/lib/regparsec/state_attributes.rb +78 -0
- data/regparsec.gemspec +17 -0
- data/spec/delegation_spec.rb +24 -0
- data/spec/regparser_spec.rb +16 -0
- data/spec/regparsers/apply_parser_spec.rb +25 -0
- data/spec/regparsers/between_parser_spec.rb +21 -0
- data/spec/regparsers/give_state_spec.rb +10 -0
- data/spec/regparsers/many1_parser_spec.rb +16 -0
- data/spec/regparsers/many_parser_spec.rb +16 -0
- data/spec/regparsers/one_of_parser_spec.rb +18 -0
- data/spec/regparsers/regexp_parser_spec.rb +79 -0
- data/spec/regparsers/string_parser_spec.rb +17 -0
- data/spec/regparsers/try_parser_spec.rb +0 -0
- data/spec/regparsers/update_state_parser_spec.rb +18 -0
- data/spec/regparsers_spec.rb +1 -0
- data/spec/result_hook_spec.rb +16 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/state_attributes_spec.rb +61 -0
- metadata +122 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg/*
|
data/README.rdoc
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
= RegParsec
|
2
|
+
|
3
|
+
This be development version yet.
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
$ git clone git@github.com:pasberth/RegParsec.git
|
8
|
+
$ cd RegParsec
|
9
|
+
$ gem build regparsec.gemspec
|
10
|
+
$ gem install regparsec-0.1.0.gem
|
11
|
+
|
12
|
+
== Try RegParsec
|
13
|
+
|
14
|
+
$ irb
|
15
|
+
|
16
|
+
require 'regparsec'
|
17
|
+
# => true
|
18
|
+
StringParser = RegParsec::Regparsers.between('"', '"', /(?:(?:\\\")|[^"])*/)
|
19
|
+
StringParser.parse('"this is a string"')
|
20
|
+
# => #<MatchData "this is a string">
|
21
|
+
StringParser.parse('"can escape the \" !"')
|
22
|
+
# => #<MatchData "can escape the \\\" !">
|
23
|
+
|
24
|
+
== Result hook
|
25
|
+
|
26
|
+
StringParser = RegParsec::Regparsers.between('"', '"', /(?:(?:\\\")|[^"])*/) { |match_data| "Result: " + match_data[0] }
|
27
|
+
StringParser.parse('"Success!"')
|
28
|
+
# => "Result: Success!"
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,24 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
require 'regparsec'
|
3
|
+
|
4
|
+
StringParser = RegParsec::Regparsers.between('"', '"', /(?:(?:\\\")|[^"])*/)
|
5
|
+
p StringParser.parse('"this is a string"')
|
6
|
+
# => #<MatchData "this is a string">
|
7
|
+
p StringParser.parse('"can escape the \" !"')
|
8
|
+
# => #<MatchData "can escape the \\\" !">
|
9
|
+
|
10
|
+
QuoteParser = RegParsec::Regparsers.instance_eval do
|
11
|
+
between(
|
12
|
+
apply('q', update_state(:quotation_mark, apply(/./) { |q| q[0].to_s })),
|
13
|
+
->(state) { apply( state.quotation_mark ) },
|
14
|
+
->(state) {
|
15
|
+
q = Regexp.quote( state.quotation_mark ) # "\"" => "\\\""
|
16
|
+
apply( /(?:(?:\\#{ q })|[^#{ q }])*/ ) # /(?:(?:\\\")|[^"])*/
|
17
|
+
}
|
18
|
+
) { |body| body[0].to_s }
|
19
|
+
end
|
20
|
+
|
21
|
+
p QuoteParser.parse('q"the double quotation!"')
|
22
|
+
# => "the double quotation!"
|
23
|
+
p QuoteParser.parse('q# the quotation by number marks! #')
|
24
|
+
# => " the quotation by number marks! "
|
data/lib/regparsec.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'give4each'
|
2
|
+
|
3
|
+
module RegParsec
|
4
|
+
|
5
|
+
require 'regparsec/state_attributes'
|
6
|
+
require 'regparsec/result'
|
7
|
+
require 'regparsec/regparser_helpers'
|
8
|
+
require 'regparsec/regparseable'
|
9
|
+
require 'regparsec/regparsers'
|
10
|
+
require 'regparsec/regular_object'
|
11
|
+
require 'regparsec/regparser_delegator'
|
12
|
+
require 'regparsec/regparser'
|
13
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
module RegParsec::Regparsers
|
2
|
+
|
3
|
+
[ [:try, :TryParser],
|
4
|
+
[:apply, :ApplyParser],
|
5
|
+
[:many, :ManyParser],
|
6
|
+
[:many1, :Many1Parser],
|
7
|
+
[:between, :BetweenParser],
|
8
|
+
[:one_of, :OneOfParser]
|
9
|
+
].each do |method, klass|
|
10
|
+
module_eval(<<-DEF)
|
11
|
+
def #{method}(*args, &result_hook)
|
12
|
+
regparser = ::RegParsec::Regparsers::#{klass}.new.curry!(*args)
|
13
|
+
regparser.result_hook!(&result_hook) if result_hook
|
14
|
+
regparser
|
15
|
+
end
|
16
|
+
DEF
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module RegParsec::Regparsers
|
21
|
+
|
22
|
+
class TryParser < Base
|
23
|
+
|
24
|
+
def __regparse__ state, doing
|
25
|
+
commit = state.commit!
|
26
|
+
case result = doing.regparse(state)
|
27
|
+
when Result::Success, Result::Valid
|
28
|
+
state.commit!
|
29
|
+
result
|
30
|
+
else
|
31
|
+
state.commit! commit
|
32
|
+
result
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class ApplyParser < Base
|
38
|
+
|
39
|
+
def __regparse__ state, *regparsers
|
40
|
+
consumed = ''
|
41
|
+
list = []
|
42
|
+
valid = false
|
43
|
+
regparsers.each do |regp|
|
44
|
+
result = regp.regparse(state)
|
45
|
+
case result
|
46
|
+
when Result::Success, Result::Valid
|
47
|
+
consumed << result.matching_string
|
48
|
+
list << result.return_value
|
49
|
+
valid = result.is_a? Result::Valid
|
50
|
+
when Result::Accepted
|
51
|
+
consumed << result.matching_string
|
52
|
+
list << result.return_value
|
53
|
+
return Result::Accepted.new( :return_value => list, :matching_string => consumed )
|
54
|
+
when Result::Invalid
|
55
|
+
return Result::Invalid.new
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
valid ?
|
60
|
+
Result::Valid.new( :return_value => list , :matching_string => consumed ) :
|
61
|
+
Result::Success.new( :return_value => list , :matching_string => consumed )
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class ManyParser < Base
|
66
|
+
|
67
|
+
def __regparse__ state, doing
|
68
|
+
consumed = ''
|
69
|
+
valid = false
|
70
|
+
list = [].tap do |list|
|
71
|
+
while result = try(doing).regparse(state)
|
72
|
+
case result
|
73
|
+
when Result::Success, Result::Valid then
|
74
|
+
consumed << result.matching_string
|
75
|
+
list << result.return_value
|
76
|
+
valid = result.is_a? Result::Valid
|
77
|
+
when Result::Accepted then
|
78
|
+
return Result::Valid.new( :return_value => list, :matching_string => consumed )
|
79
|
+
when Result::Invalid then
|
80
|
+
break
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
valid ?
|
86
|
+
Result::Valid.new( :return_value => list , :matching_string => consumed ) :
|
87
|
+
Result::Success.new( :return_value => list , :matching_string => consumed )
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class Many1Parser < Base
|
92
|
+
|
93
|
+
def __regparse__ state, doing
|
94
|
+
case head = try(doing).regparse(state)
|
95
|
+
when Result::Invalid then head
|
96
|
+
when Result::Accepted then head
|
97
|
+
when Result::Success, Result::Valid
|
98
|
+
result = many(doing).regparse(state)
|
99
|
+
if result.return_value.empty? and head.is_a? Result::Valid or result.is_a? Result::Valid then
|
100
|
+
Result::Valid.new( :return_value => [head.return_value, *result.return_value], :matching_string => head.matching_string + result.matching_string )
|
101
|
+
elsif result.is_a? Result::Success then
|
102
|
+
Result::Success.new( :return_value => [head.return_value, *result.return_value], :matching_string => head.matching_string + result.matching_string )
|
103
|
+
# when Result::Accepted
|
104
|
+
# when Result::Invalid
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class BetweenParser < Base
|
111
|
+
|
112
|
+
def __regparse__ state, open, close, body
|
113
|
+
case result = apply(open, body, close).regparse(state)
|
114
|
+
when Result::Success
|
115
|
+
Result::Success.new( :return_value => result.return_value[1], :matching_string => result.matching_string )
|
116
|
+
when Result::Valid
|
117
|
+
Result::Valid.new( :return_value => result.return_value[1], :matching_string => result.matching_string )
|
118
|
+
when Result::Accepted
|
119
|
+
Result::Accepted.new( :return_value => result.return_value[1], :matching_string => result.matching_string )
|
120
|
+
else
|
121
|
+
result
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
class OneOfParser < Base
|
127
|
+
|
128
|
+
def __regparse__ state, *choices
|
129
|
+
accepted = nil
|
130
|
+
choices.any? do |a|
|
131
|
+
case result = try(a).regparse(state)
|
132
|
+
when Result::Success, Result::Valid then return result
|
133
|
+
when Result::Accepted then accepted ||= result; false
|
134
|
+
else false
|
135
|
+
end
|
136
|
+
end or accepted or Result::Invalid.new
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'regparsec/regparsers'
|
2
|
+
|
3
|
+
class String
|
4
|
+
|
5
|
+
def to_regparser
|
6
|
+
::RegParsec::Regparsers::StringParser.well_defined_parser_get(self)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Regexp
|
11
|
+
|
12
|
+
def to_regparser
|
13
|
+
::RegParsec::Regparsers::RegexpParser.well_defined_parser_get(self)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Proc
|
18
|
+
|
19
|
+
def to_regparser
|
20
|
+
::RegParsec::Regparsers::ProcParser.new.curry!(self)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class RegParsec::Regparsers::StringParser < RegParsec::Regparsers::Base
|
25
|
+
|
26
|
+
def self.well_defined_parser_get str
|
27
|
+
(@_well_defined_parsers ||= {})[str] ||= new.curry!(str)
|
28
|
+
end
|
29
|
+
|
30
|
+
def format_args expecting, *args
|
31
|
+
[expecting, *args]
|
32
|
+
end
|
33
|
+
|
34
|
+
def __regparse__ state, expecting
|
35
|
+
if state.input[0, expecting.length] == expecting
|
36
|
+
state.input.sub!(expecting, '')
|
37
|
+
Result::Success.new( :return_value => expecting, :matching_string => expecting )
|
38
|
+
elsif expecting[0, state.input.length] == state.input
|
39
|
+
Result::Accepted.new( :return_value => state.input, :matching_string => state.input )
|
40
|
+
else
|
41
|
+
Result::Invalid.new( :return_value => nil )
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class RegParsec::Regparsers::RegexpParser < RegParsec::Regparsers::Base
|
47
|
+
|
48
|
+
def self.well_defined_parser_get regexp
|
49
|
+
(@_well_defined_parsers ||= {})[regexp] ||= new.curry!(regexp)
|
50
|
+
end
|
51
|
+
|
52
|
+
def format_args expecting, *args
|
53
|
+
[expecting, *args]
|
54
|
+
end
|
55
|
+
|
56
|
+
def __regparse__ state, regexp
|
57
|
+
case state.input # case "abc;def;"
|
58
|
+
when /\A#{regexp}\z/ # when /\A(.*?);\z/
|
59
|
+
md = $~; md[0] =~ /\A#{regexp}/ # "abc;def;" =~ /\A(.*?);/
|
60
|
+
if $~[0] != md[0] # if "abc;" != "abc;def;"
|
61
|
+
md = $~
|
62
|
+
state.input.sub!(md[0], '')
|
63
|
+
Result::Success.new( :return_value => md,
|
64
|
+
:matching_string => md[0] )
|
65
|
+
else
|
66
|
+
state.input.sub!(md[0], '')
|
67
|
+
Result::Valid.new( :return_value => md,
|
68
|
+
:matching_string => md[0] )
|
69
|
+
end
|
70
|
+
when /\A#{regexp}/
|
71
|
+
md = $~
|
72
|
+
state.input.sub!(md[0], '')
|
73
|
+
Result::Success.new( :return_value => md,
|
74
|
+
:matching_string => md[0] )
|
75
|
+
else
|
76
|
+
Result::Invalid.new( :return_value => nil )
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class RegParsec::Regparsers::ProcParser < RegParsec::Regparsers::Base
|
82
|
+
|
83
|
+
def format_args proc, *args
|
84
|
+
[proc, *args]
|
85
|
+
end
|
86
|
+
|
87
|
+
def __regparse__ state, proc
|
88
|
+
try_convert_into_regparser!( proc.call(state) ).regparse( state )
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'regparsec/regparsers'
|
2
|
+
|
3
|
+
module RegParsec::Regparsers
|
4
|
+
|
5
|
+
|
6
|
+
[ [:update_state, :UpdateStateParser],
|
7
|
+
[:give_state, :GiveStateParser]
|
8
|
+
].each do |method, klass|
|
9
|
+
module_eval(<<-DEF)
|
10
|
+
def #{method}(*args, &result_hook)
|
11
|
+
regparser = ::RegParsec::Regparsers::#{klass}.new.curry!(*args)
|
12
|
+
regparser.result_hook!(&result_hook) if result_hook
|
13
|
+
regparser
|
14
|
+
end
|
15
|
+
DEF
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class RegParsec::Regparsers::UpdateStateParser < RegParsec::Regparsers::Base
|
20
|
+
|
21
|
+
def format_args *args
|
22
|
+
[ args[0].to_sym,
|
23
|
+
try_convert_into_regparser!(args[1]),
|
24
|
+
*args[2..-1]
|
25
|
+
]
|
26
|
+
end
|
27
|
+
|
28
|
+
def __regparse__ state, binding_variable, regparser
|
29
|
+
case result = regparser.regparse( state )
|
30
|
+
when Result::Success
|
31
|
+
state.merge!(binding_variable => result.return_value)
|
32
|
+
result
|
33
|
+
else
|
34
|
+
result
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class RegParsec::Regparsers::GiveStateParser < RegParsec::Regparsers::Base
|
40
|
+
|
41
|
+
def format_args *args
|
42
|
+
[ args[0].to_sym,
|
43
|
+
try_convert_into_regparser!(args[1]),
|
44
|
+
*args[2..-1]
|
45
|
+
]
|
46
|
+
end
|
47
|
+
|
48
|
+
def __regparse__ state, binding_variable, regparser
|
49
|
+
regparser.curry( state[binding_variable] ).regparse( state )
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'regparsec'
|
2
|
+
|
3
|
+
module RegParsec::Regparseable
|
4
|
+
|
5
|
+
[ :regparse, :parse ].each do |method|
|
6
|
+
class_eval(<<-DEFINE)
|
7
|
+
def __#{method}__(*args, &block)
|
8
|
+
raise NotImplementedError, "need to define `#{method}'"
|
9
|
+
end
|
10
|
+
DEFINE
|
11
|
+
end
|
12
|
+
|
13
|
+
def regparse state
|
14
|
+
result = __regparse__ ::RegParsec::RegparserHelpers.build_state_attributes(state), *format_args(*curried_args)
|
15
|
+
case result
|
16
|
+
when ::RegParsec::Result::Success, ::RegParsec::Result::Valid
|
17
|
+
result.return_value = result_hooks.inject(result.return_value) { |r, hook| hook.call(r) }
|
18
|
+
end
|
19
|
+
result
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse state
|
23
|
+
__parse__ ::RegParsec::RegparserHelpers.build_state_attributes(state), *format_args(*curried_args)
|
24
|
+
end
|
25
|
+
|
26
|
+
def __parse__ state, *args
|
27
|
+
case result = regparse(state)
|
28
|
+
when ::RegParsec::Result::Success, ::RegParsec::Result::Valid
|
29
|
+
result.return_value
|
30
|
+
else
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def format_args *args
|
36
|
+
args.map &:try_convert_into_regparser!.in(::RegParsec::RegparserHelpers)
|
37
|
+
end
|
38
|
+
|
39
|
+
def result_hook &block
|
40
|
+
clone.result_hook! &block
|
41
|
+
end
|
42
|
+
|
43
|
+
def result_hook! &hook
|
44
|
+
result_hooks << hook || raise(ArgumentError, "tried to put a result hook without a block.")
|
45
|
+
end
|
46
|
+
|
47
|
+
def curry! *args, &block
|
48
|
+
args.each &:push.to(curried_args)
|
49
|
+
# TODO: How will using to the block
|
50
|
+
# result_procs << result_proc if result_procs.empty? and result_proc
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def curry *args, &block
|
55
|
+
clone.curry! *args, &block
|
56
|
+
end
|
57
|
+
|
58
|
+
def clone
|
59
|
+
cln = super
|
60
|
+
cln.curried_args = curried_args.clone
|
61
|
+
cln.result_hooks = result_hooks.clone
|
62
|
+
cln
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_regparser
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
protected
|
70
|
+
|
71
|
+
def curried_args= a
|
72
|
+
@_curried_args = a
|
73
|
+
end
|
74
|
+
|
75
|
+
def curried_args
|
76
|
+
@_curried_args ||= []
|
77
|
+
end
|
78
|
+
|
79
|
+
def result_hooks= a
|
80
|
+
@_result_hooks = a
|
81
|
+
end
|
82
|
+
|
83
|
+
def result_hooks
|
84
|
+
@_result_hooks ||= []
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'regparsec'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
class RegParsec::Regparser
|
5
|
+
include RegParsec
|
6
|
+
include RegParsec::Regparseable
|
7
|
+
|
8
|
+
def initialize regparser
|
9
|
+
@regparser = ::RegParsec::RegparserHelpers.try_convert_into_regparser!(regparser)
|
10
|
+
end
|
11
|
+
|
12
|
+
def __regparse__ state
|
13
|
+
consumed = ''
|
14
|
+
case state.input
|
15
|
+
when String
|
16
|
+
input = StringIO.new(state.input)
|
17
|
+
else
|
18
|
+
input = state.input
|
19
|
+
end
|
20
|
+
|
21
|
+
return_value = [].tap do |list|
|
22
|
+
state.input = ""
|
23
|
+
state.commit!
|
24
|
+
while line = input.gets or !state.input.empty?
|
25
|
+
state.input << line if line
|
26
|
+
commit = state.commit!
|
27
|
+
case result = @regparser.regparse(state)
|
28
|
+
when Result::Success then
|
29
|
+
state.commit!
|
30
|
+
consumed << result.matching_string
|
31
|
+
list << result.return_value
|
32
|
+
when Result::Valid
|
33
|
+
(state.commit!(commit); next) if line
|
34
|
+
state.commit!
|
35
|
+
consumed << result.matching_string
|
36
|
+
list << result.return_value
|
37
|
+
when Result::Accepted then line ? (state.commit!(commit); next) : break
|
38
|
+
when Result::Invalid then state.commit!(commit); break
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if return_value.empty?
|
44
|
+
Result::Invalid.new
|
45
|
+
else
|
46
|
+
Result::Success.new :return_value => return_value, :matching_string => consumed
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'regparsec'
|
2
|
+
|
3
|
+
module RegParsec::RegparserDelegatable
|
4
|
+
|
5
|
+
include ::RegParsec::Regparseable
|
6
|
+
|
7
|
+
def regular_object
|
8
|
+
@_regparser_regobj ||= ::RegParsec::RegparserHelpers.try_convert_into_regparser!(__build_regparser__)
|
9
|
+
end
|
10
|
+
|
11
|
+
def __build_regparser__
|
12
|
+
raise NotImplementedError, "need to define `__build_regparser__'"
|
13
|
+
end
|
14
|
+
|
15
|
+
def format_args *args
|
16
|
+
args
|
17
|
+
end
|
18
|
+
|
19
|
+
def __regparse__ *args, &block
|
20
|
+
regular_object.regparse *args, &block
|
21
|
+
end
|
22
|
+
|
23
|
+
def __parse__ *args, &block
|
24
|
+
regular_object.parse *args, &block
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class RegParsec::RegparserDelegator
|
29
|
+
|
30
|
+
include ::RegParsec::RegparserDelegatable
|
31
|
+
|
32
|
+
def initialize regparser
|
33
|
+
@_regparser_regobj = ::RegParsec::RegparserHelpers.try_convert_into_regparser!(regparser)
|
34
|
+
end
|
35
|
+
|
36
|
+
def __build_regparser__
|
37
|
+
@_regparser_regobj
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'regparsec'
|
2
|
+
|
3
|
+
module RegParsec::RegparserHelpers
|
4
|
+
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def try_convert_into_regparser! regobj
|
8
|
+
if regobj.respond_to? :to_regparser
|
9
|
+
regobj.to_regparser
|
10
|
+
else
|
11
|
+
raise TypeError, "Can't convert #{regobj.class} into Regparser"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def build_state_attributes state
|
16
|
+
case state
|
17
|
+
when ::RegParsec::StateAttributes then state
|
18
|
+
when String then ::RegParsec::StateAttributes.new :input => state
|
19
|
+
when Hash then ::RegParsec::StateAttributes.new state
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'regparsec'
|
2
|
+
require 'regparsec/regparseable'
|
3
|
+
|
4
|
+
module RegParsec
|
5
|
+
|
6
|
+
module Regparsers
|
7
|
+
extend self
|
8
|
+
end
|
9
|
+
|
10
|
+
module Regparseable
|
11
|
+
include Regparsers
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'regparsec/parser/base'
|
16
|
+
require 'regparsec/parser/state'
|
17
|
+
require 'regparsec/parser/primary_parsers'
|
18
|
+
require 'regparsec/parser/combinators'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'regparsec'
|
2
|
+
|
3
|
+
class RegParsec::RegularObject < RegParsec::Regparsers::Base
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@regparsers = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def concat regparser
|
10
|
+
@regparsers << try_convert_into_regparser!(regparser)
|
11
|
+
end
|
12
|
+
|
13
|
+
def __regparse__ state
|
14
|
+
return apply( *@regparsers ).regparse state
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'regparsec'
|
2
|
+
|
3
|
+
class RegParsec::Result
|
4
|
+
|
5
|
+
include RegParsec
|
6
|
+
attr_accessor :return_value
|
7
|
+
|
8
|
+
def initialize informations={}
|
9
|
+
informations.each { |key, val| send(:"#{key}=", val) }
|
10
|
+
@information_keys = informations.each_key.to_a
|
11
|
+
end
|
12
|
+
|
13
|
+
def == other
|
14
|
+
self.class == other.class and @information_keys.all? do |key|
|
15
|
+
send(key) == other.send(key)
|
16
|
+
end
|
17
|
+
rescue NoMethodError
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
# apply("string").regparse("string") # => Success
|
22
|
+
class Success < Result
|
23
|
+
attr_accessor :matching_string
|
24
|
+
end
|
25
|
+
|
26
|
+
# apply(/\d+/).regparse("123") # => Valid
|
27
|
+
# apply(/\d+/).regparse("123 ") # => Success
|
28
|
+
class Valid < Result
|
29
|
+
attr_accessor :matching_string
|
30
|
+
end
|
31
|
+
|
32
|
+
# apply("string").regparse("str") # => Accepted
|
33
|
+
class Accepted < Result
|
34
|
+
attr_accessor :matching_string
|
35
|
+
end
|
36
|
+
|
37
|
+
# apply("string").regparse("invalid") # => Invalid
|
38
|
+
class Invalid < Result
|
39
|
+
end
|
40
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module RegParsec::StateAttributesHelpers
|
2
|
+
|
3
|
+
def try_convert_into_state_attributes! attributes
|
4
|
+
case attributes
|
5
|
+
when ::RegParsec::StateAttributes then attributes
|
6
|
+
when ::Hash then ::RegParsec::StateAttributes.new(attributes)
|
7
|
+
else raise TypeError, "Can't convert #{attributes.class} into RegParsec::StateAttributes"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class RegParsec::StateAttributes
|
13
|
+
|
14
|
+
def initialize attributes={}
|
15
|
+
commit! attributes
|
16
|
+
end
|
17
|
+
|
18
|
+
def [] *args, &block
|
19
|
+
@head.send :[], *args, &block
|
20
|
+
end
|
21
|
+
|
22
|
+
def []= *args, &block
|
23
|
+
@head.send :[]=, *args, &block
|
24
|
+
end
|
25
|
+
|
26
|
+
def method_missing f, *args, &block
|
27
|
+
if f.to_s =~ /^(.*?)(\=)?$/ and @head.keys.map(&:to_sym).include? $1.to_sym or $2
|
28
|
+
send :"[]#{$2}", $1.to_sym, *args, &block
|
29
|
+
else
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def checkout! commit
|
35
|
+
@head = Hash[*commit.map { |key, val| [key, (val.clone rescue val)] }.flatten(1)]
|
36
|
+
end
|
37
|
+
|
38
|
+
def backdate!
|
39
|
+
checkout! commits.pop
|
40
|
+
end
|
41
|
+
|
42
|
+
def refresh!
|
43
|
+
checkout! commits.last
|
44
|
+
end
|
45
|
+
|
46
|
+
def commit! commit = @head
|
47
|
+
commits << commit
|
48
|
+
refresh!
|
49
|
+
end
|
50
|
+
|
51
|
+
def merge! commit
|
52
|
+
checkout! merge commit
|
53
|
+
end
|
54
|
+
|
55
|
+
protected
|
56
|
+
|
57
|
+
def head
|
58
|
+
@head
|
59
|
+
end
|
60
|
+
|
61
|
+
def updated_commit
|
62
|
+
commits.last
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def commits
|
68
|
+
@commits ||= []
|
69
|
+
end
|
70
|
+
|
71
|
+
def merge commit
|
72
|
+
commit = case commit
|
73
|
+
when ::RegParsec::StateAttributes then commit.updated_commit
|
74
|
+
when Hash then commit
|
75
|
+
end
|
76
|
+
@head.merge(commit)
|
77
|
+
end
|
78
|
+
end
|
data/regparsec.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "regparsec"
|
3
|
+
s.version = File.read("VERSION")
|
4
|
+
s.authors = ["pasberth"]
|
5
|
+
s.description = %{A parsing library}
|
6
|
+
s.summary = %q{}
|
7
|
+
s.email = "pasberth@gmail.com"
|
8
|
+
s.extra_rdoc_files = ["README.rdoc"]
|
9
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
10
|
+
s.homepage = "http://github.com/pasberth/RegParsec"
|
11
|
+
s.require_paths = ["lib"]
|
12
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
13
|
+
s.files = `git ls-files`.split("\n")
|
14
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
15
|
+
s.add_development_dependency "rake"
|
16
|
+
s.add_development_dependency "rspec"
|
17
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class ExampleDelegation
|
4
|
+
|
5
|
+
include ::RegParsec::RegparserDelegatable
|
6
|
+
|
7
|
+
def __build_regparser__
|
8
|
+
apply("abc", "def")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe ExampleDelegation do
|
13
|
+
|
14
|
+
example { subject.parse("abc").should == nil }
|
15
|
+
example { subject.regparse("abc").should == ::RegParsec::Result::Accepted.new( :return_value => ["abc", ""], :matching_string => "abc" ) }
|
16
|
+
example { subject.parse("a").should == nil }
|
17
|
+
example { subject.regparse("a").should == ::RegParsec::Result::Accepted.new( :return_value => ["a"], :matching_string => "a" ) }
|
18
|
+
example { subject.parse("abcd").should == nil }
|
19
|
+
example { subject.regparse("abcd").should == ::RegParsec::Result::Accepted.new( :return_value => ["abc", "d"], :matching_string => "abcd" ) }
|
20
|
+
example { subject.regparse("abcdef").should == ::RegParsec::Result::Success.new( :return_value => ["abc", "def"], :matching_string => "abcdef" ) }
|
21
|
+
example { subject.parse("abcdef").should == ["abc", "def"] }
|
22
|
+
example { subject.regparse("def").should == ::RegParsec::Result::Invalid.new }
|
23
|
+
example { subject.parse("def").should == nil }
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ::RegParsec::Regparser do
|
4
|
+
subject { described_class.new("abc") }
|
5
|
+
|
6
|
+
example { subject.parse("abc").should == ["abc"] }
|
7
|
+
example { subject.regparse("abc").should == ::RegParsec::Result::Success.new( :return_value => ["abc"], :matching_string => "abc" ) }
|
8
|
+
example { subject.parse("abcabc").should == ["abc", "abc"] }
|
9
|
+
example { subject.regparse("abcabc").should == ::RegParsec::Result::Success.new( :return_value => ["abc", "abc"], :matching_string => "abcabc" ) }
|
10
|
+
example { subject.parse("def").should be_nil }
|
11
|
+
example { subject.regparse("def").should == ::RegParsec::Result::Invalid.new }
|
12
|
+
example { subject.parse("abcdef").should == ["abc"] }
|
13
|
+
example { subject.regparse("abcdef").should == ::RegParsec::Result::Success.new( :return_value => ["abc"], :matching_string => "abc" ) }
|
14
|
+
example { subject.parse("abcab").should == ["abc"] }
|
15
|
+
example { subject.regparse("abcab").should == ::RegParsec::Result::Success.new( :return_value => ["abc"], :matching_string => "abc" ) }
|
16
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RegParsec::Regparsers::ApplyParser do
|
4
|
+
|
5
|
+
subject { described_class.new.curry!("abc", "def") }
|
6
|
+
|
7
|
+
example { subject.parse("abc").should be_nil }
|
8
|
+
example { subject.regparse("abc").should == ::RegParsec::Result::Accepted.new( :return_value => ["abc", ""], :matching_string => "abc" ) }
|
9
|
+
example { subject.parse("a").should be_nil }
|
10
|
+
example { subject.regparse("a").should == ::RegParsec::Result::Accepted.new( :return_value => ["a"], :matching_string => "a" ) }
|
11
|
+
example { subject.parse("abcd").should be_nil }
|
12
|
+
example { subject.regparse("abcd").should == ::RegParsec::Result::Accepted.new( :return_value => ["abc", "d"], :matching_string => "abcd" ) }
|
13
|
+
example { subject.regparse("abcdef").should == ::RegParsec::Result::Success.new( :return_value => ["abc", "def"], :matching_string => "abcdef" ) }
|
14
|
+
example { subject.parse("abcdef").should == ["abc", "def"] }
|
15
|
+
example { subject.regparse("def").should == ::RegParsec::Result::Invalid.new }
|
16
|
+
example { subject.parse("def").should be_nil }
|
17
|
+
|
18
|
+
context "valid input" do
|
19
|
+
subject { described_class.new.curry!(/.*/) }
|
20
|
+
example { subject.parse("abc").should_not be_nil }
|
21
|
+
example { subject.regparse("abc").should be_is_a ::RegParsec::Result::Valid }
|
22
|
+
example { subject.parse("abc\n").should_not be_nil }
|
23
|
+
example { subject.regparse("abc\n").should be_is_a ::RegParsec::Result::Success }
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RegParsec::Regparsers::BetweenParser do
|
4
|
+
|
5
|
+
subject { described_class.new.curry!('"', '"', "abc") }
|
6
|
+
|
7
|
+
example { subject.parse(%q_"abc"_).should == "abc" }
|
8
|
+
example { subject.regparse(%q_"abc"_).should == ::RegParsec::Result::Success.new( :return_value => "abc", :matching_string => %q_"abc"_ ) }
|
9
|
+
example { subject.parse(%q_"abc" "abc"_).should == "abc" }
|
10
|
+
example { subject.regparse(%q_"abc" "abc"_).should == ::RegParsec::Result::Success.new( :return_value => "abc", :matching_string => %q_"abc"_ ) }
|
11
|
+
example { subject.parse(%q_"a"_).should == nil }
|
12
|
+
example { subject.regparse(%q_"a"_).should == ::RegParsec::Result::Invalid.new }
|
13
|
+
example { subject.parse(%q_"abcd"_).should == nil }
|
14
|
+
example { subject.regparse(%q_"abcd"_).should == ::RegParsec::Result::Invalid.new }
|
15
|
+
example { subject.parse("abc").should == nil }
|
16
|
+
example { subject.regparse("abc").should == ::RegParsec::Result::Invalid.new }
|
17
|
+
example { subject.parse(%q_abc"_).should == nil }
|
18
|
+
example { subject.regparse(%q_abc"_).should == ::RegParsec::Result::Invalid.new }
|
19
|
+
example { subject.parse(%q_"abc_).should == nil }
|
20
|
+
example { subject.regparse(%q_"abc_).should == ::RegParsec::Result::Accepted.new( :return_value => "abc", :matching_string => %q_"abc_) }
|
21
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ::RegParsec::Regparsers::GiveStateParser do
|
4
|
+
subject { described_class.new.curry(:x, ::RegParsec::Regparsers.apply) }
|
5
|
+
|
6
|
+
example { subject.parse( :input => 'abc', :x => 'abc' ).should == ["abc"] }
|
7
|
+
example { subject.regparse( :input => 'abc', :x => 'abc' ).should == ::RegParsec::Result::Success.new( :return_value => ['abc'], :matching_string => 'abc' ) }
|
8
|
+
example { subject.parse( :input => 'def', :x => 'abc' ).should be_nil }
|
9
|
+
example { subject.regparse( :input => 'def', :x => 'abc' ).should == ::RegParsec::Result::Invalid.new }
|
10
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RegParsec::Regparsers::Many1Parser do
|
4
|
+
subject { described_class.new.curry!("abc") }
|
5
|
+
|
6
|
+
example { subject.parse("abc").should == ["abc"] }
|
7
|
+
example { subject.regparse("abc").should == ::RegParsec::Result::Valid.new( :return_value => ["abc"], :matching_string => "abc" ) }
|
8
|
+
example { subject.parse("a").should be_nil }
|
9
|
+
example { subject.regparse("a").should == ::RegParsec::Result::Accepted.new( :return_value => "a", :matching_string => "a" ) }
|
10
|
+
example { subject.parse("abca").should == ["abc"] }
|
11
|
+
example { subject.regparse("abca").should == ::RegParsec::Result::Valid.new( :return_value => ["abc"], :matching_string => "abc" ) }
|
12
|
+
example { subject.parse("d").should be_nil }
|
13
|
+
example { subject.regparse("d").should == ::RegParsec::Result::Invalid.new }
|
14
|
+
example { subject.parse("abcd").should == ["abc"] }
|
15
|
+
example { subject.regparse("abcd").should == ::RegParsec::Result::Success.new( :return_value => ["abc"], :matching_string => "abc" ) }
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RegParsec::Regparsers::ManyParser do
|
4
|
+
subject { described_class.new.curry!("abc") }
|
5
|
+
|
6
|
+
example { subject.parse("abc").should == ["abc"] }
|
7
|
+
example { subject.regparse("abc").should == ::RegParsec::Result::Valid.new( :return_value => ["abc"], :matching_string => "abc" ) }
|
8
|
+
example { subject.parse("a").should == [] }
|
9
|
+
example { subject.regparse("a").should == ::RegParsec::Result::Valid.new( :return_value => [], :matching_string => "" ) }
|
10
|
+
example { subject.parse("abca").should == ["abc"] }
|
11
|
+
example { subject.regparse("abca").should == ::RegParsec::Result::Valid.new( :return_value => ["abc"], :matching_string => "abc" ) }
|
12
|
+
example { subject.parse("d").should == [] }
|
13
|
+
example { subject.regparse("d").should == ::RegParsec::Result::Success.new( :return_value => [], :matching_string => "" ) }
|
14
|
+
example { subject.parse("abcd").should == ["abc"] }
|
15
|
+
example { subject.regparse("abcd").should == ::RegParsec::Result::Success.new( :return_value => ["abc"], :matching_string => "abc" ) }
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RegParsec::Regparsers::OneOfParser do
|
4
|
+
subject { described_class.new.curry!("abc", "def") }
|
5
|
+
|
6
|
+
example { subject.parse("abc").should == "abc" }
|
7
|
+
example { subject.regparse("abc").should == ::RegParsec::Result::Success.new( :return_value => "abc", :matching_string => "abc" ) }
|
8
|
+
example { subject.parse("a").should == nil }
|
9
|
+
example { subject.regparse("a").should == ::RegParsec::Result::Accepted.new( :return_value => "a", :matching_string => "a" ) }
|
10
|
+
example { subject.parse("def").should == "def" }
|
11
|
+
example { subject.regparse("def").should == ::RegParsec::Result::Success.new( :return_value => "def", :matching_string => "def" ) }
|
12
|
+
example { subject.parse("d").should == nil }
|
13
|
+
example { subject.regparse("d").should == ::RegParsec::Result::Accepted.new( :return_value => "d", :matching_string => "d" ) }
|
14
|
+
example { subject.regparse("abcdef").should == ::RegParsec::Result::Success.new( :return_value => "abc", :matching_string => "abc" ) }
|
15
|
+
example { subject.parse("abcdef").should == "abc" }
|
16
|
+
example { subject.regparse("defabc").should == ::RegParsec::Result::Success.new( :return_value => "def", :matching_string => "def" ) }
|
17
|
+
example { subject.parse("defabc").should == "def" }
|
18
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RegParsec::Regparsers::RegexpParser do
|
4
|
+
|
5
|
+
context ' /(.*?);/ case ' do
|
6
|
+
subject { described_class.new.curry!(/(.*?);/) }
|
7
|
+
|
8
|
+
example { subject.parse("abc").should be_nil }
|
9
|
+
example { subject.regparse("abc").should be_is_a ::RegParsec::Result::Invalid }
|
10
|
+
example { subject.parse("abc;")[0].should == "abc;" }
|
11
|
+
example { subject.parse("abc;")[1].should == "abc" }
|
12
|
+
example { subject.regparse("abc;").should be_is_a ::RegParsec::Result::Valid }
|
13
|
+
example { subject.parse("abc;def;")[0].should == "abc;" }
|
14
|
+
example { subject.parse("abc;def;")[1].should == "abc" }
|
15
|
+
example { subject.regparse("abc;def;").should be_is_a ::RegParsec::Result::Success }
|
16
|
+
end
|
17
|
+
|
18
|
+
context ' /./ case ' do
|
19
|
+
subject { described_class.new.curry!(/./) }
|
20
|
+
|
21
|
+
example { subject.parse("a")[0].should == "a" }
|
22
|
+
example { subject.regparse("a").should be_is_a ::RegParsec::Result::Valid }
|
23
|
+
example { subject.parse("ab")[0].should == "a" }
|
24
|
+
example { subject.regparse("ab").should be_is_a ::RegParsec::Result::Success }
|
25
|
+
example { subject.parse("").should be_nil }
|
26
|
+
example { subject.regparse("").should be_is_a ::RegParsec::Result::Invalid }
|
27
|
+
end
|
28
|
+
|
29
|
+
context ' /.*/ case ' do
|
30
|
+
subject { described_class.new.curry!(/.*/) }
|
31
|
+
|
32
|
+
example { subject.parse("abc")[0].should == "abc" }
|
33
|
+
example { subject.regparse("abc").should be_is_a ::RegParsec::Result::Valid }
|
34
|
+
example { subject.parse("abc\n")[0].should == "abc" }
|
35
|
+
example { subject.regparse("abc\n").should be_is_a ::RegParsec::Result::Success }
|
36
|
+
example { subject.parse("abc\ndef")[0].should == "abc" }
|
37
|
+
example { subject.regparse("abc\ndef").should be_is_a ::RegParsec::Result::Success }
|
38
|
+
example { subject.parse("abc\ndef\n")[0].should == "abc" }
|
39
|
+
example { subject.regparse("abc\ndef\n").should be_is_a ::RegParsec::Result::Success }
|
40
|
+
end
|
41
|
+
|
42
|
+
context ' /#(.*)\n/ case ' do
|
43
|
+
subject { described_class.new.curry!(/\#(.*?)\n/) }
|
44
|
+
|
45
|
+
example { subject.parse("abc").should be_nil }
|
46
|
+
example { subject.regparse("abc").should be_is_a ::RegParsec::Result::Invalid }
|
47
|
+
|
48
|
+
example { subject.parse("# abc\n")[0].should == "# abc\n" }
|
49
|
+
example { subject.parse("# abc\n")[1].should == " abc" }
|
50
|
+
example { subject.regparse("# abc\n").should be_is_a ::RegParsec::Result::Valid }
|
51
|
+
|
52
|
+
example { subject.parse("# abc\n def")[0].should == "# abc\n" }
|
53
|
+
example { subject.parse("# abc\n def")[1].should == " abc" }
|
54
|
+
example { subject.regparse("# abc\n def").should be_is_a ::RegParsec::Result::Success }
|
55
|
+
end
|
56
|
+
|
57
|
+
context ' /#(.*)\n+/ case ' do
|
58
|
+
subject { described_class.new.curry!(/\#(.*?)\n+/) }
|
59
|
+
|
60
|
+
example { subject.parse("abc").should be_nil }
|
61
|
+
example { subject.regparse("abc").should be_is_a ::RegParsec::Result::Invalid }
|
62
|
+
|
63
|
+
example { subject.parse("# abc\n")[0].should == "# abc\n" }
|
64
|
+
example { subject.parse("# abc\n")[1].should == " abc" }
|
65
|
+
example { subject.regparse("# abc\n").should be_is_a ::RegParsec::Result::Valid }
|
66
|
+
|
67
|
+
example { subject.parse("# abc\n def")[0].should == "# abc\n" }
|
68
|
+
example { subject.parse("# abc\n def")[1].should == " abc" }
|
69
|
+
example { subject.regparse("# abc\n def").should be_is_a ::RegParsec::Result::Success }
|
70
|
+
|
71
|
+
example { subject.parse("# abc\n\n\n")[0].should == "# abc\n\n\n" }
|
72
|
+
example { subject.parse("# abc\n\n\n")[1].should == " abc" }
|
73
|
+
example { subject.regparse("# abc\n\n\n").should be_is_a ::RegParsec::Result::Valid }
|
74
|
+
|
75
|
+
example { subject.parse("# abc\n\n\n def")[0].should == "# abc\n\n\n" }
|
76
|
+
example { subject.parse("# abc\n\n\n def")[1].should == " abc" }
|
77
|
+
example { subject.regparse("# abc\n\n\n def").should be_is_a ::RegParsec::Result::Success }
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RegParsec::Regparsers::StringParser do
|
4
|
+
|
5
|
+
subject { described_class.new.curry!("abc") }
|
6
|
+
|
7
|
+
example { subject.parse("abc").should == "abc" }
|
8
|
+
example { subject.regparse("abc").should == ::RegParsec::Result::Success.new( :return_value => "abc", :matching_string => "abc" ) }
|
9
|
+
example { subject.parse("ab").should be_nil }
|
10
|
+
example { subject.regparse("ab").should == ::RegParsec::Result::Accepted.new( :return_value => "ab", :matching_string => "ab" ) }
|
11
|
+
example { subject.parse("abcd").should == "abc" }
|
12
|
+
example { subject.regparse("abcd").should == ::RegParsec::Result::Success.new( :return_value => "abc", :matching_string => "abc" ) }
|
13
|
+
example { subject.parse("d").should be_nil }
|
14
|
+
example { subject.regparse("d").should == ::RegParsec::Result::Invalid.new }
|
15
|
+
example { subject.parse("abd").should be_nil }
|
16
|
+
example { subject.regparse("abd").should == ::RegParsec::Result::Invalid.new }
|
17
|
+
end
|
File without changes
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ::RegParsec::Regparsers::UpdateStateParser do
|
4
|
+
subject { described_class.new.curry(:x, "abc") }
|
5
|
+
let(:state) { ::RegParsec::StateAttributes.new( :x => '' ) }
|
6
|
+
|
7
|
+
example do
|
8
|
+
state.input = "abc"
|
9
|
+
subject.parse( state )
|
10
|
+
state.x.should == "abc"
|
11
|
+
end
|
12
|
+
|
13
|
+
example do
|
14
|
+
state.input = "def"
|
15
|
+
subject.parse( state )
|
16
|
+
state.x.should == ''
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'spec_helper'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "result hook" do
|
4
|
+
subject { ::RegParsec::Regparsers.apply("abc", "def") { |list| list.join ', ' } }
|
5
|
+
|
6
|
+
example { subject.parse("abc").should == nil }
|
7
|
+
example { subject.regparse("abc").should == ::RegParsec::Result::Accepted.new( :return_value => ["abc", ""], :matching_string => "abc" ) }
|
8
|
+
example { subject.parse("a").should == nil }
|
9
|
+
example { subject.regparse("a").should == ::RegParsec::Result::Accepted.new( :return_value => ["a"], :matching_string => "a" ) }
|
10
|
+
example { subject.parse("abcd").should == nil }
|
11
|
+
example { subject.regparse("abcd").should == ::RegParsec::Result::Accepted.new( :return_value => ["abc", "d"], :matching_string => "abcd" ) }
|
12
|
+
example { subject.regparse("abcdef").should == ::RegParsec::Result::Success.new( :return_value => "abc, def", :matching_string => "abcdef" ) }
|
13
|
+
example { subject.parse("abcdef").should == "abc, def" }
|
14
|
+
example { subject.regparse("def").should == ::RegParsec::Result::Invalid.new }
|
15
|
+
example { subject.parse("def").should == nil }
|
16
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ::RegParsec::StateAttributes do
|
4
|
+
|
5
|
+
context "Getting and Setting to the :x" do
|
6
|
+
|
7
|
+
subject { described_class.new(:x => 0) }
|
8
|
+
|
9
|
+
example { subject[:x].should == 0 }
|
10
|
+
example { subject[:x] = 1; subject[:x].should == 1 }
|
11
|
+
example { subject[:y].should be_nil }
|
12
|
+
example { subject[:y] = 1; subject[:y].should == 1 }
|
13
|
+
|
14
|
+
example { expect { subject.x }.should_not raise_error NoMethodError }
|
15
|
+
example { expect { subject.x = 0 }.should_not raise_error NoMethodError }
|
16
|
+
example { expect { subject.y }.should raise_error NoMethodError }
|
17
|
+
example { expect { subject.y = 0 }.should_not raise_error NoMethodError }
|
18
|
+
example { subject.y = 1; expect { subject.y }.should_not raise_error NoMethodError }
|
19
|
+
|
20
|
+
example { subject.x.should == 0 }
|
21
|
+
example { subject.x = 1; subject.x.should == 1 }
|
22
|
+
example { subject.y = 1; subject.y.should == 1 }
|
23
|
+
end
|
24
|
+
|
25
|
+
context "Substitute and Refresh" do
|
26
|
+
|
27
|
+
subject { described_class.new(:x => 0) }
|
28
|
+
|
29
|
+
example { subject.x == 0 }
|
30
|
+
example { subject.x = 1; subject.x == 1 }
|
31
|
+
|
32
|
+
example { subject.x = 1; subject.refresh!; subject.x == 0 }
|
33
|
+
example { subject.x = 1; subject.refresh!; subject.commit!; subject.x == 0 }
|
34
|
+
|
35
|
+
example { subject.x = 1; subject.commit!; subject.x == 1 }
|
36
|
+
example { subject.x = 1; subject.commit!; subject.refresh!; subject.x == 1 }
|
37
|
+
|
38
|
+
example { subject.x = 1; subject.commit!; subject.backdate!; subject.x == 1 }
|
39
|
+
example { subject.x = 1; subject.commit!; subject.backdate!; subject.refresh!; subject.x == 0 }
|
40
|
+
|
41
|
+
example { subject.merge!(:x => 1); subject.x == 1 }
|
42
|
+
example { subject.merge!(:x => 1); subject.refresh!; subject.x == 0 }
|
43
|
+
end
|
44
|
+
|
45
|
+
context "Destructive change and Refresh" do
|
46
|
+
|
47
|
+
subject { described_class.new(:x => 'a') }
|
48
|
+
|
49
|
+
example { subject.x == 'a' }
|
50
|
+
example { subject.x << 'b'; subject.x == 'ab' }
|
51
|
+
|
52
|
+
example { subject.x << 'b'; subject.refresh!; subject.x == 'a' }
|
53
|
+
example { subject.x << 'b'; subject.refresh!; subject.commit!; subject.x == 'a' }
|
54
|
+
|
55
|
+
example { subject.x << 'b'; subject.commit!; subject.x == 'ab' }
|
56
|
+
example { subject.x << 'b'; subject.commit!; subject.refresh!; subject.x == 'ab' }
|
57
|
+
|
58
|
+
example { subject.x << 'b'; subject.commit!; subject.backdate!; subject.x == 'ab' }
|
59
|
+
example { subject.x << 'b'; subject.commit!; subject.backdate!; subject.refresh!; subject.x == 'a' }
|
60
|
+
end
|
61
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: regparsec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- pasberth
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-24 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &70325019159360 !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: *70325019159360
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &70325019158340 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70325019158340
|
36
|
+
description: A parsing library
|
37
|
+
email: pasberth@gmail.com
|
38
|
+
executables: []
|
39
|
+
extensions: []
|
40
|
+
extra_rdoc_files:
|
41
|
+
- README.rdoc
|
42
|
+
files:
|
43
|
+
- .gitignore
|
44
|
+
- README.rdoc
|
45
|
+
- VERSION
|
46
|
+
- examples/string_parser.rb
|
47
|
+
- lib/regparsec.rb
|
48
|
+
- lib/regparsec/parser/base.rb
|
49
|
+
- lib/regparsec/parser/combinators.rb
|
50
|
+
- lib/regparsec/parser/primary_parsers.rb
|
51
|
+
- lib/regparsec/parser/state.rb
|
52
|
+
- lib/regparsec/regparseable.rb
|
53
|
+
- lib/regparsec/regparser.rb
|
54
|
+
- lib/regparsec/regparser_delegator.rb
|
55
|
+
- lib/regparsec/regparser_helpers.rb
|
56
|
+
- lib/regparsec/regparsers.rb
|
57
|
+
- lib/regparsec/regular_object.rb
|
58
|
+
- lib/regparsec/result.rb
|
59
|
+
- lib/regparsec/result/accepted.rb
|
60
|
+
- lib/regparsec/result/invalid.rb
|
61
|
+
- lib/regparsec/result/success.rb
|
62
|
+
- lib/regparsec/state_attributes.rb
|
63
|
+
- regparsec.gemspec
|
64
|
+
- spec/delegation_spec.rb
|
65
|
+
- spec/regparser_spec.rb
|
66
|
+
- spec/regparsers/apply_parser_spec.rb
|
67
|
+
- spec/regparsers/between_parser_spec.rb
|
68
|
+
- spec/regparsers/give_state_spec.rb
|
69
|
+
- spec/regparsers/many1_parser_spec.rb
|
70
|
+
- spec/regparsers/many_parser_spec.rb
|
71
|
+
- spec/regparsers/one_of_parser_spec.rb
|
72
|
+
- spec/regparsers/regexp_parser_spec.rb
|
73
|
+
- spec/regparsers/string_parser_spec.rb
|
74
|
+
- spec/regparsers/try_parser_spec.rb
|
75
|
+
- spec/regparsers/update_state_parser_spec.rb
|
76
|
+
- spec/regparsers_spec.rb
|
77
|
+
- spec/result_hook_spec.rb
|
78
|
+
- spec/spec_helper.rb
|
79
|
+
- spec/state_attributes_spec.rb
|
80
|
+
homepage: http://github.com/pasberth/RegParsec
|
81
|
+
licenses: []
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options:
|
84
|
+
- --charset=UTF-8
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 1.8.10
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: ''
|
105
|
+
test_files:
|
106
|
+
- spec/delegation_spec.rb
|
107
|
+
- spec/regparser_spec.rb
|
108
|
+
- spec/regparsers/apply_parser_spec.rb
|
109
|
+
- spec/regparsers/between_parser_spec.rb
|
110
|
+
- spec/regparsers/give_state_spec.rb
|
111
|
+
- spec/regparsers/many1_parser_spec.rb
|
112
|
+
- spec/regparsers/many_parser_spec.rb
|
113
|
+
- spec/regparsers/one_of_parser_spec.rb
|
114
|
+
- spec/regparsers/regexp_parser_spec.rb
|
115
|
+
- spec/regparsers/string_parser_spec.rb
|
116
|
+
- spec/regparsers/try_parser_spec.rb
|
117
|
+
- spec/regparsers/update_state_parser_spec.rb
|
118
|
+
- spec/regparsers_spec.rb
|
119
|
+
- spec/result_hook_spec.rb
|
120
|
+
- spec/spec_helper.rb
|
121
|
+
- spec/state_attributes_spec.rb
|
122
|
+
has_rdoc:
|