erruby_parser 2.3.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +30 -0
  3. data/.travis.yml +23 -0
  4. data/.yardopts +21 -0
  5. data/CHANGELOG.md +3 -0
  6. data/CONTRIBUTING.md +17 -0
  7. data/Gemfile +8 -0
  8. data/LICENSE.txt +25 -0
  9. data/README.md +278 -0
  10. data/Rakefile +158 -0
  11. data/bin/ruby-parse +6 -0
  12. data/bin/ruby-rewrite +6 -0
  13. data/doc/AST_FORMAT.md +1694 -0
  14. data/doc/CUSTOMIZATION.md +37 -0
  15. data/doc/INTERNALS.md +21 -0
  16. data/doc/css/.gitkeep +0 -0
  17. data/doc/css/common.css +68 -0
  18. data/lib/gauntlet_parser.rb +121 -0
  19. data/lib/parser.rb +81 -0
  20. data/lib/parser/all.rb +7 -0
  21. data/lib/parser/ast/node.rb +38 -0
  22. data/lib/parser/ast/processor.rb +234 -0
  23. data/lib/parser/base.rb +268 -0
  24. data/lib/parser/builders/default.rb +1581 -0
  25. data/lib/parser/clobbering_error.rb +11 -0
  26. data/lib/parser/compatibility/ruby1_8.rb +20 -0
  27. data/lib/parser/compatibility/ruby1_9.rb +32 -0
  28. data/lib/parser/current.rb +81 -0
  29. data/lib/parser/diagnostic.rb +163 -0
  30. data/lib/parser/diagnostic/engine.rb +103 -0
  31. data/lib/parser/lexer.rl +2261 -0
  32. data/lib/parser/lexer/dedenter.rb +49 -0
  33. data/lib/parser/lexer/explanation.rb +53 -0
  34. data/lib/parser/lexer/literal.rb +262 -0
  35. data/lib/parser/lexer/stack_state.rb +42 -0
  36. data/lib/parser/macruby.y +2172 -0
  37. data/lib/parser/messages.rb +69 -0
  38. data/lib/parser/meta.rb +27 -0
  39. data/lib/parser/rewriter.rb +119 -0
  40. data/lib/parser/ruby18.y +1917 -0
  41. data/lib/parser/ruby19.y +2149 -0
  42. data/lib/parser/ruby20.y +2325 -0
  43. data/lib/parser/ruby21.y +2334 -0
  44. data/lib/parser/ruby22.y +2341 -0
  45. data/lib/parser/ruby23.y +2351 -0
  46. data/lib/parser/ruby24.y +2347 -0
  47. data/lib/parser/rubymotion.y +2145 -0
  48. data/lib/parser/runner.rb +241 -0
  49. data/lib/parser/runner/ruby_parse.rb +146 -0
  50. data/lib/parser/runner/ruby_rewrite.rb +99 -0
  51. data/lib/parser/source/buffer.rb +333 -0
  52. data/lib/parser/source/comment.rb +120 -0
  53. data/lib/parser/source/comment/associator.rb +201 -0
  54. data/lib/parser/source/map.rb +184 -0
  55. data/lib/parser/source/map/collection.rb +16 -0
  56. data/lib/parser/source/map/condition.rb +19 -0
  57. data/lib/parser/source/map/constant.rb +30 -0
  58. data/lib/parser/source/map/definition.rb +21 -0
  59. data/lib/parser/source/map/for.rb +17 -0
  60. data/lib/parser/source/map/heredoc.rb +17 -0
  61. data/lib/parser/source/map/keyword.rb +18 -0
  62. data/lib/parser/source/map/objc_kwarg.rb +17 -0
  63. data/lib/parser/source/map/operator.rb +15 -0
  64. data/lib/parser/source/map/rescue_body.rb +19 -0
  65. data/lib/parser/source/map/send.rb +34 -0
  66. data/lib/parser/source/map/ternary.rb +16 -0
  67. data/lib/parser/source/map/variable.rb +29 -0
  68. data/lib/parser/source/range.rb +242 -0
  69. data/lib/parser/source/rewriter.rb +473 -0
  70. data/lib/parser/source/rewriter/action.rb +42 -0
  71. data/lib/parser/static_environment.rb +44 -0
  72. data/lib/parser/syntax_error.rb +19 -0
  73. data/lib/parser/version.rb +3 -0
  74. data/parser.gemspec +46 -0
  75. data/test/bug_163/fixtures/input.rb +3 -0
  76. data/test/bug_163/fixtures/output.rb +3 -0
  77. data/test/bug_163/rewriter.rb +18 -0
  78. data/test/bug_163/test_runner_rewrite.rb +35 -0
  79. data/test/helper.rb +41 -0
  80. data/test/parse_helper.rb +258 -0
  81. data/test/racc_coverage_helper.rb +130 -0
  82. data/test/test_base.rb +29 -0
  83. data/test/test_current.rb +25 -0
  84. data/test/test_diagnostic.rb +94 -0
  85. data/test/test_diagnostic_engine.rb +60 -0
  86. data/test/test_encoding.rb +78 -0
  87. data/test/test_lexer.rb +3370 -0
  88. data/test/test_lexer_stack_state.rb +76 -0
  89. data/test/test_parse_helper.rb +80 -0
  90. data/test/test_parser.rb +5518 -0
  91. data/test/test_source_buffer.rb +144 -0
  92. data/test/test_source_comment.rb +34 -0
  93. data/test/test_source_comment_associator.rb +275 -0
  94. data/test/test_source_map.rb +13 -0
  95. data/test/test_source_range.rb +125 -0
  96. data/test/test_source_rewriter.rb +539 -0
  97. data/test/test_source_rewriter_action.rb +44 -0
  98. data/test/test_static_environment.rb +43 -0
  99. metadata +317 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 16faa3521e8c9a9552edbb42a0a693dcb7980f67
4
+ data.tar.gz: 6a133800c59f2cfcc5e4cb14fd623bcac4de7ba3
5
+ SHA512:
6
+ metadata.gz: 74b5903e42f4a09f929a29931be2f77b7fd3adf7be796472ad4e9b7c0dcb8d2a1dc5216a31a7e99afb04a4f31f79b2def5532748e3a7a5928472690a4f632940
7
+ data.tar.gz: 2f8d42ffaaddc5ae8907cfeb342ed8bdff1ba655de0e2675c314c754d148b39e4b059ced9e5f1ac20d941d45ba8dd19bd0b330e187448b5e56ef2fdc31d86bdb
data/.gitignore ADDED
@@ -0,0 +1,30 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ lib/bundler/man
11
+ pkg
12
+ rdoc
13
+ yardoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.output
19
+ .ruby-version
20
+ .ruby-gemset
21
+ lib/parser/lexer.rb
22
+ lib/parser/ruby18.rb
23
+ lib/parser/ruby19.rb
24
+ lib/parser/ruby20.rb
25
+ lib/parser/ruby21.rb
26
+ lib/parser/ruby22.rb
27
+ lib/parser/ruby23.rb
28
+ lib/parser/ruby24.rb
29
+ lib/parser/macruby.rb
30
+ lib/parser/rubymotion.rb
data/.travis.yml ADDED
@@ -0,0 +1,23 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - 2.2.4
8
+ - 2.3.0
9
+ - ruby-head
10
+ - jruby-18mode
11
+ - jruby-19mode
12
+ - rbx-2
13
+ matrix:
14
+ allow_failures:
15
+ - rvm: ruby-head
16
+ - rvm: rbx-2
17
+ before_install:
18
+ - gem update bundler
19
+ - bundle --version
20
+ - gem update --system 2.1.11
21
+ - gem --version
22
+ script:
23
+ - bundle exec rake test_cov
data/.yardopts ADDED
@@ -0,0 +1,21 @@
1
+ ./lib/parser/**/*.rb ./lib/parser.rb
2
+ -m markdown
3
+ -M kramdown
4
+ -o ./yardoc
5
+ -r ./README.md
6
+ --asset ./doc/css/common.css:css/common.css
7
+ --verbose
8
+ --api public
9
+ --exclude lib/parser/lexer.rb
10
+ --exclude lib/parser/ruby18.rb
11
+ --exclude lib/parser/ruby19.rb
12
+ --exclude lib/parser/ruby20.rb
13
+ --exclude lib/parser/ruby21.rb
14
+ --exclude lib/parser/ruby22.rb
15
+ --exclude lib/parser/ruby23.rb
16
+ --exclude lib/parser/ruby24.rb
17
+ --exclude lib/parser/macruby.rb
18
+ --exclude lib/parser/rubymotion.rb
19
+ -
20
+ ./doc/*.md
21
+ LICENSE.txt
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ Changelog
2
+ =========
3
+
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,17 @@
1
+ Contributing to Parser
2
+ ----------------------
3
+
4
+ Parser employs a script to extract information from VCS (git) log and form a Changelog file. Thus, each commit which affects the public API in any way must be marked with one of the following sigils, or characters at the beginning of line:
5
+
6
+ * `-` for bugfixes. For example: `- lexer.rl: fixed lexing of "alias $foo $bar".`
7
+ * `+` for features. For example: `+ Implemented Parser::Rewriter, a module for non-intrusive rewriting of source code.`
8
+ * `*` for miscellaneous changes. For example: `* Converted measurement units from metric to imperial.`
9
+
10
+ Versioning
11
+ ----------
12
+
13
+ Parser is versioned as follows:
14
+ * The version starts with the most recent Ruby version that Parser supports (which should be also the most recent released Ruby version).
15
+ * After that, a `.x` is appended, where `x` is incremented for every change.
16
+
17
+ No breaking changes to API will be ever made, except for changes that correct behavior which did not match documentation or Ruby MRI behavior.
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in parser.gemspec
4
+ gemspec
5
+
6
+ # Workaround for bug in Bundler on JRuby
7
+ # See https://github.com/bundler/bundler/issues/4157
8
+ gem 'ast', '>= 1.1', '< 3.0'
data/LICENSE.txt ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2013-2016 whitequark <whitequark@whitequark.org>
2
+
3
+ Parts of the source are derived from ruby_parser:
4
+ Copyright (c) Ryan Davis, seattle.rb
5
+
6
+ MIT License
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining
9
+ a copy of this software and associated documentation files (the
10
+ "Software"), to deal in the Software without restriction, including
11
+ without limitation the rights to use, copy, modify, merge, publish,
12
+ distribute, sublicense, and/or sell copies of the Software, and to
13
+ permit persons to whom the Software is furnished to do so, subject to
14
+ the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be
17
+ included in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,278 @@
1
+ # Parser
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/parser.svg)](https://badge.fury.io/rb/parser)
4
+ [![Build Status](https://travis-ci.org/whitequark/parser.svg?branch=master)](https://travis-ci.org/whitequark/parser)
5
+
6
+ _Parser_ is a production-ready Ruby parser written in pure Ruby. It recognizes as
7
+ much or more code than Ripper, Melbourne, JRubyParser or ruby\_parser, and
8
+ is vastly more convenient to use.
9
+
10
+ You can also use [unparser](https://github.com/mbj/unparser) to produce
11
+ equivalent source code from Parser's ASTs.
12
+
13
+ Sponsored by [Evil Martians](http://evilmartians.com).
14
+ MacRuby and RubyMotion support sponsored by [CodeClimate](http://codeclimate.com).
15
+
16
+ ## Installation
17
+
18
+ $ gem install parser
19
+
20
+ ## Usage
21
+
22
+ Parse a chunk of code:
23
+
24
+ require 'parser/current'
25
+ Parser::Builders::Default.emit_lambda = true # opt-in to most recent AST format
26
+
27
+ p Parser::CurrentRuby.parse("2 + 2")
28
+ # (send
29
+ # (int 2) :+
30
+ # (int 2))
31
+
32
+ Access the AST's source map:
33
+
34
+ p Parser::CurrentRuby.parse("2 + 2").loc
35
+ # #<Parser::Source::Map::Send:0x007fe5a1ac2388
36
+ # @dot=nil,
37
+ # @begin=nil,
38
+ # @end=nil,
39
+ # @selector=#<Source::Range (string) 2...3>,
40
+ # @expression=#<Source::Range (string) 0...5>>
41
+
42
+ p Parser::CurrentRuby.parse("2 + 2").loc.selector.source
43
+ # "+"
44
+
45
+ Traverse the AST: see the documentation for [gem ast](https://whitequark.github.io/ast/).
46
+
47
+ Parse a chunk of code and display all diagnostics:
48
+
49
+ parser = Parser::CurrentRuby.new
50
+ parser.diagnostics.consumer = lambda do |diag|
51
+ puts diag.render
52
+ end
53
+
54
+ buffer = Parser::Source::Buffer.new('(string)')
55
+ buffer.source = "foo *bar"
56
+
57
+ p parser.parse(buffer)
58
+ # (string):1:5: warning: `*' interpreted as argument prefix
59
+ # foo *bar
60
+ # ^
61
+ # (send nil :foo
62
+ # (splat
63
+ # (send nil :bar)))
64
+
65
+ If you reuse the same parser object for multiple `#parse` runs, you need to
66
+ `#reset` it.
67
+
68
+ You can also use the `ruby-parse` utility (it's bundled with the gem) to play
69
+ with Parser:
70
+
71
+ $ ruby-parse -L -e "2+2"
72
+ (send
73
+ (int 2) :+
74
+ (int 2))
75
+ 2+2
76
+ ~ selector
77
+ ~~~ expression
78
+ (int 2)
79
+ 2+2
80
+ ~ expression
81
+ (int 2)
82
+ 2+2
83
+
84
+ $ ruby-parse -E -e "2+2"
85
+ 2+2
86
+ ^ tINTEGER 2 expr_end [0 <= cond] [0 <= cmdarg]
87
+ 2+2
88
+ ^ tPLUS "+" expr_beg [0 <= cond] [0 <= cmdarg]
89
+ 2+2
90
+ ^ tINTEGER 2 expr_end [0 <= cond] [0 <= cmdarg]
91
+ 2+2
92
+ ^ false "$eof" expr_end [0 <= cond] [0 <= cmdarg]
93
+ (send
94
+ (int 2) :+
95
+ (int 2))
96
+
97
+ ## Features
98
+
99
+ * Precise source location reporting.
100
+ * [Documented](doc/AST_FORMAT.md) AST format which is convenient to work with.
101
+ * A simple interface and a powerful, tweakable one.
102
+ * Parses 1.8, 1.9, 2.0, 2.1, 2.2 and 2.3 syntax with backwards-compatible
103
+ AST formats.
104
+ * Parses MacRuby and RubyMotion syntax extensions.
105
+ * [Rewriting][rewriting] support.
106
+ * Parsing error recovery.
107
+ * Improved [clang-like][] diagnostic messages with location information.
108
+ * Written in pure Ruby, runs on MRI 1.8.7 or >=1.9.2, JRuby and Rubinius in 1.8
109
+ and 1.9 mode.
110
+ * Only one runtime dependency: the [ast][] gem.
111
+ * [Insane][insane-lexer] Ruby lexer rewritten from scratch in Ragel.
112
+ * 100% test coverage for Bison grammars (except error recovery).
113
+ * Readable, commented source code.
114
+
115
+ [clang-like]: http://clang.llvm.org/diagnostics.html
116
+ [ast]: https://rubygems.org/gems/ast
117
+ [insane-lexer]: http://whitequark.org/blog/2013/04/01/ruby-hacking-guide-ch-11-finite-state-lexer/
118
+ [rewriting]: http://whitequark.org/blog/2013/04/26/lets-play-with-ruby-code/
119
+
120
+ ## Documentation
121
+
122
+ Documentation for Parser is available [online](https://whitequark.github.io/parser/).
123
+
124
+ ### Node names
125
+
126
+ Several Parser nodes seem to be confusing enough to warrant a dedicated README section.
127
+
128
+ #### (block)
129
+
130
+ The `(block)` node passes a Ruby block, that is, a closure, to a method call represented by its first child, a `(send)`, `(super)` or `(zsuper)` node. To demonstrate:
131
+
132
+ ```
133
+ $ ruby-parse -e 'foo { |x| x + 2 }'
134
+ (block
135
+ (send nil :foo)
136
+ (args
137
+ (arg :x))
138
+ (send
139
+ (lvar :x) :+
140
+ (int 2)))
141
+ ```
142
+
143
+ #### (begin) and (kwbegin)
144
+
145
+ **TL;DR: Unless you perform rewriting, treat `(begin)` and `(kwbegin)` as the same node type.**
146
+
147
+ Both `(begin)` and `(kwbegin)` nodes represent compound statements, that is, several expressions which are executed sequentally and the value of the last one is the value of entire compound statement. They may take several forms in the source code:
148
+
149
+ * `foo; bar`: without delimiters
150
+ * `(foo; bar)`: parenthesized
151
+ * `begin foo; bar; end`: grouped with `begin` keyword
152
+ * `def x; foo; bar; end`: grouped inside a method definition
153
+
154
+ and so on.
155
+
156
+ ```
157
+ $ ruby-parse -e '(foo; bar)'
158
+ (begin
159
+ (send nil :foo)
160
+ (send nil :bar))
161
+ $ ruby-parse -e 'def x; foo; bar end'
162
+ (def :x
163
+ (args)
164
+ (begin
165
+ (send nil :foo)
166
+ (send nil :bar)))
167
+ ```
168
+
169
+ Note that, despite its name, `kwbegin` node only has tangential relation to the `begin` keyword. Normally, Parser AST is semantic, that is, if two constructs look differently but behave identically, they get parsed to the same node. However, there exists a peculiar construct called post-loop in Ruby:
170
+
171
+ ```
172
+ begin
173
+ body
174
+ end while condition
175
+ ```
176
+
177
+ This specific syntactic construct, that is, keyword `begin..end` block followed by a postfix `while`, [behaves][postloop] very unlike other similar constructs, e.g. `(body) while condition`. While the body itself is wrapped into a `while-post` node, Parser also supports rewriting, and in that context it is important to not accidentally convert one kind of loop into another.
178
+
179
+ [postloop]: http://rosettacode.org/wiki/Loops/Do-while#Ruby
180
+
181
+ ```
182
+ $ ruby-parse -e 'begin foo end while cond'
183
+ (while-post
184
+ (send nil :cond)
185
+ (kwbegin
186
+ (send nil :foo)))
187
+ $ ruby-parse -e 'foo while cond'
188
+ (while
189
+ (send nil :cond)
190
+ (send nil :foo))
191
+ $ ruby-parse -e '(foo) while cond'
192
+ (while
193
+ (send nil :cond)
194
+ (begin
195
+ (send nil :foo)))
196
+ ```
197
+
198
+ (Parser also needs the `(kwbegin)` node type internally, and it is highly problematic to map it back to `(begin)`.)
199
+
200
+ ## Compatibility with Ruby MRI
201
+
202
+ Unfortunately, Ruby MRI often changes syntax in patchlevel versions. This has happened, at least, for every release since 1.9; for example, commits [c5013452](https://github.com/ruby/ruby/commit/c501345218dc5fb0fae90d56a0c6fd19d38df5bb) and [04bb9d6b](https://github.com/ruby/ruby/commit/04bb9d6b75a55d4000700769eead5a5cb942c25b) were backported all the way from HEAD to 1.9. Moreover, there is no simple way to track these changes.
203
+
204
+ This policy makes it all but impossible to make Parser precisely compatible with the Ruby MRI parser. Indeed, at September 2014, it would be necessary to maintain and update ten different parsers together with their lexer quirks in order to be able to emulate any given released Ruby MRI version.
205
+
206
+ As a result, Parser chooses a different path: the `parser/rubyXY` parsers recognize the syntax of the latest minor version of Ruby MRI X.Y at the time of the gem release.
207
+
208
+ ## Compatibility with MacRuby and RubyMotion
209
+
210
+ Parser implements the MacRuby 0.12 and RubyMotion mid-2015 parsers precisely. However, the lexers of these have been forked off Ruby MRI and independently maintained for some time, and because of that, Parser may accept some code that these upstream implementations are unable to parse.
211
+
212
+ ## Known issues
213
+
214
+ Adding support for the following Ruby MRI features in Parser would needlessly complicate it, and as they all are very specific and rarely occuring corner cases, this is not done.
215
+
216
+ Parser has been extensively tested; in particular, it parses almost entire [Rubygems][rg] corpus. For every issue, a breakdown of affected gems is offered.
217
+
218
+ [rg]: https://rubygems.org
219
+
220
+ ### Void value expressions
221
+
222
+ Ruby MRI prohibits so-called "void value expressions". For a description
223
+ of what a void value expression is, see [this
224
+ gist](https://gist.github.com/JoshCheek/5625007) and [this Parser
225
+ issue](https://github.com/whitequark/parser/issues/72).
226
+
227
+ It is unknown whether any gems are affected by this issue.
228
+
229
+ ### Invalid characters inside comments and literals
230
+
231
+ Ruby MRI permits arbitrary non-7-bit byte sequences to appear in comments, as well as in string or symbol literals in form of escape sequences, regardless of source encoding. Parser requires all source code, including the expanded escape sequences, to consist of valid byte sequences in the source encoding that are convertible to UTF-8.
232
+
233
+ As of 2013-07-25, there are about 180 affected gems.
234
+
235
+ ### \u escape in 1.8 mode
236
+
237
+ Ruby MRI 1.8 permits to specify a bare `\u` escape sequence in a string; it treats it like `u`. Ruby MRI 1.9 and later treat `\u` as a prefix for Unicode escape sequence and do not allow it to appear bare. Parser follows 1.9+ behavior.
238
+
239
+ As of 2013-07-25, affected gems are: activerdf, activerdf_net7, fastreader, gkellog-reddy.
240
+
241
+ ### Dollar-dash
242
+
243
+ (This one is so obscure I couldn't even think of a saner name for this issue.) Pre-2.1 Ruby allows
244
+ to specify a global variable named `$-`. Ruby 2.1 and later treat it as a syntax error. Parser
245
+ follows 2.1 behavior.
246
+
247
+ No known code is affected by this issue.
248
+
249
+ ## Contributors
250
+
251
+ * [whitequark][]
252
+ * Markus Schirp ([mbj][])
253
+ * Yorick Peterse ([yorickpeterse][])
254
+ * Magnus Holm ([judofyr][])
255
+ * Bozhidar Batsov ([bbatsov][])
256
+
257
+ [whitequark]: https://github.com/whitequark
258
+ [mbj]: https://github.com/mbj
259
+ [yorickpeterse]: https://github.com/yorickpeterse
260
+ [judofyr]: https://github.com/judofyr
261
+ [bbatsov]: https://github.com/bbatsov
262
+
263
+ ## Acknowledgements
264
+
265
+ The lexer testsuite is derived from
266
+ [ruby\_parser](https://github.com/seattlerb/ruby_parser).
267
+
268
+ The Bison parser rules are derived from [Ruby MRI](https://github.com/ruby/ruby)
269
+ parse.y.
270
+
271
+ ## Contributing
272
+
273
+ 1. Make sure you have [Ragel ~> 6.7](http://www.complang.org/ragel/) installed
274
+ 2. Fork it
275
+ 3. Create your feature branch (`git checkout -b my-new-feature`)
276
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
277
+ 5. Push to the branch (`git push origin my-new-feature`)
278
+ 6. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,158 @@
1
+ # encoding:utf-8
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
5
+ require 'rake/clean'
6
+
7
+ task :default => [:test]
8
+
9
+ Rake::TestTask.new do |t|
10
+ t.libs = %w(test/ lib/)
11
+ t.test_files = FileList["test/**/test_*.rb"]
12
+ t.warning = false
13
+ end
14
+
15
+ task :test_cov do
16
+ ENV['COVERAGE'] = '1'
17
+ Rake::Task['test'].invoke
18
+ end
19
+
20
+ task :build => [:generate_release, :changelog]
21
+
22
+ GENERATED_FILES = %w(lib/parser/lexer.rb
23
+ lib/parser/ruby18.rb
24
+ lib/parser/ruby19.rb
25
+ lib/parser/ruby20.rb
26
+ lib/parser/ruby21.rb
27
+ lib/parser/ruby22.rb
28
+ lib/parser/ruby23.rb
29
+ lib/parser/ruby24.rb
30
+ lib/parser/macruby.rb
31
+ lib/parser/rubymotion.rb)
32
+
33
+ CLEAN.include(GENERATED_FILES)
34
+
35
+ desc 'Generate the Ragel lexer and Racc parser.'
36
+ task :generate => GENERATED_FILES do
37
+ Rake::Task[:ragel_check].invoke
38
+ GENERATED_FILES.each do |filename|
39
+ content = File.read(filename)
40
+ content = "# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*-\n" + content
41
+
42
+ File.open(filename, 'w') do |io|
43
+ io.write content
44
+ end
45
+ end
46
+ end
47
+
48
+ task :regenerate => [:clean, :generate]
49
+
50
+ desc 'Generate the Ragel lexer and Racc parser in release mode.'
51
+ task :generate_release => [:clean_env, :regenerate]
52
+
53
+ task :clean_env do
54
+ ENV.delete 'RACC_DEBUG'
55
+ end
56
+
57
+ task :ragel_check do
58
+ require 'cliver'
59
+ Cliver.assert('ragel', '~> 6.7')
60
+ end
61
+
62
+ desc 'Generate YARD documentation'
63
+ task :yard => :generate do
64
+ sh('yard doc')
65
+ end
66
+
67
+ PAGES_REPO = 'git@github.com:whitequark/parser'
68
+
69
+ desc "Build and deploy documentation to GitHub pages"
70
+ task :pages do
71
+ system "git clone #{PAGES_REPO} gh-temp/ -b gh-pages; rm gh-temp/* -rf; touch gh-temp/.nojekyll" or abort
72
+ system "yardoc -o gh-temp/;" or abort
73
+ system "cd gh-temp/; git add -A; git commit -m 'Updated pages.'; git push -f origin gh-pages" or abort
74
+ FileUtils.rm_rf 'gh-temp'
75
+ end
76
+
77
+ desc 'Generate Changelog'
78
+ task :changelog do
79
+ fs = "\u{fffd}"
80
+ format = "%d#{fs}%s#{fs}%an#{fs}%ai"
81
+
82
+ # Format: version => { commit-class => changes }
83
+ changelog = Hash.new do |hash, version|
84
+ hash[version] = Hash.new do |hash, klass|
85
+ hash[klass] = []
86
+ end
87
+ end
88
+
89
+ branch = `git describe HEAD --all`.strip.gsub(/.+\/([^\/]+)$/, '\1')
90
+
91
+ IO.popen("git log --pretty='#{format}' " \
92
+ "remotes/origin/2.0 remotes/origin/2.1 remotes/origin/2.2 #{branch}", 'r') do |io|
93
+ current_version = nil
94
+
95
+ io.each_line do |line|
96
+ version, message, author, date = line.
97
+ match(/^(?: \((.*)\))?#{fs}(.*)#{fs}(.*)#{fs}(.*)$/o).captures
98
+ date = Date.parse(date)
99
+
100
+ current_version = "#{$1} (#{date})" if version =~ /(v[\d\w.]+)/
101
+ current_version = "v#{Parser::VERSION} (#{date})" \
102
+ if version =~ /(^| |\/)#{Regexp.escape branch}$/
103
+
104
+ next if current_version.nil?
105
+ changelog[current_version] # add a hash
106
+
107
+ next if message !~ /^[+*-]/
108
+ changelog[current_version][message[0]] << "#{message[1..-1]} (#{author})"
109
+ end
110
+ end
111
+
112
+ commit_classes = {
113
+ '*' => 'API modifications:',
114
+ '+' => 'Features implemented:',
115
+ '-' => 'Bugs fixed:',
116
+ }
117
+
118
+ File.open('CHANGELOG.md', 'w') do |io|
119
+ io.puts 'Changelog'
120
+ io.puts '========='
121
+ io.puts
122
+
123
+ changelog.each do |version, commits|
124
+ io.puts version
125
+ io.puts '-' * version.length
126
+ io.puts
127
+
128
+ commit_classes.each do |sigil, description|
129
+ next unless commits[sigil].any?
130
+
131
+ io.puts description
132
+ commits[sigil].uniq.each do |commit|
133
+ io.puts " * #{commit.gsub('<', '\<').lstrip}"
134
+ end
135
+ io.puts
136
+ end
137
+ end
138
+ end
139
+
140
+ sh('git commit CHANGELOG.md -m "Update changelog." || true')
141
+ end
142
+
143
+ rule '.rb' => '.rl' do |t|
144
+ sh "ragel -F1 -R #{t.source} -o #{t.name}"
145
+ end
146
+
147
+ rule '.rb' => '.y' do |t|
148
+ opts = [ "--superclass=Parser::Base",
149
+ t.source,
150
+ "-o", t.name
151
+ ]
152
+ opts << "--no-line-convert" unless ENV['RACC_DEBUG']
153
+ opts << "--debug" if ENV['RACC_DEBUG']
154
+
155
+ sh "racc", *opts
156
+ end
157
+
158
+ task :test => [:generate]