Class: RParsec::Parser
- Inherits:
-
Object
- Object
- RParsec::Parser
- Defined in:
- lib/rparsec/parser.rb
Overview
Represents a parser that parses a certain grammar rule.
Direct Known Subclasses
AnyParser, AreParser, AtomParser, BestParser, BoundParser, BoundnParser, CatchParser, EofParser, ExpectParser, FailureParser, FollowedParser, FragmentParser, GetIndexParser, LazyParser, LookAheadSensitiveParser, ManyParser, Many_Parser, MapCurrentParser, MapParser, MapnCurrentParser, MapnParser, NestedParser, OneParser, PeekParser, RegexpParser, RepeatParser, Repeat_Parser, SatisfiesParser, SequenceParser, SetIndexParser, SomeParser, Some_Parser, StringCaseInsensitiveParser, ThrowParser, TokenParser, ValueParser, WatchParser, WatchnParser, ZeroParser
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
-
#name ⇒ Object
Returns the value of attribute name.
Attributes included from Monad
Instance Method Summary collapse
-
#>>(other) ⇒ Object
Similar to seq.
-
#atomize ⇒ Object
Create a new parser that’s atomic., meaning that when it fails, input consumption is undone.
-
#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.
-
#catchp(symbol) ⇒ Object
a.catchp(:somesymbol) will catch the :somesymbol thrown by a.
-
#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.
-
#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.
-
#expect(msg) ⇒ Object
To create a parser that fails with a given error message.
-
#followed(other) ⇒ Object
(also: #<<)
a.followed b will sequentially run a and b; result of a is preserved as the ultimate return value.
-
#fragment ⇒ Object
a.fragment will return the string matched by a.
-
#infixl(op) ⇒ Object
For left-associative infix binary operator.
-
#infixn(op) ⇒ Object
For non-associative infix binary operator.
-
#infixr(op) ⇒ Object
For right-associative infix binary operator.
-
#lexeme(delim = Parsers.whitespaces) ⇒ Object
a.lexeme(delim) will parse a for 0 or more times and ignore all patterns recognized by delim.
-
#lookahead(_n) ⇒ Object
To create a parser that does “look ahead” for n inputs.
-
#many(least = 0) ⇒ Object
To create a parser that repeats self for at least least times.
-
#many_(least = 0) ⇒ Object
To create a parser that repeats self for at least least times.
-
#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).
-
#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.
-
#nested(parser) ⇒ Object
a.nested b will feed the token array returned by parser a to parser b for a nested parsing.
-
#not(msg = "#{self} unexpected") ⇒ Object
(also: #~)
To create a new parser that succeed only if self fails.
-
#optional(default = nil) ⇒ Object
a.optional(default) is equivalent to a.plus(value(default)).
-
#parse(src) ⇒ Object
parses a string.
-
#peek ⇒ Object
Create a new parser that looks at inputs whthout consuming them.
-
#postfix(op) ⇒ Object
For postfix unary operator.
-
#prefix(op) ⇒ Object
For prefix unary operator.
-
#repeat(min, max = min) ⇒ Object
To create a parser that repeats self for a minimum min times, and maximally max times.
-
#repeat_(min, max = min) ⇒ Object
(also: #*)
To create a parser that repeats self for a minimum min times, and maximally max times.
-
#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.
-
#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.
-
#seq(other, &block) ⇒ Object
a.seq b will sequentially run a then b.
-
#setName(nm) ⇒ Object
Set name for the parser.
-
#some(max) ⇒ Object
To create a parser that repeats self for at most max times.
-
#some_(max) ⇒ Object
To create a parser that repeats self for at most max times.
-
#to_s ⇒ Object
String representation.
-
#token(kind) ⇒ Object
a.token(:word_token) will return a Token object when a succeeds.
-
#|(other) ⇒ Object
a | b will run b when a fails.
Methods included from Signature
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
#name ⇒ Object
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 |
#atomize ⇒ Object
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 |
#fragment ⇒ Object
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.
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 |
#peek ⇒ Object
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_s ⇒ Object
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 |