Class: RParsec::Parser

Inherits:
Object
  • Object
show all
Extended by:
DefHelper, Signature
Includes:
Functors, Monad
Defined in:
lib/rparsec/parser.rb

Overview

Represents a parser that parses a certain grammar rule.

Constant Summary collapse

MyMonad =
ParserMonad.new

Constants included from Functors

Functors::And, Functors::At, Functors::BitAnd, Functors::Call, Functors::Compare, Functors::Dec, Functors::Div, Functors::Eq, Functors::Feed, Functors::Fst, Functors::Ge, Functors::Gt, Functors::Id, Functors::Idn, Functors::Inc, Functors::Le, Functors::Lt, Functors::Match, Functors::Minus, Functors::Mod, Functors::Mul, Functors::Ne, Functors::Neg, Functors::Not, Functors::Or, Functors::Plus, Functors::Power, Functors::Snd, Functors::Succ, Functors::To_a, Functors::To_f, Functors::To_i, Functors::To_s, Functors::To_sym, Functors::Union, Functors::Xor

Instance Attribute Summary collapse

Attributes included from Monad

#this

Instance Method Summary collapse

Methods included from Signature

def_sig

Methods included from DefHelper

def_ctor, def_mutable, def_readable

Methods included from Monad

#bind, #initMonad, #plus, #value

Methods included from Functors

#compose, #const, #curry, #flip, make_curry, make_reverse_curry, #nth, #power, #reverse_curry, #reverse_uncurry, #uncurry

Instance Attribute Details

#nameObject

Returns the value of attribute name.



16
17
18
# File 'lib/rparsec/parser.rb', line 16

def name
  @name
end

Instance Method Details

#>>(other) ⇒ Object

Similar to seq. other is auto-boxed if it is not of type Parser.



440
441
442
# File 'lib/rparsec/parser.rb', line 440

def >>(other)
  seq(autobox_parser(other))
end

#atomizeObject

Create a new parser that’s atomic., meaning that when it fails, input consumption is undone.



125
126
127
# File 'lib/rparsec/parser.rb', line 125

def atomize
  AtomParser.new(self).setName(@name)
end

#bindn(&block) ⇒ Object

self is first executed, the parser result is then passed as parameter to the associated block, which evaluates to another Parser object at runtime. This new Parser object is then executed to get the final parser result.

Different from bind, parser result of self will be expanded first if it is an array.



105
106
107
108
# File 'lib/rparsec/parser.rb', line 105

def bindn(&block)
  return self unless block
  BoundnParser.new(self, block)
end

#catchp(symbol) ⇒ Object

a.catchp(:somesymbol) will catch the :somesymbol thrown by a.



303
304
305
# File 'lib/rparsec/parser.rb', line 303

def catchp(symbol)
  CatchParser.new(symbol, self)
end

#delimited(delim) ⇒ Object

To create a parser that repeats self for unlimited times, with the pattern recognized by delim as separator that separates each occurrence and also possibly ends the pattern. Return values of self are collected in an array.



273
274
275
# File 'lib/rparsec/parser.rb', line 273

def delimited delim
  delimited1(delim).plus value([])
end

#delimited1(delim) ⇒ Object

To create a parser that repeats self for unlimited times, with the pattern recognized by delim as separator that separates each occurrence and also possibly ends the pattern. self has to match for at least once. Return values of self are collected in an array.



259
260
261
262
263
264
265
# File 'lib/rparsec/parser.rb', line 259

def delimited1 delim
  rest = delim >> (self.plus Parsers.throwp(:__end_delimiter__))
  self.bind do |v0|
    result = [v0]
    (rest.map { |v| result << v }).many_.catchp(:__end_delimiter__) >> value(result)
  end
end

#expect(msg) ⇒ Object

To create a parser that fails with a given error message.



153
154
155
# File 'lib/rparsec/parser.rb', line 153

def expect msg
  ExpectParser.new(self, msg)
end

#followed(other) ⇒ Object Also known as: <<

a.followed b will sequentially run a and b; result of a is preserved as the ultimate return value.



161
162
163
# File 'lib/rparsec/parser.rb', line 161

def followed(other)
  FollowedParser.new(self, other)
end

#fragmentObject

a.fragment will return the string matched by a.



310
311
312
# File 'lib/rparsec/parser.rb', line 310

def fragment
  FragmentParser.new(self)
end

#infixl(op) ⇒ Object

For left-associative infix binary operator. op has to return a Proc that takes two parameters, who are returned by the self parser as operands.



382
383
384
385
386
387
388
389
390
# File 'lib/rparsec/parser.rb', line 382

def infixl(op)
  Parsers.sequence(self, _infix_rest(op, self).many) do |v, rests|
    rests.each do |r|
      f, v1 = *r
      v = f.call(v, v1)
    end
    v
  end
end

#infixn(op) ⇒ Object

For non-associative infix binary operator. op has to return a Proc that takes two parameters, who are returned by the self parser as operands.



368
369
370
371
372
373
374
375
# File 'lib/rparsec/parser.rb', line 368

def infixn(op)
  bind do |v1|
    bin = Parsers.sequence(op, self) do |f, v2|
      f.call(v1, v2)
    end
    bin | value(v1)
  end
end

#infixr(op) ⇒ Object

For right-associative infix binary operator. op has to return a Proc that takes two parameters, who are returned by the self parser as operands.



397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
# File 'lib/rparsec/parser.rb', line 397

def infixr(op)
  Parsers.sequence(self, _infix_rest(op, self).many) do |v, rests|
    if rests.empty?
      v
    else
      f, seed = *rests.last
      for i in (0...rests.length - 1)
        cur = rests.length - 2 - i
        f1, v1 = *rests[cur]
        seed = f.call(v1, seed)
        f = f1
      end
      f.call(v, seed)
    end
  end
end

#lexeme(delim = Parsers.whitespaces) ⇒ Object

a.lexeme(delim) will parse a for 0 or more times and ignore all patterns recognized by delim. Values returned by a are collected in an array.



327
328
329
330
# File 'lib/rparsec/parser.rb', line 327

def lexeme(delim = Parsers.whitespaces)
  delim = delim.many_
  delim >> self.delimited(delim)
end

#lookahead(_n) ⇒ Object

To create a parser that does “look ahead” for n inputs.



146
147
148
# File 'lib/rparsec/parser.rb', line 146

def lookahead _n
  self
end

#many(least = 0) ⇒ Object

To create a parser that repeats self for at least least times. All return values are collected in an array.



209
210
211
# File 'lib/rparsec/parser.rb', line 209

def many(least = 0)
  ManyParser.new(self, least)
end

#many_(least = 0) ⇒ Object

To create a parser that repeats self for at least least times. parser.many_ is equivalent to bnf notation “parser*”. Only the return value of the last execution is preserved.



201
202
203
# File 'lib/rparsec/parser.rb', line 201

def many_(least = 0)
  Many_Parser.new(self, least)
end

#map(&block) ⇒ Object

a.map{|x|x+1} will first execute parser a, when it succeeds, the associated block is executed to transform the result to a new value (increment it in this case).



93
94
95
96
# File 'lib/rparsec/parser.rb', line 93

def map(&block)
  return self unless block
  MapParser.new(self, block)
end

#mapn(&block) ⇒ Object

a.mapn{|x,y|x+y} will first execute parser a, when it succeeds, the array result (if any) is expanded and passed as parameters to the associated block. The result of the block is then used as the parsing result.



116
117
118
119
# File 'lib/rparsec/parser.rb', line 116

def mapn(&block)
  return self unless block
  MapnParser.new(self, block)
end

#nested(parser) ⇒ Object

a.nested b will feed the token array returned by parser a to parser b for a nested parsing.



318
319
320
# File 'lib/rparsec/parser.rb', line 318

def nested(parser)
  NestedParser.new(self, parser)
end

#not(msg = "#{self} unexpected") ⇒ Object Also known as: ~

To create a new parser that succeed only if self fails.



139
140
141
# File 'lib/rparsec/parser.rb', line 139

def not(msg = "#{self} unexpected")
  NotParser.new(self, msg)
end

#optional(default = nil) ⇒ Object

a.optional(default) is equivalent to a.plus(value(default))



296
297
298
# File 'lib/rparsec/parser.rb', line 296

def optional(default = nil)
  self.plus(value(default))
end

#parse(src) ⇒ Object

parses a string.

Raises:



68
69
70
71
72
73
74
75
76
77
# File 'lib/rparsec/parser.rb', line 68

def parse(src)
  ctxt = ParseContext.new(src)
  return ctxt.result if _parse ctxt
  ctxt.prepare_error
  locator = CodeLocator.new(src)
  raise ParserException.new(ctxt.error.index),
    _add_location_to_error(locator, ctxt,
      _add_encountered_error(ctxt.to_msg,
         _display_current_input(ctxt.error.input, src, ctxt.index)), src)
end

#peekObject

Create a new parser that looks at inputs whthout consuming them.



132
133
134
# File 'lib/rparsec/parser.rb', line 132

def peek
  PeekParser.new(self).setName(@name)
end

#postfix(op) ⇒ Object

For postfix unary operator. a.postfix op will run parser a for once and then op for 0 or more times. op should return a Proc that accepts one parameter. Proc objects returned by op is then fed with the value returned by a from left to right. The final result is returned as return value.



356
357
358
359
360
361
# File 'lib/rparsec/parser.rb', line 356

def postfix(op)
  Parsers.sequence(self, op.many) do |v, funcs|
    funcs.each { |f| v = f.call(v) }
    v
  end
end

#prefix(op) ⇒ Object

For prefix unary operator. a.prefix op will run parser op for 0 or more times and eventually run parser a for one time. op should return a Proc that accepts one parameter. Proc objects returned by op is then fed with the value returned by a from right to left. The final result is returned as return value.



341
342
343
344
345
346
# File 'lib/rparsec/parser.rb', line 341

def prefix(op)
  Parsers.sequence(op.many, self) do |funcs, v|
    funcs.reverse_each { |f| v = f.call(v) }
    v
  end
end

#repeat(min, max = min) ⇒ Object

To create a parser that repeats self for a minimum min times, and maximally max times. All return values are collected in an array.



187
188
189
190
191
192
193
194
# File 'lib/rparsec/parser.rb', line 187

def repeat(min, max = min)
  return Parsers.failure("min=#{min}, max=#{max}") if min > max
  if min == max
    RepeatParser.new(self, max)
  else
    SomeParser.new(self, min, max)
  end
end

#repeat_(min, max = min) ⇒ Object Also known as: *

To create a parser that repeats self for a minimum min times, and maximally max times. Only the return value of the last execution is preserved.



171
172
173
174
175
176
177
178
179
180
# File 'lib/rparsec/parser.rb', line 171

def repeat_(min, max = min)
  return Parsers.failure("min=#{min}, max=#{max}") if min > max
  if min == max
    return Parsers.one if max <= 0
    return self if max == 1
    Repeat_Parser.new(self, max)
  else
    Some_Parser.new(self, min, max)
  end
end

#separated(delim) ⇒ Object

To create a parser that repeats self for unlimited times, with the pattern recognized by delim as separator that separates each occurrence. Return values of self are collected in an array.



248
249
250
# File 'lib/rparsec/parser.rb', line 248

def separated delim
  separated1(delim).plus value([])
end

#separated1(delim) ⇒ Object

To create a parser that repeats self for unlimited times, with the pattern recognized by delim as separator that separates each occurrence. self has to match for at least once. Return values of self are collected in an array.



235
236
237
238
239
240
241
# File 'lib/rparsec/parser.rb', line 235

def separated1 delim
  rest = delim >> self
  self.bind do |v0|
    result = [v0]
    (rest.map { |v| result << v }).many_ >> value(result)
  end
end

#seq(other, &block) ⇒ Object

a.seq b will sequentially run a then b. The result of b is preserved as return value. If a block is associated, values returned by a and b are passed into the block and the return value of the block is used as the final result of the parser.



431
432
433
434
# File 'lib/rparsec/parser.rb', line 431

def seq(other, &block)
  # TypeChecker.check_arg_type Parser, other, :seq
  Parsers.sequence(self, other, &block)
end

#setName(nm) ⇒ Object

Set name for the parser. self is returned.



83
84
85
86
# File 'lib/rparsec/parser.rb', line 83

def setName(nm)
  @name = nm
  self
end

#some(max) ⇒ Object

To create a parser that repeats self for at most max times. All return values are collected in an array.



225
226
227
# File 'lib/rparsec/parser.rb', line 225

def some(max)
  repeat(0, max)
end

#some_(max) ⇒ Object

To create a parser that repeats self for at most max times. Only the return value of the last execution is preserved.



217
218
219
# File 'lib/rparsec/parser.rb', line 217

def some_(max)
  repeat_(0, max)
end

#to_sObject

String representation



280
281
282
283
# File 'lib/rparsec/parser.rb', line 280

def to_s
  return name unless name.nil?
  self.class.to_s
end

#token(kind) ⇒ Object

a.token(:word_token) will return a Token object when a succeeds. The matched string (or the string returned by a, if any) is encapsulated in the token, together with the :word_token symbol and the starting index of the match.



420
421
422
# File 'lib/rparsec/parser.rb', line 420

def token(kind)
  TokenParser.new(kind, self)
end

#|(other) ⇒ Object

a | b will run b when a fails. b is auto-boxed to Parser when it is not of type Parser.



289
290
291
# File 'lib/rparsec/parser.rb', line 289

def | other
  AltParser.new([self, autobox_parser(other)])
end