Parent

Files

Parslet::Atoms::Base

Base class for all parslets, handles orchestration of calls and implements a lot of the operator and chaining methods.

Also see Parslet::Atoms::DSL chaining parslet atoms together.

Public Class Methods

precedence(prec) click to toggle source

Debug printing - in Treetop syntax.

# File lib/parslet/atoms/base.rb, line 130
def self.precedence(prec)
  define_method(:precedence) { prec }
end

Public Instance Methods

accept(visitor) click to toggle source
# File lib/parslet/atoms/visitor.rb, line 7
def accept(visitor)
  raise NotImplementedError, "No #accept method on #{self.class.name}."
end
apply(source, context, consume_all=false) click to toggle source
Calls the #try method of this parslet. Success consumes input, error will 
rewind the input. 

@param source [Parslet::Source] source to read input from

 @param context [Parslet::Atoms::Context] context to use for the parsing

@param consume_all [Boolean] true if the current parse must consume
  all input by itself.
# File lib/parslet/atoms/base.rb, line 80
def apply(source, context, consume_all=false)
  old_pos = source.bytepos
  
  success, value = result = context.try_with_cache(self, source, consume_all)

  if success
    # If a consume_all parse was made and doesn't result in the consumption
    # of all the input, that is considered an error. 
    if consume_all && source.chars_left>0
      # Read 10 characters ahead. Why ten? I don't know. 
      offending_pos   = source.pos
      offending_input = source.consume(10)
      
      # Rewind input (as happens always in error case)
      source.bytepos  = old_pos
      
      return context.err_at(
        self, 
        source, 
        "Don't know what to do with #{offending_input.to_s.inspect}", 
        offending_pos
      ) 
    end
    
    # Looks like the parse was successful after all. Don't rewind the input.
    return result
  end
  
  # We only reach this point if the parse has failed. Rewind the input.
  source.bytepos = old_pos
  return result
end
cached?() click to toggle source

Returns true if this atom can be cached in the packrat cache. Most parslet atoms are cached, so this always returns true, unless overridden.

# File lib/parslet/atoms/base.rb, line 124
def cached?
  true
end
inspect() click to toggle source
# File lib/parslet/atoms/base.rb, line 141
def inspect
  to_s(OUTER)
end
parse(io, options={}) click to toggle source

Given a string or an IO object, this will attempt a parse of its contents and return a result. If the parse fails, a Parslet::ParseFailed exception will be thrown.

@param io [String, Source] input for the parse process @option options [Parslet::ErrorReporter] :reporter error reporter to use,

defaults to Parslet::ErrorReporter::Tree

@option options [Boolean] :prefix Should a prefix match be accepted?

(default: false)

@return [Hash, Array, Parslet::Slice] PORO (Plain old Ruby object) result

tree
# File lib/parslet/atoms/base.rb, line 23
def parse(io, options={})
  source = io.respond_to?(:line_and_column) ? 
    io : 
    Parslet::Source.new(io)

  # Try to cheat. Assuming that we'll be able to parse the input, don't 
  # run error reporting code. 
  success, value = setup_and_apply(source, nil, !options[:prefix])
  
  # If we didn't succeed the parse, raise an exception for the user. 
  # Stack trace will be off, but the error tree should explain the reason
  # it failed.
  unless success
    # Cheating has not paid off. Now pay the cost: Rerun the parse,
    # gathering error information in the process.
    reporter = options[:reporter] || Parslet::ErrorReporter::Tree.new
    source.bytepos = 0
    success, value = setup_and_apply(source, reporter, !options[:prefix])
    
    fail "Assertion failed: success was true when parsing with reporter"          if success
    
    # Value is a Parslet::Cause, which can be turned into an exception:
    value.raise
    
    fail "NEVER REACHED"
  end
  
  # assert: success is true

  # Extra input is now handled inline with the rest of the parsing. If 
  # really we have success == true, prefix: false and still some input 
  # is left dangling, that is a BUG.
  if !options[:prefix] && source.chars_left > 0
    fail "BUG: New error strategy should not reach this point."
  end
  
  return flatten(value)
end
parse_with_debug(str, opts={}) click to toggle source

Packages the common idiom

begin
  tree = parser.parse('something')
rescue Parslet::ParseFailed => error
  puts parser.cause.ascii_tree
end

into a convenient method.

Usage:

require 'parslet'
require 'parslet/convenience'

class FooParser < Parslet::Parser
  rule(:foo) { str('foo') }
  root(:foo)
end

FooParser.new.parse_with_debug('bar')

@see Parslet::Atoms::Base#parse

# File lib/parslet/convenience.rb, line 27
def parse_with_debug str, opts={}
  parse str, opts
rescue Parslet::ParseFailed => error
  puts error.cause.ascii_tree
end
setup_and_apply(source, error_reporter, consume_all) click to toggle source

Creates a context for parsing and applies the current atom to the input. Returns the parse result.

@return [<Boolean, Object>] Result of the parse. If the first member is

true, the parse has succeeded.
# File lib/parslet/atoms/base.rb, line 68
def setup_and_apply(source, error_reporter, consume_all)
  context = Parslet::Atoms::Context.new(error_reporter)
  apply(source, context, consume_all)
end
to_s(outer_prec=OUTER) click to toggle source
# File lib/parslet/atoms/base.rb, line 134
def to_s(outer_prec=OUTER)
  if outer_prec < precedence
    "("+to_s_inner(precedence)+")"
  else
    to_s_inner(precedence)
  end
end
try(source, context, consume_all) click to toggle source

Override this in your Atoms::Base subclasses to implement parsing behaviour.

# File lib/parslet/atoms/base.rb, line 116
def try(source, context, consume_all)
  raise NotImplementedError,        "Atoms::Base doesn't have behaviour, please implement #try(source, context)."
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.