Project

General

Profile

Bug #6929 » 0002-Documentation-for-Ripper.patch

zzak (Zachary Scott), 08/31/2012 05:36 AM

View differences:

ext/ripper/lib/ripper.rb
require 'ripper/lexer'
require 'ripper/filter'
require 'ripper/sexp'
# Ripper is a Ruby script parser.
#
# You can get information from the parser with event-based style.
# Information such as abstract syntax trees or simple lexical analysis of the
# Ruby program.
#
# == Usage
#
# Ripper provides an easy interface for parsing your program into a symbolic
# expression tree (or S-expression).
#
# Understanding the output of the parser may come as a challenge, it's
# recommended you use PP to format the output for legibility.
#
# require 'ripper'
# require 'pp'
#
# pp Ripper.sexp('def hello(world); "Hello, #{world}!"; end')
# #=> [:program,
# [[:def,
# [:@ident, "hello", [1, 4]],
# [:paren,
# [:params, [[:@ident, "world", [1, 10]]], nil, nil, nil, nil, nil, nil]],
# [:bodystmt,
# [[:void_stmt],
# [:string_literal,
# [:string_content,
# [:@tstring_content, "Hello, ", [1, 19]],
# [:string_embexpr, [[:var_ref, [:@ident, "world", [1, 28]]]]],
# [:@tstring_content, "!", [1, 34]]]]],
# nil,
# nil,
# nil]]]]
#
# You can see in the example above, the expression starts with +:program+.
#
# From here, a method definition at +:def+, followed by the method's identifier
# <code>:@ident</code>. After the method's identifier comes the parentheses
# +:paren+ and the method parameters under +:params+.
#
# Next is the method body, starting at +:bodystmt+ (+stmt+ meaning statement),
# which contains the full definition of the method.
#
# In our case, we're simply returning a String, so next we have the
# +:void_stmt+ followed by a +:string_literal+.
#
# Within our +:string_literal+ you'll notice two <code>@tstring_content</code>,
# this is the literal part for <code>Hello, </code> and <code>!</code>. Between
# the two <code>@tstring_content</code> statements is a +:string_embexpr+,
# where _embexpr_ is an embedded expression. Our expression consists of a local
# variable, or +var_ref+, with the identifier (<code>@ident</code>) of +world+.
#
# == Resources
#
# * {Ruby Inside}[http://www.rubyinside.com/using-ripper-to-see-how-ruby-is-parsing-your-code-5270.html]
#
# == Requirements
#
# * ruby 1.9 (support CVS HEAD only)
# * bison 1.28 or later (Other yaccs do not work)
#
# == License
#
# Ruby License.
#
# Minero Aoki
# aamine@loveruby.net
# http://i.loveruby.net
class Ripper; end
ext/ripper/lib/ripper/core.rb
class Ripper
# Parses Ruby program read from _src_.
# _src_ must be a String or a IO or a object which has #gets method.
# Parses the given Ruby program read from +src+.
# +src+ must be a String or an IO or a object with a #gets method.
def Ripper.parse(src, filename = '(ripper)', lineno = 1)
new(src, filename, lineno).parse
end
......
end
# This method is called when weak warning is produced by the parser.
# _fmt_ and _args_ is printf style.
# +fmt+ and +args+ is printf style.
def warn(fmt, *args)
end
# This method is called when strong warning is produced by the parser.
# _fmt_ and _args_ is printf style.
# +fmt+ and +args+ is printf style.
def warning(fmt, *args)
end
ext/ripper/lib/ripper/filter.rb
class Ripper
# This class handles only scanner events,
# and they are dispatched in the `right' order (same with input).
# which are dispatched in the 'right' order (same with input).
class Filter
# Creates a new Ripper::Filter instance, passes parameters +src+,
# +filename+, and +lineno+ to Ripper::Lexer.new
#
# The lexer is for internal use only.
def initialize(src, filename = '-', lineno = 1)
@__lexer = Lexer.new(src, filename, lineno)
@__line = nil
......
@__col
end
# Starts parsing. _init_ is a data accumulator.
# It is passed to the next event handler (as of Enumerable#inject).
# Starts the parser.
# +init+ is a data accumulator and is passed to the next event handler (as
# of Enumerable#inject).
def parse(init = nil)
data = init
@__lexer.lex.each do |pos, event, tok|
......
private
# This method is called when some event handler have not defined.
# _event_ is :on_XXX, _token_ is scanned token, _data_ is a data
# accumulator. The return value of this method is passed to the
# next event handler (as of Enumerable#inject).
# This method is called when some event handler is undefined.
# +event+ is :on_XXX, +token+ is the scanned token, and +data+ is a data
# accumulator.
#
# The return value of this method is passed to the next event handler (as
# of Enumerable#inject).
def on_default(event, token, data)
data
end
ext/ripper/lib/ripper/lexer.rb
class Ripper
# Tokenizes Ruby program and returns an Array of String.
# Tokenizes the Ruby program and returns an Array of String.
def Ripper.tokenize(src, filename = '-', lineno = 1)
Lexer.new(src, filename, lineno).tokenize
end
# Tokenizes Ruby program and returns an Array of Array,
# which is formatted like [[lineno, column], type, token].
# Tokenizes the Ruby program and returns an Array of an Array,
# which is formatted like <code>[[lineno, column], type, token]</code>.
#
# require 'ripper'
# require 'pp'
......
class TokenPattern #:nodoc:
class Error < ::StandardError; end
class CompileError < Error; end
class MatchError < Error; end
class Error < ::StandardError # :nodoc:
end
class CompileError < Error # :nodoc:
end
class MatchError < Error # :nodoc:
end
class << self
alias compile new
......
MAP[tok] or raise CompileError, "unknown token: #{tok}"
end
class MatchData
class MatchData # :nodoc:
def initialize(tokens, match)
@tokens = tokens
@match = match
ext/ripper/lib/ripper/sexp.rb
# [EXPERIMENTAL]
# Parses +src+ and create S-exp tree.
# Returns more readable tree rather than Ripper.sexp_raw.
# This method is for mainly developer use.
# This method is mainly for developer use.
#
# require 'ripper'
# require 'pp'
......
# [EXPERIMENTAL]
# Parses +src+ and create S-exp tree.
# This method is for mainly developer use.
# This method is mainly for developer use.
#
# require 'ripper'
# require 'pp'
(2-2/2)