rkelly 1.0.4 → 1.0.7
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.
- data/lib/rkelly/constants.rb +1 -1
- data/lib/rkelly/generated_parser.rb +3 -3
- data/lib/rkelly/nodes/binary_node.rb +2 -2
- data/lib/rkelly/token.rb +4 -0
- data/lib/rkelly/tokenizer.rb +31 -8
- data/lib/rkelly/visitors/ecma_visitor.rb +7 -2
- data/test/test_ecma_visitor.rb +12 -0
- data/test/test_tokenizer.rb +20 -0
- metadata +28 -7
data/lib/rkelly/constants.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# DO NOT MODIFY!!!!
|
3
|
-
# This file is automatically generated by Racc 1.4.
|
3
|
+
# This file is automatically generated by Racc 1.4.9
|
4
4
|
# from Racc grammer file "".
|
5
5
|
#
|
6
6
|
|
@@ -280,7 +280,7 @@ clist = [
|
|
280
280
|
'96,22,23,24,,,,,,,,43,44,,,,,112,22,23,24,92,,,28,,,27,25,26,87,,,,112',
|
281
281
|
'32,,86,92,,33,28,,45,46,47,48,,,,,,,,,,27,25,26,87,,,,,32,,86,,,33,',
|
282
282
|
',,27,25,26,87,,,,,32,,86,,,33' ]
|
283
|
-
racc_action_table = arr = Array.new(8578, nil)
|
283
|
+
racc_action_table = arr = ::Array.new(8578, nil)
|
284
284
|
idx = 0
|
285
285
|
clist.each do |str|
|
286
286
|
str.split(',', -1).each do |i|
|
@@ -575,7 +575,7 @@ clist = [
|
|
575
575
|
'36,92,92,92,36,,,36,,,485,485,485,485,,,,92,485,,485,92,,485,92,,485',
|
576
576
|
'485,485,485,,,,,,,,,,36,36,36,36,,,,,36,,36,,,36,,,,92,92,92,92,,,,',
|
577
577
|
'92,,92,,,92' ]
|
578
|
-
racc_action_check = arr = Array.new(8578, nil)
|
578
|
+
racc_action_check = arr = ::Array.new(8578, nil)
|
579
579
|
idx = 0
|
580
580
|
clist.each do |str|
|
581
581
|
str.split(',', -1).each do |i|
|
@@ -8,11 +8,11 @@ module RKelly
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
%w[Subtract LessOrEqual GreaterOrEqual Add Multiply
|
11
|
+
%w[Subtract LessOrEqual GreaterOrEqual Add Multiply NotEqual
|
12
12
|
DoWhile Switch LogicalAnd UnsignedRightShift Modulus While
|
13
13
|
NotStrictEqual Less With In Greater BitOr StrictEqual LogicalOr
|
14
14
|
BitXOr LeftShift Equal BitAnd InstanceOf Divide RightShift].each do |node|
|
15
|
-
|
15
|
+
const_set "#{node}Node", Class.new(BinaryNode)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
data/lib/rkelly/token.rb
CHANGED
data/lib/rkelly/tokenizer.rb
CHANGED
@@ -45,7 +45,15 @@ module RKelly
|
|
45
45
|
'/=' => :DIVEQUAL,
|
46
46
|
}
|
47
47
|
|
48
|
-
|
48
|
+
# Some keywords can be followed by regular expressions (eg, return and throw).
|
49
|
+
# Others can be followed by division.
|
50
|
+
KEYWORDS_THAT_IMPLY_DIVISION = %w{
|
51
|
+
this true false null
|
52
|
+
}
|
53
|
+
|
54
|
+
KEYWORDS_THAT_IMPLY_REGEX = KEYWORDS - KEYWORDS_THAT_IMPLY_DIVISION
|
55
|
+
|
56
|
+
SINGLE_CHARS_THAT_IMPLY_DIVISION = [')', ']', '}']
|
49
57
|
|
50
58
|
def initialize(&block)
|
51
59
|
@lexemes = []
|
@@ -72,17 +80,26 @@ module RKelly
|
|
72
80
|
[LITERALS[value], value]
|
73
81
|
end
|
74
82
|
|
75
|
-
token(:
|
83
|
+
token(:RAW_IDENT, /\A([_\$A-Za-z][_\$0-9A-Za-z]*)/) do |type,value|
|
76
84
|
if KEYWORDS.include?(value)
|
77
85
|
[value.upcase.to_sym, value]
|
78
86
|
elsif RESERVED.include?(value)
|
79
87
|
[:RESERVED, value]
|
80
88
|
else
|
81
|
-
[
|
89
|
+
[:IDENT, value]
|
82
90
|
end
|
83
91
|
end
|
84
92
|
|
85
|
-
|
93
|
+
# To distinguish regular expressions from comments, we require that
|
94
|
+
# regular expressions start with a non * character (ie, not look like
|
95
|
+
# /*foo*/). Note that we can't depend on the length of the match to
|
96
|
+
# correctly distinguish, since `/**/i` is longer if matched as a regular
|
97
|
+
# expression than as matched as a comment.
|
98
|
+
# Incidentally, we're also not matching empty regular expressions
|
99
|
+
# (eg, // and //g). Here we could depend on match length and priority to
|
100
|
+
# determine that these are actually comments, but it turns out to be
|
101
|
+
# easier to not match them in the first place.
|
102
|
+
token(:REGEXP, /\A\/(?:[^\/\r\n\\*]|\\[^\r\n])[^\/\r\n\\]*(?:\\[^\r\n][^\/\r\n\\]*)*\/[gim]*/)
|
86
103
|
token(:S, /\A[\s\r\n]*/m)
|
87
104
|
|
88
105
|
token(:SINGLE_CHAR, /\A./) do |type, value|
|
@@ -129,10 +146,16 @@ module RKelly
|
|
129
146
|
end
|
130
147
|
|
131
148
|
def followable_by_regex(current_token)
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
149
|
+
case current_token.name
|
150
|
+
when :RAW_IDENT
|
151
|
+
KEYWORDS_THAT_IMPLY_REGEX.include?(current_token.value)
|
152
|
+
when :NUMBER
|
153
|
+
false
|
154
|
+
when :SINGLE_CHAR
|
155
|
+
!SINGLE_CHARS_THAT_IMPLY_DIVISION.include?(current_token.value)
|
156
|
+
else
|
157
|
+
true
|
158
|
+
end
|
136
159
|
end
|
137
160
|
end
|
138
161
|
end
|
@@ -232,7 +232,11 @@ module RKelly
|
|
232
232
|
end
|
233
233
|
|
234
234
|
def visit_CaseClauseNode(o)
|
235
|
-
|
235
|
+
if o.left
|
236
|
+
case_code = "#{indent}case #{o.left.accept(self)}:\n"
|
237
|
+
else
|
238
|
+
case_code = "#{indent}default:\n"
|
239
|
+
end
|
236
240
|
@indent += 1
|
237
241
|
case_code += "#{o.value.accept(self)}\n"
|
238
242
|
@indent -= 1
|
@@ -292,7 +296,8 @@ module RKelly
|
|
292
296
|
end
|
293
297
|
|
294
298
|
def visit_ForInNode(o)
|
295
|
-
|
299
|
+
var = o.left.is_a?(RKelly::Nodes::VarDeclNode) ? 'var ' : ''
|
300
|
+
"for(#{var}#{o.left.accept(self)} in #{o.right.accept(self)}) " +
|
296
301
|
"#{o.value.accept(self)}"
|
297
302
|
end
|
298
303
|
|
data/test/test_ecma_visitor.rb
CHANGED
@@ -110,6 +110,17 @@ class ECMAVisitorTest < Test::Unit::TestCase
|
|
110
110
|
}")
|
111
111
|
end
|
112
112
|
|
113
|
+
def test_switch_default_node
|
114
|
+
assert_to_ecma("switch(a) {
|
115
|
+
case 1:
|
116
|
+
foo();
|
117
|
+
break;
|
118
|
+
default:
|
119
|
+
bar();
|
120
|
+
break;
|
121
|
+
}")
|
122
|
+
end
|
123
|
+
|
113
124
|
def test_do_while_node
|
114
125
|
assert_to_ecma("do { foo(); } while(true);")
|
115
126
|
end
|
@@ -181,6 +192,7 @@ class ECMAVisitorTest < Test::Unit::TestCase
|
|
181
192
|
|
182
193
|
def test_for_in_node
|
183
194
|
assert_to_ecma('for(foo in bar) { var x = 10; }')
|
195
|
+
assert_to_ecma('for(var foo in bar) { var x = 10; }')
|
184
196
|
end
|
185
197
|
|
186
198
|
def test_for_node
|
data/test/test_tokenizer.rb
CHANGED
@@ -100,6 +100,7 @@ class TokenizerTest < Test::Unit::TestCase
|
|
100
100
|
|
101
101
|
def test_regular_expression_is_not_found_if_prev_token_implies_division
|
102
102
|
{:IDENT => 'foo',
|
103
|
+
:TRUE => 'true',
|
103
104
|
:NUMBER => 1,
|
104
105
|
')' => ')',
|
105
106
|
']' => ']',
|
@@ -115,6 +116,25 @@ class TokenizerTest < Test::Unit::TestCase
|
|
115
116
|
end
|
116
117
|
end
|
117
118
|
|
119
|
+
def test_regular_expression_is_found_if_prev_token_is_non_literal_keyword
|
120
|
+
{:RETURN => 'return',
|
121
|
+
:THROW => 'throw'}.each do |name, value|
|
122
|
+
tokens = @tokenizer.tokenize("#{value}/2/")
|
123
|
+
assert_tokens([
|
124
|
+
[name, value],
|
125
|
+
[:REGEXP, "/2/"],
|
126
|
+
], tokens)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_regular_expression_is_not_found_if_block_comment_with_re_modifier
|
131
|
+
tokens = @tokenizer.tokenize("/**/i")
|
132
|
+
assert_tokens([
|
133
|
+
[:COMMENT, "/**/"],
|
134
|
+
[:IDENT, "i"]
|
135
|
+
], tokens)
|
136
|
+
end
|
137
|
+
|
118
138
|
def test_comment_assign
|
119
139
|
tokens = @tokenizer.tokenize("foo = /**/;")
|
120
140
|
assert_tokens([
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rkelly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,27 +9,48 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-10-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rdoc
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.10'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.10'
|
14
30
|
- !ruby/object:Gem::Dependency
|
15
31
|
name: hoe
|
16
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
17
33
|
none: false
|
18
34
|
requirements:
|
19
35
|
- - ~>
|
20
36
|
- !ruby/object:Gem::Version
|
21
|
-
version: '
|
37
|
+
version: '3.0'
|
22
38
|
type: :development
|
23
39
|
prerelease: false
|
24
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '3.0'
|
25
46
|
description: The RKelly library will parse JavaScript and return a parse tree.
|
26
47
|
email:
|
27
48
|
- aaron.patterson@gmail.com
|
28
49
|
executables: []
|
29
50
|
extensions: []
|
30
51
|
extra_rdoc_files:
|
31
|
-
- Manifest.txt
|
32
52
|
- CHANGELOG.rdoc
|
53
|
+
- Manifest.txt
|
33
54
|
- README.rdoc
|
34
55
|
files:
|
35
56
|
- CHANGELOG.rdoc
|
@@ -254,7 +275,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
254
275
|
version: '0'
|
255
276
|
requirements: []
|
256
277
|
rubyforge_project: rkelly
|
257
|
-
rubygems_version: 1.8.
|
278
|
+
rubygems_version: 1.8.24
|
258
279
|
signing_key:
|
259
280
|
specification_version: 3
|
260
281
|
summary: The RKelly library will parse JavaScript and return a parse tree.
|