rkelly 1.0.1 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/CHANGELOG.rdoc +8 -0
- data/Manifest.txt +1 -0
- data/Rakefile +8 -9
- data/lib/parser.y +1 -1
- data/lib/rkelly.rb +1 -0
- data/lib/rkelly/constants.rb +1 -1
- data/lib/rkelly/generated_parser.rb +1 -1
- data/lib/rkelly/parser.rb +4 -0
- data/lib/rkelly/syntax_error.rb +4 -0
- data/lib/rkelly/tokenizer.rb +15 -1
- data/lib/rkelly/visitors/visitor.rb +1 -1
- data/test/test_parser.rb +6 -0
- data/test/test_tokenizer.rb +22 -0
- metadata +31 -11
data/.gemtest
ADDED
File without changes
|
data/CHANGELOG.rdoc
CHANGED
data/Manifest.txt
CHANGED
data/Rakefile
CHANGED
@@ -1,18 +1,17 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'hoe'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
require 'rkelly/constants'
|
4
|
+
Hoe.plugin :gemspec # `gem install hoe-gemspec`
|
5
|
+
Hoe.plugin :git # `gem install hoe-git`
|
7
6
|
|
8
7
|
GENERATED_PARSER = "lib/rkelly/generated_parser.rb"
|
9
8
|
|
10
|
-
HOE = Hoe.
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
HOE = Hoe.spec('rkelly') do |p|
|
10
|
+
developer('Aaron Patterson', 'aaron.patterson@gmail.com')
|
11
|
+
self.readme_file = 'README.rdoc'
|
12
|
+
self.history_file = 'CHANGELOG.rdoc'
|
13
|
+
self.extra_rdoc_files = FileList['*.rdoc']
|
14
|
+
self.clean_globs = [GENERATED_PARSER]
|
16
15
|
end
|
17
16
|
|
18
17
|
file GENERATED_PARSER => "lib/parser.y" do |t|
|
data/lib/parser.y
CHANGED
data/lib/rkelly.rb
CHANGED
data/lib/rkelly/constants.rb
CHANGED
@@ -2777,7 +2777,7 @@ module_eval(<<'.,.,', 'parser.y', 590)
|
|
2777
2777
|
def _reduce_240(val, _values, result)
|
2778
2778
|
result = ExpressionStatementNode.new(val.first)
|
2779
2779
|
debug(result)
|
2780
|
-
|
2780
|
+
raise RKelly::SyntaxError unless allow_auto_semi?(val.last)
|
2781
2781
|
|
2782
2782
|
result
|
2783
2783
|
end
|
data/lib/rkelly/parser.rb
CHANGED
data/lib/rkelly/tokenizer.rb
CHANGED
@@ -45,6 +45,8 @@ module RKelly
|
|
45
45
|
'/=' => :DIVEQUAL,
|
46
46
|
}
|
47
47
|
|
48
|
+
TOKENS_THAT_IMPLY_DIVISION = [:IDENT, :NUMBER, ')', ']', '}']
|
49
|
+
|
48
50
|
def initialize(&block)
|
49
51
|
@lexemes = []
|
50
52
|
|
@@ -70,7 +72,7 @@ module RKelly
|
|
70
72
|
[LITERALS[value], value]
|
71
73
|
end
|
72
74
|
|
73
|
-
token(:IDENT, /\A(
|
75
|
+
token(:IDENT, /\A([_\$A-Za-z][_\$0-9A-Za-z]*)/) do |type,value|
|
74
76
|
if KEYWORDS.include?(value)
|
75
77
|
[value.upcase.to_sym, value]
|
76
78
|
elsif RESERVED.include?(value)
|
@@ -95,10 +97,13 @@ module RKelly
|
|
95
97
|
def raw_tokens(string)
|
96
98
|
tokens = []
|
97
99
|
line_number = 1
|
100
|
+
accepting_regexp = true
|
98
101
|
while string.length > 0
|
99
102
|
longest_token = nil
|
100
103
|
|
101
104
|
@lexemes.each { |lexeme|
|
105
|
+
next if lexeme.name == :REGEXP && !accepting_regexp
|
106
|
+
|
102
107
|
match = lexeme.match(string)
|
103
108
|
next if match.nil?
|
104
109
|
longest_token = match if longest_token.nil?
|
@@ -106,6 +111,8 @@ module RKelly
|
|
106
111
|
longest_token = match
|
107
112
|
}
|
108
113
|
|
114
|
+
accepting_regexp = followable_by_regex(longest_token)
|
115
|
+
|
109
116
|
longest_token.line = line_number
|
110
117
|
line_number += longest_token.value.scan(/\n/).length
|
111
118
|
string = string.slice(Range.new(longest_token.value.length, -1))
|
@@ -118,5 +125,12 @@ module RKelly
|
|
118
125
|
def token(name, pattern = nil, &block)
|
119
126
|
@lexemes << Lexeme.new(name, pattern, &block)
|
120
127
|
end
|
128
|
+
|
129
|
+
def followable_by_regex(current_token)
|
130
|
+
name = current_token.name
|
131
|
+
name = current_token.value if name == :SINGLE_CHAR
|
132
|
+
#the tokens that imply division vs. start of regex form a disjoint set
|
133
|
+
!TOKENS_THAT_IMPLY_DIVISION.include?(name)
|
134
|
+
end
|
121
135
|
end
|
122
136
|
end
|
@@ -29,7 +29,7 @@ module RKelly
|
|
29
29
|
CONDITIONAL_NODES = %w{ If Conditional }
|
30
30
|
FUNC_CALL_NODES = %w{ NewExpr FunctionCall }
|
31
31
|
FUNC_DECL_NODES = %w{ FunctionExpr FunctionDecl }
|
32
|
-
ALL_NODES = %w{ For ForIn Try BracketAccessor
|
32
|
+
ALL_NODES = %w{ For ForIn Try BracketAccessor DotAccessor } +
|
33
33
|
TERMINAL_NODES + SINGLE_VALUE_NODES + BINARY_NODES + ARRAY_VALUE_NODES +
|
34
34
|
NAME_VALUE_NODES + PREFIX_POSTFIX_NODES + CONDITIONAL_NODES +
|
35
35
|
FUNC_CALL_NODES + FUNC_DECL_NODES
|
data/test/test_parser.rb
CHANGED
@@ -5,6 +5,12 @@ class ParserTest < Test::Unit::TestCase
|
|
5
5
|
@parser = RKelly::Parser.new
|
6
6
|
end
|
7
7
|
|
8
|
+
def test_birthday!
|
9
|
+
assert_raises(RKelly::SyntaxError) do
|
10
|
+
RKelly::Parser.new.parse "Happy birthday, tenderlove!"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
8
14
|
def test_array_access
|
9
15
|
assert_sexp(
|
10
16
|
[
|
data/test/test_tokenizer.rb
CHANGED
@@ -49,6 +49,11 @@ class TokenizerTest < Test::Unit::TestCase
|
|
49
49
|
assert_tokens([[:IDENT, 'foo']], tokens)
|
50
50
|
end
|
51
51
|
|
52
|
+
def test_ignore_identifier
|
53
|
+
tokens = @tokenizer.tokenize("0foo")
|
54
|
+
assert_tokens([[:NUMBER, 0], [:IDENT, 'foo']], tokens)
|
55
|
+
end
|
56
|
+
|
52
57
|
def test_increment
|
53
58
|
tokens = @tokenizer.tokenize("foo += 1;")
|
54
59
|
assert_tokens([
|
@@ -79,6 +84,23 @@ class TokenizerTest < Test::Unit::TestCase
|
|
79
84
|
], tokens)
|
80
85
|
end
|
81
86
|
|
87
|
+
def test_regular_expression_is_not_found_if_prev_token_implies_division
|
88
|
+
{:IDENT => 'foo',
|
89
|
+
:NUMBER => 1,
|
90
|
+
')' => ')',
|
91
|
+
']' => ']',
|
92
|
+
'}' => '}'}.each do |name, value|
|
93
|
+
tokens = @tokenizer.tokenize("#{value}/2/3")
|
94
|
+
assert_tokens([
|
95
|
+
[name, value],
|
96
|
+
["/", "/"],
|
97
|
+
[:NUMBER, 2],
|
98
|
+
["/", "/"],
|
99
|
+
[:NUMBER, 3],
|
100
|
+
], tokens)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
82
104
|
def test_comment_assign
|
83
105
|
tokens = @tokenizer.tokenize("foo = /**/;")
|
84
106
|
assert_tokens([
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rkelly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 17
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 3
|
10
|
+
version: 1.0.3
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Aaron Patterson
|
@@ -9,22 +15,28 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2011-02-28 00:00:00 -08:00
|
13
19
|
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
22
|
name: hoe
|
17
|
-
|
18
|
-
|
19
|
-
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
20
26
|
requirements:
|
21
27
|
- - ">="
|
22
28
|
- !ruby/object:Gem::Version
|
23
|
-
|
24
|
-
|
29
|
+
hash: 41
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 9
|
33
|
+
- 1
|
34
|
+
version: 2.9.1
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
25
37
|
description: The RKelly library will parse JavaScript and return a parse tree.
|
26
38
|
email:
|
27
|
-
-
|
39
|
+
- aaron.patterson@gmail.com
|
28
40
|
executables: []
|
29
41
|
|
30
42
|
extensions: []
|
@@ -87,6 +99,7 @@ files:
|
|
87
99
|
- lib/rkelly/runtime.rb
|
88
100
|
- lib/rkelly/runtime/ruby_function.rb
|
89
101
|
- lib/rkelly/runtime/scope_chain.rb
|
102
|
+
- lib/rkelly/syntax_error.rb
|
90
103
|
- lib/rkelly/token.rb
|
91
104
|
- lib/rkelly/tokenizer.rb
|
92
105
|
- lib/rkelly/visitable.rb
|
@@ -232,6 +245,7 @@ files:
|
|
232
245
|
- test/test_void_node.rb
|
233
246
|
- test/test_while_node.rb
|
234
247
|
- test/test_with_node.rb
|
248
|
+
- .gemtest
|
235
249
|
has_rdoc: true
|
236
250
|
homepage: http://rkelly.rubyforge.org/
|
237
251
|
licenses: []
|
@@ -243,21 +257,27 @@ rdoc_options:
|
|
243
257
|
require_paths:
|
244
258
|
- lib
|
245
259
|
required_ruby_version: !ruby/object:Gem::Requirement
|
260
|
+
none: false
|
246
261
|
requirements:
|
247
262
|
- - ">="
|
248
263
|
- !ruby/object:Gem::Version
|
264
|
+
hash: 3
|
265
|
+
segments:
|
266
|
+
- 0
|
249
267
|
version: "0"
|
250
|
-
version:
|
251
268
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
269
|
+
none: false
|
252
270
|
requirements:
|
253
271
|
- - ">="
|
254
272
|
- !ruby/object:Gem::Version
|
273
|
+
hash: 3
|
274
|
+
segments:
|
275
|
+
- 0
|
255
276
|
version: "0"
|
256
|
-
version:
|
257
277
|
requirements: []
|
258
278
|
|
259
279
|
rubyforge_project: rkelly
|
260
|
-
rubygems_version: 1.
|
280
|
+
rubygems_version: 1.5.2
|
261
281
|
signing_key:
|
262
282
|
specification_version: 3
|
263
283
|
summary: The RKelly library will parse JavaScript and return a parse tree.
|