Module: RParsec::Parsers

Extended by:
Parsers
Included in:
Keywords, Parsers
Defined in:
lib/rparsec/parsers.rb

Overview

This module provides all out-of-box parser implementations.

Instance Method Summary collapse

Instance Method Details

#alt(*alts) ⇒ Object

A parser that calls alternative parsers until one succeeds.



74
75
76
# File 'lib/rparsec/parsers.rb', line 74

def alt(*alts)
  AltParser.new(alts)
end

#among(*vals) ⇒ Object

A parser that succeeds when the the current input is among the given values.



108
109
110
111
112
# File 'lib/rparsec/parsers.rb', line 108

def among(*vals)
  expected = "one of [#{vals.join(', ')}] expected"
  vals = as_list vals
  satisfies(expected) { |c| vals.include? c }
end

#anyObject

A parser that consumes one input.



236
237
238
# File 'lib/rparsec/parsers.rb', line 236

def any
  AnyParser.new
end

#are(vals, expected = "#{vals} expected") ⇒ Object

A parser that tries to match the current inputs one by one with the given values. It succeeds only when all given values are matched, in which case all the matched inputs are consumed.



160
161
162
# File 'lib/rparsec/parsers.rb', line 160

def are(vals, expected = "#{vals} expected")
  AreParser.new(vals, expected)
end

#arent(vals, expected = "#{vals} unexpected") ⇒ Object

A parser that makes sure that the given values don’t match the current inputs. One input is consumed if it succeeds.



168
169
170
# File 'lib/rparsec/parsers.rb', line 168

def arent(vals, expected = "#{vals} unexpected")
  are(vals, '').not(expected) >> any
end

#char(c) ⇒ Object

A parser that succeeds when the the current input is the given character.



126
127
128
129
130
131
132
133
# File 'lib/rparsec/parsers.rb', line 126

def char(c)
  if c.kind_of? Integer
    nm = c.chr
    is(c, "'#{nm}' expected").tap { |p| p.name = nm }
  else
    is(c[0], "'#{c}' expected").tap { |p| p.name = c }
  end
end

#comment_block(open, close) ⇒ Object

A parser that parses a chunk of text started with open and ended by close. nil is the result.



361
362
363
# File 'lib/rparsec/parsers.rb', line 361

def comment_block open, close
  string(open) >> not_string(close).many_ >> string(close) >> value(nil)
end

#comment_line(start) ⇒ Object

A parser that parses a line started with start. nil is the result.



353
354
355
# File 'lib/rparsec/parsers.rb', line 353

def comment_line start
  string(start) >> not_char(?\n).many_ >> char(?\n).optional >> value(nil)
end

#eof(expected = "EOF expected") ⇒ Object

A parser that succeeds when there’s no input available.



150
151
152
# File 'lib/rparsec/parsers.rb', line 150

def eof(expected = "EOF expected")
  EofParser.new(expected).tap { |p| p.name = "EOF" }
end

#failure(msg) ⇒ Object

A parser that always fails with the given error message.



52
53
54
# File 'lib/rparsec/parsers.rb', line 52

def failure msg
  FailureParser.new(msg)
end

#get_indexObject

A parser that returns the current input index (starting from 0).



203
204
205
# File 'lib/rparsec/parsers.rb', line 203

def get_index
  GetIndexParser.new.tap { |p| p.name = 'get_index' }
end

#integer(expected = 'integer expected') ⇒ Object

A parser that parses an integer and return the matched integer as string.



292
293
294
# File 'lib/rparsec/parsers.rb', line 292

def integer(expected = 'integer expected')
  regexp(/\d+(?!\w)/, expected)
end

#is(v, expected = "#{v} expected") ⇒ Object

A parser that succeeds when the the current input is equal to the given value. expected is the error message when the predicate returns false.



92
93
94
# File 'lib/rparsec/parsers.rb', line 92

def is(v, expected = "#{v} expected")
  satisfies(expected) { |c| c == v }
end

#isnt(v, expected = "#{v} unexpected") ⇒ Object

A parser that succeeds when the the current input is not equal to the given value. expected is the error message when the predicate returns false.



101
102
103
# File 'lib/rparsec/parsers.rb', line 101

def isnt(v, expected = "#{v} unexpected")
  satisfies(expected) { |c| c != v }
end

#lazy(&block) ⇒ Object

A lazy parser, when executed, calls the given block to get a parser object and delegate the call to this lazily instantiated parser.



370
371
372
# File 'lib/rparsec/parsers.rb', line 370

def lazy(&block)
  LazyParser.new(block)
end

#longest(*parsers) ⇒ Object Also known as: longer

A parser that tries all given alternative parsers and picks the one with the longest match.



218
219
220
# File 'lib/rparsec/parsers.rb', line 218

def longest(*parsers)
  BestParser.new(parsers, true)
end

#map(&block) ⇒ Object

A parser that maps current parser result to a new result using the given block.

Different from Parser#map, this method does not need to be combined with any Parser object. It is rather an independent Parser object that maps the current parser result.

parser1.map { |x| ... } is equivalent to parser1 >> map { |x| ... }.

See also Parser#>>.



417
418
419
420
# File 'lib/rparsec/parsers.rb', line 417

def map(&block)
  return one unless block
  MapCurrentParser.new(block)
end

#mapn(&block) ⇒ Object

A parser that maps current parser result to a new result using the given block. If the current parser result is an array, the array elements are expanded and then passed as parameters to the block.

Different from Parser#mapn, this method does not need to be combined with any Parser object. It is rather an independent Parser object that maps the current parser result.

parser1.mapn { |x, y| ... } is equivalent to parser1 >> mapn { |x, y| ... }.

See also Parser#>>.



437
438
439
440
# File 'lib/rparsec/parsers.rb', line 437

def mapn(&block)
  return one unless block
  MapnCurrentParser.new(block)
end

#not_among(*vals) ⇒ Object

A parser that succeeds when the the current input is not among the given values.



117
118
119
120
121
# File 'lib/rparsec/parsers.rb', line 117

def not_among(*vals)
  expected = "one of [#{vals.join(', ')}] unexpected"
  vals = as_list vals
  satisfies(expected) { |c| !vals.include? c }
end

#not_char(c) ⇒ Object

A parser that succeeds when the the current input is not the given character.



138
139
140
141
142
143
144
145
# File 'lib/rparsec/parsers.rb', line 138

def not_char(c)
  if c.kind_of? Integer
    nm = c.chr
    isnt(c, "'#{nm}' unexpected").tap { |p| p.name = "~#{nm}" }
  else
    isnt(c[0], "'#{c}' unexpected").tap { |p| p.name = "~#{c}" }
  end
end

#not_string(str, msg = "\"#{str}\" unexpected") ⇒ Object

A parser that makes sure that the current input doesn’t match a string. One character is consumed if it succeeds.



183
184
185
# File 'lib/rparsec/parsers.rb', line 183

def not_string(str, msg = "\"#{str}\" unexpected")
  string(str).not(msg) >> any
end

#number(expected = 'number expected') ⇒ Object

A parser that parses a number (integer, or decimal number) and return the matched number as string.



300
301
302
# File 'lib/rparsec/parsers.rb', line 300

def number(expected = 'number expected')
  regexp(/\d+(\.\d+)?/, expected)
end

#oneObject

A parser that always succeeds.



250
251
252
# File 'lib/rparsec/parsers.rb', line 250

def one
  OneParser.new
end

#range(from, to, msg = "#{as_char from}..#{as_char to} expected") ⇒ Object

A parser that succeeds if the current input is within a certain range.



257
258
259
260
261
# File 'lib/rparsec/parsers.rb', line 257

def range(from, to, msg = "#{as_char from}..#{as_char to} expected")
  from = as_num(from)
  to = as_num(to)
  satisfies(msg) { |c| c <= to && c >= from }
end

#regexp(ptn, expected = "/#{ptn}/ expected") ⇒ Object

A parser that succeeds if the current inputs match the given regular expression. The matched string is consumed and returned as result.



275
276
277
# File 'lib/rparsec/parsers.rb', line 275

def regexp(ptn, expected = "/#{ptn}/ expected")
  RegexpParser.new(as_regexp(ptn), expected).tap { |p| p.name = expected }
end

#satisfies(expected, &pred) ⇒ Object

A parser that succeeds when the given predicate returns true (with the current input as the parameter). expected is the error message when pred returns false.



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

def satisfies(expected, &pred)
  SatisfiesParser.new(pred, expected)
end

#sequence(*parsers, &proc) ⇒ Object

A parser that sequentially run the given parsers. The result of the last parser is used as return value. If a block is given, the results of the parsers are passed into the block as parameters, and the block return value is used as result instead.



196
197
198
# File 'lib/rparsec/parsers.rb', line 196

def sequence(*parsers, &proc)
  SequenceParser.new(parsers, proc)
end

#set_index(ind) ⇒ Object

A parser that moves the current input pointer to a certain index.



210
211
212
# File 'lib/rparsec/parsers.rb', line 210

def set_index ind
  SetIndexParser.new(ind).tap { |p| p.name = "set_index" }
end

#shortest(*parsers) ⇒ Object Also known as: shorter

A parser that tries all given alternative parsers and picks the one with the shortest match.



226
227
228
# File 'lib/rparsec/parsers.rb', line 226

def shortest(*parsers)
  BestParser.new(parsers, false)
end

#string(str, msg = "\"#{str}\" expected") ⇒ Object Also known as: str

A parser that matches the given string.



175
176
177
# File 'lib/rparsec/parsers.rb', line 175

def string(str, msg = "\"#{str}\" expected")
  are(str, msg).tap { |p| p.name = str }
end

#string_nocase(str, expected = "'#{str}' expected") ⇒ Object

A parser that matches the given string, case insensitively.



307
308
309
# File 'lib/rparsec/parsers.rb', line 307

def string_nocase(str, expected = "'#{str}' expected")
  StringCaseInsensitiveParser.new(str, expected).tap { |p| p.name = str }
end

#sum(*alts) ⇒ Object

A parser that calls alternative parsers until one succeed, or any failure with input consumption beyond the current look-ahead.



67
68
69
# File 'lib/rparsec/parsers.rb', line 67

def sum(*alts)
  PlusParser.new(alts)
end

#throwp(symbol) ⇒ Object

A parser that throws a symbol.



266
267
268
# File 'lib/rparsec/parsers.rb', line 266

def throwp(symbol)
  ThrowParser.new(symbol)
end

#token(*kinds, &proc) ⇒ Object

A parser that succeeds when the current input is a token with one of the the given token kinds. If a block is given, the token text is passed to the block as parameter, and the block return value is used as result. Otherwise, the token object is used as result.



318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/rparsec/parsers.rb', line 318

def token(*kinds, &proc)
  expected = "#{kinds.join(' or ')} expected"
  recognizer = nil
  if kinds.length == 1
    kind = kinds[0]
    recognizer = satisfies(expected) do |tok|
      tok.respond_to? :kind, :text and kind == tok.kind
    end
  else
    recognizer = satisfies(expected) do |tok|
      tok.respond_to? :kind, :text and kinds.include? tok.kind
    end
  end
  recognizer = recognizer.map { |tok| proc.call(tok.text) } if proc
  recognizer
end

#value(v) ⇒ Object

A parser that always succeeds with the given return value.



59
60
61
# File 'lib/rparsec/parsers.rb', line 59

def value v
  ValueParser.new(v)
end

#watch(&block) ⇒ Object

A parser that watches the current parser result without changing it. The following assert will succeed:

char(?a) >> watch { |x| assert_equal(?a, x) }

watch can also be used as a handy tool to print trace information, for example:

some_parser >> watch { puts "some_parser succeeded." }


385
386
387
388
# File 'lib/rparsec/parsers.rb', line 385

def watch(&block)
  return one unless block
  WatchParser.new(block)
end

#watchn(&block) ⇒ Object

A parser that watches the current parser result without changing it. The following assert will succeed:

char(?a).repeat(2) >> watchn { |x, y| assert_equal([?a, ?a], [x, y]) }

Slightly different from #watch, watchn expands the current parser result before passing it into the associated block.



399
400
401
402
# File 'lib/rparsec/parsers.rb', line 399

def watchn(&block)
  return one unless block
  WatchnParser.new(block)
end

#whitespace(expected = "whitespace expected") ⇒ Object

A parser that parses a white space character.



338
339
340
# File 'lib/rparsec/parsers.rb', line 338

def whitespace(expected = "whitespace expected")
  satisfies(expected) { |c| Whitespaces.include? c }
end

#whitespaces(expected = "whitespace(s) expected") ⇒ Object

A parser that parses 1 or more white space characters.



345
346
347
# File 'lib/rparsec/parsers.rb', line 345

def whitespaces(expected = "whitespace(s) expected")
  whitespace(expected).many_(1)
end

#word(expected = 'word expected') ⇒ Object

A parser that parses a word (starting with alpha or underscore, followed by 0 or more alpha, number or underscore). and return the matched word as string.



284
285
286
# File 'lib/rparsec/parsers.rb', line 284

def word(expected = 'word expected')
  regexp(/[a-zA-Z_]\w*/, expected)
end

#zeroObject

A parser that always fails.



243
244
245
# File 'lib/rparsec/parsers.rb', line 243

def zero
  ZeroParser.new
end