rparsec 0.4 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ %w{
2
+ parsers operators keywords expressions
3
+ }.each {|lib| require "rparsec/#{lib}"}
@@ -0,0 +1,66 @@
1
+
2
+
3
+ class ParseContext
4
+ attr_reader :error, :src, :index, :result
5
+ attr_writer :error, :index, :result
6
+ def initialize(src, index=0, error=nil)
7
+ @src, @index, @error = src, index, error
8
+ end
9
+
10
+ def scanner
11
+ @scanner = StringScanner.new(src) if @scanner.nil?
12
+ @scanner.pos= @index
13
+ @scanner
14
+ end
15
+ def prepare_error
16
+ @error.flatten! if @error.kind_of?(Array)
17
+ end
18
+ def to_msg
19
+ return '' if @error.nil?
20
+ return @error.msg unless @error.kind_of?(Array)
21
+ @error.map{|e|e.msg}.join(' or ')
22
+ end
23
+ def error_input
24
+ return nil if @error.nil?
25
+ err = @error
26
+ err = err.last if err.kind_of? Array
27
+ err.input
28
+ end
29
+ def reset_error
30
+ @error = nil
31
+ end
32
+ def current
33
+ @src[@index]
34
+ end
35
+ def eof
36
+ @index >= @src.length
37
+ end
38
+ def available
39
+ @src.length - @index
40
+ end
41
+ def peek i
42
+ @src[@index+i]
43
+ end
44
+ def next
45
+ @index += 1
46
+ end
47
+ def advance n
48
+ @index += n
49
+ end
50
+ def retn(val)
51
+ @result = val
52
+ true
53
+ end
54
+ def failure(msg=nil)
55
+ @error = Failure.new(@index, get_current_input, msg)
56
+ return false
57
+ end
58
+ def expecting(expected=nil)
59
+ @error = Expected.new(@index, get_current_input, expected)
60
+ return false
61
+ end
62
+ def get_current_input
63
+ return nil if eof
64
+ current
65
+ end
66
+ end
@@ -0,0 +1,20 @@
1
+ require 'rparsec/misc'
2
+ class ParserException < StandardError
3
+ extend DefHelper
4
+ def_readable :index
5
+ end
6
+ class Failure
7
+ def initialize(ind, input, msg=nil)
8
+ @index, @input, @msg = ind, input, msg
9
+ end
10
+ attr_reader :index, :input
11
+ attr_writer :index
12
+ def msg
13
+ return @msg.to_s
14
+ end
15
+ Precedence = 100
16
+ end
17
+
18
+ class Expected < Failure
19
+ Precedence = 100
20
+ end
@@ -0,0 +1,137 @@
1
+ require 'rparsec/parser'
2
+
3
+ Associativities = [:prefix, :postfix, :infixn, :infixr, :infixl]
4
+ #
5
+ # This class holds information about operator precedences
6
+ # and associativities.
7
+ # prefix, postfix, infixl, infixr, infixn can be called
8
+ # to register operators.
9
+ #
10
+ class OperatorTable
11
+ #
12
+ # operators attribute is used internally. Do not access it.
13
+ #
14
+ attr_reader :operators
15
+ #
16
+ # Re-initialize the operator table.
17
+ #
18
+ def reinit
19
+ @operators = []
20
+ end
21
+ #
22
+ # To create an OperatorTable instance.
23
+ # If a block is given, it is invoked to do post-instantiation.
24
+ # For example:
25
+ #
26
+ # OperatorTable.new do |tbl|
27
+ # tbl.infixl(char(?+) >> Plus)
28
+ # tbl.infixl(char(?-) >> Minus)
29
+ # tbl.prefix(char(?-) >> Neg)
30
+ # end
31
+ #
32
+ def self.new
33
+ this = allocate
34
+ this.reinit
35
+ if block_given?
36
+ yield this
37
+ end
38
+ this
39
+ end
40
+ private
41
+ #
42
+ # To define methods for registering operator.
43
+ # This is typically used internally.
44
+ #
45
+ def self.def_operator(*kinds)
46
+ kinds.each do |kind|
47
+ define_method(kind) do |op, precedence|
48
+ add(kind, op, precedence)
49
+ end
50
+ end
51
+ end
52
+ def_operator(*Associativities)
53
+ def add(*entry)
54
+ @operators << entry
55
+ self
56
+ end
57
+ end
58
+
59
+ #
60
+ # This module helps build an expression parser
61
+ # using an OperatorTable instance and a parser
62
+ # that parses the term expression.
63
+ #
64
+ module Expressions
65
+ private
66
+ def self.array_to_dict arr
67
+ result = {}
68
+ arr.each_with_index do |key,i|
69
+ result [key] = i unless result.include? key
70
+ end
71
+ result
72
+ end
73
+ KindPrecedence = array_to_dict Associativities
74
+ public
75
+ #
76
+ # build an expression parser using the given term parser
77
+ # and operator table.
78
+ # When _delim_ is specified, patterns recognized by _delim_
79
+ # is automatically ignored.
80
+ #
81
+ def self.build(term, table, delim=nil)
82
+ # sort so that higher precedence first.
83
+ apply_operators(term, prepare_suites(table).sort, delim)
84
+ end
85
+ private
86
+ def self.apply_operators(term, entries, delim)
87
+ # apply operators stored in [[precedence,associativity],[op...]] starting from beginning.
88
+ entries.inject(term) do |result, entry|
89
+ key, ops = *entry
90
+ null, kind_index = *key
91
+ op = ops[0]
92
+ op = Parsers.sum(*ops) if ops.length>1
93
+ apply_operator(result, op, Associativities[kind_index], delim)
94
+ end
95
+ end
96
+ def self.apply_operator(term, op, kind, delim)
97
+ term, op = ignore_rest(term, delim), ignore_rest(op, delim)
98
+ # we could use send here,
99
+ # but explicit case stmt is more straight forward and less coupled with names.
100
+ # performance might be another benefit,
101
+ # though it is not clear whether meta-code is indeed slower than regular ones at all.
102
+ case kind
103
+ when :prefix
104
+ term.prefix(op)
105
+ when :postfix
106
+ term.postfix(op)
107
+ when :infixl
108
+ term.infixl(op)
109
+ when :infixr
110
+ term.infixr(op)
111
+ when :infixn
112
+ term.infixn(op)
113
+ else
114
+ raise ArgumentError, "unknown associativity: #{kind}"
115
+ end
116
+ end
117
+ def self.ignore_rest(parser, delim)
118
+ return parser if delim.nil?
119
+ parser << delim
120
+ end
121
+ def self.prepare_suites(table)
122
+ # create a hash with [precedence, associativity] as key, and op as value.
123
+ suites = {}
124
+ table.operators.each do |entry|
125
+ kind, op, precedence = *entry
126
+ key = [-precedence, KindPrecedence[kind]]
127
+ suite = suites[key]
128
+ if suite.nil?
129
+ suite = [op]
130
+ suites[key] = suite
131
+ else
132
+ suite << op
133
+ end
134
+ end
135
+ suites
136
+ end
137
+ end
@@ -0,0 +1,249 @@
1
+ #
2
+ # This module provides frequently used functors.
3
+ #
4
+ module Functors
5
+ Id = proc {|x|x}
6
+ Idn = proc {|*x|x}
7
+ Neg = proc {|x|-x}
8
+ Inc = proc {|x|x+1}
9
+ Dec = proc {|x|x-1}
10
+ Plus = proc {|x,y|x+y}
11
+ Minus = proc {|x,y|x-y}
12
+ Mul = proc {|x,y|x*y}
13
+ Div = proc {|x,y|x/y}
14
+ Mod = proc {|x,y|x%y}
15
+ Power = proc {|x,y|x**y}
16
+ Not = proc {|x,y|!x}
17
+ And = proc {|x,y|x&&y}
18
+ Or = proc {|x,y|x||y}
19
+ Xor = proc {|x,y|x^y}
20
+ BitAnd = proc {|x,y|x&y}
21
+ Union = proc {|x,y|x|y}
22
+ Match = proc {|x,y|x=~y}
23
+ Eq = proc {|x,y|x==y}
24
+ Ne = proc {|x,y|x!=y}
25
+ Lt = proc {|x,y|x<y}
26
+ Gt = proc {|x,y|x>y}
27
+ Le = proc {|x,y|x<=y}
28
+ Ge = proc {|x,y|x>=y}
29
+ Compare = proc {|x,y|x<=>y}
30
+ Call = proc {|x,y|x.call(y)}
31
+ Feed = proc {|x,y|y.call(x)}
32
+ Fst = proc {|x,_|x}
33
+ Snd = proc {|_, x|x}
34
+ At = proc {|x,y|x[y]}
35
+ To_a = proc {|x|x.to_a}
36
+ To_s = proc {|x|x.to_s}
37
+ To_i = proc {|x|x.to_i}
38
+ To_sym = proc {|x|x.to_sym}
39
+ To_f = proc {|x|x.to_f}
40
+ #
41
+ # Get a Proc, when called, always return the given value.
42
+ #
43
+ def const(v)
44
+ proc {|_|v}
45
+ end
46
+ #
47
+ # Get a Proc, when called, return the nth parameter.
48
+ #
49
+ def nth(n)
50
+ proc {|*args|args[n]}
51
+ end
52
+
53
+
54
+ #
55
+ # Create a Proc, which expects the two parameters
56
+ # in the reverse order of _block_.
57
+ #
58
+ def flip(&block)
59
+ proc {|x,y|block.call(y,x)}
60
+ end
61
+ #
62
+ # Create a Proc, when called, the parameter is
63
+ # first passed into _f2_, _f1_ is called in turn
64
+ # with the return value from _other_.
65
+ #
66
+ def compose(f1, f2)
67
+ proc {|*x|f1.call(f2.call(*x))}
68
+ end
69
+ #
70
+ # Create a Proc that's curriable.
71
+ # When curried, parameters are passed in from left to right.
72
+ # i.e. curry(closure).call(a).call(b) is quivalent to closure.call(a,b) .
73
+ # _block_ is encapsulated under the hood to perform the actual
74
+ # job when currying is done.
75
+ # arity explicitly specifies the number of parameters to curry.
76
+ #
77
+ def curry(arity, &block)
78
+ fail "cannot curry for unknown arity" if arity < 0
79
+ Functors.make_curry(arity, &block)
80
+ end
81
+ #
82
+ # Create a Proc that's curriable.
83
+ # When curried, parameters are passed in from right to left.
84
+ # i.e. reverse_curry(closure).call(a).call(b) is quivalent to closure.call(b,a) .
85
+ # _block_ is encapsulated under the hood to perform the actual
86
+ # job when currying is done.
87
+ # arity explicitly specifies the number of parameters to curry.
88
+ #
89
+ def reverse_curry(arity, &block)
90
+ fail "cannot curry for unknown arity" if arity < 0
91
+ Functors.make_reverse_curry(arity, &block)
92
+ end
93
+ #
94
+ # Uncurry a curried closure.
95
+ #
96
+ def uncurry(&block)
97
+ return block unless block.arity == 1
98
+ proc do |*args|
99
+ result = block
100
+ args.each do |a|
101
+ result = result.call(a)
102
+ end
103
+ result
104
+ end
105
+ end
106
+ #
107
+ # Uncurry a reverse curried closure.
108
+ #
109
+ def reverse_uncurry(&block)
110
+ return block unless block.arity == 1
111
+ proc do |*args|
112
+ result = block
113
+ args.reverse_each do |a|
114
+ result = result.call(a)
115
+ end
116
+ result
117
+ end
118
+ end
119
+ #
120
+ # Create a Proc, when called,
121
+ # repeatedly call _block_ for _n_ times.
122
+ # The same arguments are passed to each invocation.
123
+ #
124
+ def repeat(n, &block)
125
+ proc do |*args|
126
+ result = nil
127
+ n.times {result = block.call(*args)}
128
+ result
129
+ end
130
+ end
131
+ #
132
+ # Create a Proc, when called,
133
+ # repeatedly call _block_ for _n_ times.
134
+ # At each iteration, return value from the previous iteration
135
+ # is used as parameter.
136
+ #
137
+ def power(n, &block)
138
+ return const(nil) if n<=0
139
+ return block if n==1
140
+ proc do |*args|
141
+ result = block.call(*args)
142
+ (n-1).times {result = block.call(result)}
143
+ result
144
+ end
145
+ end
146
+ extend self
147
+ private_class_method
148
+ def self.make_curry(arity, &block)
149
+ return block if arity<=1
150
+ proc do |x|
151
+ make_curry(arity-1) do |*rest|
152
+ block.call(*rest.insert(0, x))
153
+ end
154
+ end
155
+ end
156
+ def self.make_reverse_curry(arity, &block)
157
+ return block if arity <= 1
158
+ proc do |x|
159
+ make_reverse_curry(arity-1) do |*rest|
160
+ block.call(*rest << x)
161
+ end
162
+ end
163
+ end
164
+
165
+
166
+ end
167
+
168
+ #
169
+ # This module provides instance methods that
170
+ # manipulate closures in a functional style.
171
+ # It is typically included in Proc and Method.
172
+ #
173
+ module FunctorMixin
174
+ #
175
+ # Create a Proc, which expects the two parameters
176
+ # in the reverse order of _self_.
177
+ #
178
+ def flip
179
+ Functors.flip(&self)
180
+ end
181
+ #
182
+ # Create a Proc, when called, the parameter is
183
+ # first passed into _other_, _self_ is called in turn
184
+ # with the return value from _other_.
185
+ #
186
+ def compose(other)
187
+ Functors.compose(self, other)
188
+ end
189
+ alias << compose
190
+ #
191
+ # a >> b is equivalent to b << a
192
+ #
193
+ def >> (other)
194
+ other << self
195
+ end
196
+ #
197
+ # Create a Proc that's curriable.
198
+ # When curried, parameters are passed in from left to right.
199
+ # i.e. closure.curry.call(a).call(b) is quivalent to closure.call(a,b) .
200
+ # _self_ is encapsulated under the hood to perform the actual
201
+ # job when currying is done.
202
+ # _ary_ explicitly specifies the number of parameters to curry.
203
+ #
204
+ def curry(ary=arity)
205
+ Functors.curry(ary, &self)
206
+ end
207
+ #
208
+ # Create a Proc that's curriable.
209
+ # When curried, parameters are passed in from right to left.
210
+ # i.e. closure.reverse_curry.call(a).call(b) is quivalent to closure.call(b,a) .
211
+ # _self_ is encapsulated under the hood to perform the actual
212
+ # job when currying is done.
213
+ # _ary_ explicitly specifies the number of parameters to curry.
214
+ #
215
+ def reverse_curry(ary=arity)
216
+ Functors.reverse_curry(ary, &self)
217
+ end
218
+ #
219
+ # Uncurry a curried closure.
220
+ #
221
+ def uncurry
222
+ Functors.uncurry(&self)
223
+ end
224
+ #
225
+ # Uncurry a reverse curried closure.
226
+ #
227
+ def reverse_uncurry
228
+ Functors.reverse_uncurry(&self)
229
+ end
230
+ #
231
+ # Create a Proc, when called,
232
+ # repeatedly call _self_ for _n_ times.
233
+ # The same arguments are passed to each invocation.
234
+ #
235
+ def repeat(n)
236
+ Functors.repeat(n, &self)
237
+ end
238
+ #
239
+ # Create a Proc, when called,
240
+ # repeatedly call _self_ for _n_ times.
241
+ # At each iteration, return value from the previous iteration
242
+ # is used as parameter.
243
+ #
244
+ def power(n)
245
+ Functors.power(n, &self)
246
+ end
247
+ alias ** power
248
+ alias * repeat
249
+ end