regparsec 0.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.
- 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:
|