parser 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|