redparse
文件大小: unknow
源码售价: 5 个金币 积分规则     积分充值
资源说明:RedParse is a ruby parser written in pure ruby.
= RedParse
* http://rubyforge.org/projects/redparse
* http://github.com/coatl/redparse

== DESCRIPTION:

RedParse is a ruby parser (and parser-compiler) written in pure ruby. 
Instead of YACC or ANTLR, it's parse tool is a home-brewed language. (The
tool is (at least) LALR(1)-equivalent and the 'parse language' is 
pretty nice, even in it's current form.)

My intent is to have a completely correct parser for ruby, in 100% 
ruby. And I think I've more or less succeeded. Aside from some fairly
minor quibbles (see below), RedParse can parse all known ruby 1.8 and 1.9 
constructions correctly. Input text may be encoded in ascii, binary, 
utf-8, iso-8859-1, and the euc-* family of encodings. Sjis is not yet 
supported.

== INSTALL:
* gem install redparse #(as root if necessary)

== LICENSE:

RedParse is available under the Library General Public License (LGPL).
Please see COPYING.LGPL for details.

== Benefits:

* Pure ruby, through and through. No part is written in C, YACC, 
  ANTLR, lisp, assembly, intercal, befunge or any other language
  except ruby.
* Pretty AST trees (at least, I think so). 
* AST trees closely mirror the actual structure of source code.
* unparser is built in
* ParseTree format output too, if you want that.
* Did I mention that there's no YACC at all? YACC grammars are 
  notoriously difficult to modify, (I've never successfully done it) 
  but I've found it easy, at times even pleasant to modify the parse 
  rules of this grammar as necessary. 
* Relatively small parser: 70 rules in 240 lines 
  (vs (by my count) 320 rules in 2200 lines for MRI 1.8.7. This is 
  by no means a fair comparison, tho, since RubyLexer does a lot 
  more than MRI's lexer, and MRI's 2200 lines include its 
  actions (which occupy somewhere under 3100 lines in RedParse). 
  Also, what is a rule? I counted most things which required a 
  separate action in MRI's parser, I'm not sure if that's fair.
  On the other hand, RedParse rules require no separate actions 
  anywhere.In the end, I still think RedParse is still much easier to 
  understand than MRI's parse.y.) 
* "loosey-goosey" parser happily parses many expressions which normal 
  ruby considers errors.

== Drawbacks:

* Slow. Not as bad as it used to be, tho.
* Error coverage is sketchy at best
* No warnings at all.
* Unit test takes a fairly long time (much better now, tho! down to 15min).
* Lots of warnings printed during unit test.
* Debugging parse rules is not straightforward.
* "loosey-goosey" parser happily parses many expressions which normal 
  ruby considers errors.



== SYNOPSIS:

  #simple example of usage:

  require 'redparse'
  
  parser=RedParse.new("some ruby code here")
  tree=parser.parse

  tree.walk{|parent,i,subi,node|
    case node
    when RedParse::CallNode: #... do something with method calls
    when RedParse::AssignNode: #... maybe alter assignments somehow
    #.... and so on
    end
  }

  #presumably tree was altered somehow in the walk-"loop" above
  #when done mucking with the tree, you can turn it into one
  #of two other formats: ParseTree s-exps or ruby source code.

  tree.to_parsetree #=> turns a tree into an ParseTree-style s-exp.

  tree.unparse({})  #=> turns a tree back into ruby source code.

  #to understand the tree format, you must understand the node classes,
  #which are documented in the next section.

== NODE TYPES:

Syntax trees are represented by trees of nested Nodes. All Nodes descend from 
Array, and their subnodes can be addressed by numeric index, just like normal
Arrays. However, many subnodes want to have names as well, thus most (but not
all) array slots within the various Node classes have names. The general rule
is that Node slots may contain a Node, a plain Array, a String, or nil. 
However, many cases are more specific than that. Specific Node classes are 
documented briefly below in this format:

 NodeName          #comments describing node
                    (slot1: Type, slot2: Type)
                           -OR-
                    (Array[Type*])

Here's an example of how to use this imaginary Node:

 if NodeName===node
   do_something_with node.slot1
   do_something_else_with node.slot2
         #  -OR-
   do_something_with node[0] #slot1
   do_something_else_with node[1] #slot2
 end

Types are specified in an psuedo-BNF syntax. | * + ? all have the same meaning
as in Regexp. Array[Spec] indicates a plain Array (not a Node). The Spec 
describes the constraints on the Array's contents. 
In the cases where node slots don't have names, there will be no colon-
terminated slot name(s) on the second line, just an Array[] specification.

This is a final depiction of the syntax tree. There may be additions to the
existing format in the future, but no incompatibility-creating changes.

 Several abbreviations are used:
 Expr means ValueNode
 LValue means ConstantNode|VarNode|UnaryStarNode|CallNode|
              BracketsGetNode|AssigneeList[LValue*]
 UnAmpNode means UnOpNode with op == "&"

 Node

本源码包内暂不包含可直接显示的源代码文件,请下载源码包。