parser 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -7
- data/.gitignore +1 -0
- data/README.md +1 -1
- data/Rakefile +12 -2
- data/bin/benchmark +3 -3
- data/lib/parser/builders/default.rb +46 -3
- data/lib/parser/current.rb +34 -0
- data/lib/parser/lexer.rb +2760 -2667
- data/lib/parser/lexer.rl +38 -14
- data/lib/parser/ruby18.rb +1956 -1957
- data/lib/parser/ruby19.rb +1962 -1969
- data/lib/parser/ruby19.y +2 -0
- data/lib/parser/ruby20.rb +2412 -2407
- data/lib/parser/ruby20.y +16 -2
- data/lib/parser/ruby21.rb +7310 -0
- data/lib/parser/ruby21.y +2352 -0
- data/lib/parser/source/buffer.rb +52 -2
- data/lib/parser.rb +16 -5
- data/parser.gemspec +2 -1
- data/test/helper.rb +1 -1
- data/test/parse_helper.rb +12 -4
- data/test/test_current.rb +17 -0
- data/test/test_encoding.rb +31 -0
- data/test/test_lexer.rb +5 -7
- data/test/test_parse_helper.rb +9 -4
- data/test/test_parser.rb +172 -10
- metadata +93 -125
- data/TODO.md +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
5
|
-
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
1
|
+
---
|
2
|
+
SHA512:
|
3
|
+
metadata.gz: 9770aa1a6462f5becb021dd1273bb992ce984aa07f4d2ab3184f909b4c9d5b7bf207c62e1c2d1f6684dfbde36c2e12cad77824d9b2343c86569b8d37d8b40259
|
4
|
+
data.tar.gz: c84a8295a37621c885de2618f8fc514469c239b564ca29ca75a576e0a1133f396707382aeccc1b4d73347671b081c0162b84bed32546796ea1fae02d66968aad
|
5
|
+
SHA1:
|
6
|
+
metadata.gz: 4a29479081e4085c756ccbfe0841c4b8244ce7ac
|
7
|
+
data.tar.gz: b2bdbd92ecf63102deafdfe71be38930d2c33930
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -46,7 +46,7 @@ p parser.parse(buffer)
|
|
46
46
|
* Precise source location reporting (WIP, no, not really yet).
|
47
47
|
* [Documented](AST_FORMAT.md) AST format which is convenient to work with.
|
48
48
|
* A simple interface and a powerful, tweakable one.
|
49
|
-
* Parses 1.8, 1.9 and 2.
|
49
|
+
* Parses 1.8, 1.9, 2.0 and 2.1 (preliminary) syntax with backwards-compatible AST formats.
|
50
50
|
* Parsing error recovery.
|
51
51
|
* Improved [clang-like][] diagnostic messages with location information.
|
52
52
|
* Written in pure Ruby, runs on MRI 1.8.7 or >=1.9.2, JRuby and Rubinius in 1.8 and 1.9 mode.
|
data/Rakefile
CHANGED
@@ -14,12 +14,22 @@ task :build => :generate_release
|
|
14
14
|
GENERATED_FILES = %w(lib/parser/lexer.rb
|
15
15
|
lib/parser/ruby18.rb
|
16
16
|
lib/parser/ruby19.rb
|
17
|
-
lib/parser/ruby20.rb
|
17
|
+
lib/parser/ruby20.rb
|
18
|
+
lib/parser/ruby21.rb)
|
18
19
|
|
19
20
|
CLEAN.include(GENERATED_FILES)
|
20
21
|
|
21
22
|
desc 'Generate the Ragel lexer and Bison parser.'
|
22
|
-
task :generate => GENERATED_FILES
|
23
|
+
task :generate => GENERATED_FILES do
|
24
|
+
GENERATED_FILES.each do |filename|
|
25
|
+
content = File.read(filename)
|
26
|
+
content = "# -*- encoding:utf-8; warn-indent:false -*-\n" + content
|
27
|
+
|
28
|
+
File.open(filename, 'w') do |io|
|
29
|
+
io.write content
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
23
33
|
|
24
34
|
task :regenerate => [:clean, :generate]
|
25
35
|
|
data/bin/benchmark
CHANGED
@@ -15,7 +15,7 @@ def measure(what)
|
|
15
15
|
what.each do |file, src|
|
16
16
|
begin
|
17
17
|
Ruby18Parser.new.parse(src)
|
18
|
-
rescue
|
18
|
+
rescue => e
|
19
19
|
puts file
|
20
20
|
puts "RP: #{e.class}: #{e.message}"
|
21
21
|
rp_failures += 1
|
@@ -26,10 +26,10 @@ def measure(what)
|
|
26
26
|
x.report "parser" do
|
27
27
|
what.each do |file, src|
|
28
28
|
begin
|
29
|
-
Parser::
|
29
|
+
Parser::Ruby20.parse(src, file)
|
30
30
|
rescue Parser::SyntaxError
|
31
31
|
p_failures += 1
|
32
|
-
rescue
|
32
|
+
rescue => e
|
33
33
|
puts file
|
34
34
|
puts "P: #{e.class}: #{e.message}"
|
35
35
|
puts e.backtrace
|
@@ -288,7 +288,9 @@ module Parser
|
|
288
288
|
|
289
289
|
def op_assign(lhs, operator_t, rhs)
|
290
290
|
case lhs.type
|
291
|
-
when :gvasgn, :ivasgn, :lvasgn, :cvasgn, :cvdecl,
|
291
|
+
when :gvasgn, :ivasgn, :lvasgn, :cvasgn, :cvdecl,
|
292
|
+
:cdecl,
|
293
|
+
:send
|
292
294
|
operator = value(operator_t)[0..-1].to_sym
|
293
295
|
|
294
296
|
case operator
|
@@ -393,7 +395,7 @@ module Parser
|
|
393
395
|
#
|
394
396
|
|
395
397
|
def args(begin_t, args, end_t)
|
396
|
-
s(:args, *args)
|
398
|
+
s(:args, *check_duplicate_args(args))
|
397
399
|
end
|
398
400
|
|
399
401
|
def arg(name_t)
|
@@ -482,7 +484,7 @@ module Parser
|
|
482
484
|
end
|
483
485
|
|
484
486
|
def block(method_call, begin_t, args, body, end_t)
|
485
|
-
|
487
|
+
_receiver, _selector, *call_args = *method_call
|
486
488
|
last_arg = call_args.last
|
487
489
|
|
488
490
|
if last_arg && last_arg.type == :block_pass
|
@@ -667,6 +669,47 @@ module Parser
|
|
667
669
|
cond
|
668
670
|
end
|
669
671
|
|
672
|
+
def check_duplicate_args(args, map={})
|
673
|
+
args.each do |this_arg|
|
674
|
+
case this_arg.type
|
675
|
+
when :arg, :optarg, :restarg, :blockarg,
|
676
|
+
:kwarg, :kwoptarg, :kwrestarg,
|
677
|
+
:shadowarg
|
678
|
+
|
679
|
+
this_name, = *this_arg
|
680
|
+
|
681
|
+
that_arg = map[this_name]
|
682
|
+
that_name, = *that_arg
|
683
|
+
|
684
|
+
if that_arg.nil?
|
685
|
+
map[this_name] = this_arg
|
686
|
+
elsif arg_name_collides?(this_name, that_name)
|
687
|
+
# TODO reenable when source maps are done
|
688
|
+
diagnostic :error, ERRORS[:duplicate_argument],
|
689
|
+
nil # this_arg.src.expression, [ that_arg.src.expression ]
|
690
|
+
end
|
691
|
+
|
692
|
+
when :mlhs
|
693
|
+
check_duplicate_args(this_arg.children, map)
|
694
|
+
end
|
695
|
+
end
|
696
|
+
end
|
697
|
+
|
698
|
+
def arg_name_collides?(this_name, that_name)
|
699
|
+
case @parser.version
|
700
|
+
when 18
|
701
|
+
this_name == that_name
|
702
|
+
when 19
|
703
|
+
# Ignore underscore.
|
704
|
+
this_name != :_ &&
|
705
|
+
this_name == that_name
|
706
|
+
else
|
707
|
+
# Ignore everything beginning with underscore.
|
708
|
+
this_name[0] != '_' &&
|
709
|
+
this_name == that_name
|
710
|
+
end
|
711
|
+
end
|
712
|
+
|
670
713
|
def collapse_string_parts?(parts)
|
671
714
|
parts.one? &&
|
672
715
|
[:str, :dstr].include?(parts.first.type)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Parser
|
2
|
+
class << self
|
3
|
+
def warn_syntax_deviation(feature, version)
|
4
|
+
warn "warning: parser/current is loading #{feature}, which recognizes"
|
5
|
+
warn "warning: #{version}-compliant syntax, but you are running #{RUBY_VERSION}."
|
6
|
+
end
|
7
|
+
private :warn_syntax_deviation
|
8
|
+
end
|
9
|
+
|
10
|
+
case RUBY_VERSION
|
11
|
+
when /^1\.8\./
|
12
|
+
if RUBY_VERSION != '1.8.7'
|
13
|
+
warn_syntax_deviation 'parser/ruby18', '1.8.7'
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'parser/ruby18'
|
17
|
+
CurrentRuby = Ruby18
|
18
|
+
|
19
|
+
when /^1\.9\./
|
20
|
+
if RUBY_VERSION != '1.9.3'
|
21
|
+
warn_syntax_deviation 'parser/ruby19', '1.9.3'
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'parser/ruby19'
|
25
|
+
CurrentRuby = Ruby19
|
26
|
+
|
27
|
+
when /^2\.0\./
|
28
|
+
require 'parser/ruby20'
|
29
|
+
CurrentRuby = Ruby20
|
30
|
+
|
31
|
+
else # :nocov:
|
32
|
+
raise NotImplementedError, "Parser does not support parsing Ruby #{RUBY_VERSION}"
|
33
|
+
end
|
34
|
+
end
|