rkelly 1.0.1 → 1.0.3

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/.gemtest ADDED
File without changes
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,13 @@
1
1
  = RKelly CHANGELOG
2
2
 
3
+ === 1.0.3
4
+
5
+ * Bugfixes
6
+
7
+ * Fixed a typo in visitor.rb
8
+ * Fixed syntax error class
9
+ * Regex tonenization (thanks Josh Dzielak)
10
+
3
11
  === 1.0.1
4
12
 
5
13
  * Bugfixes
data/Manifest.txt CHANGED
@@ -51,6 +51,7 @@ lib/rkelly/parser.rb
51
51
  lib/rkelly/runtime.rb
52
52
  lib/rkelly/runtime/ruby_function.rb
53
53
  lib/rkelly/runtime/scope_chain.rb
54
+ lib/rkelly/syntax_error.rb
54
55
  lib/rkelly/token.rb
55
56
  lib/rkelly/tokenizer.rb
56
57
  lib/rkelly/visitable.rb
data/Rakefile CHANGED
@@ -1,18 +1,17 @@
1
1
  require 'rubygems'
2
2
  require 'hoe'
3
3
 
4
- $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "lib")
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.new('rkelly', RKelly::VERSION) do |p|
11
- p.developer('Aaron Patterson', 'aaronp@rubyforge.org')
12
- p.readme_file = 'README.rdoc'
13
- p.history_file = 'CHANGELOG.rdoc'
14
- p.extra_rdoc_files = FileList['*.rdoc']
15
- p.clean_globs = [GENERATED_PARSER]
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
@@ -590,7 +590,7 @@ rule
590
590
  | ExprNoBF error {
591
591
  result = ExpressionStatementNode.new(val.first)
592
592
  debug(result)
593
- yyabort unless allow_auto_semi?(val.last)
593
+ raise RKelly::SyntaxError unless allow_auto_semi?(val.last)
594
594
  }
595
595
  ;
596
596
 
data/lib/rkelly.rb CHANGED
@@ -3,6 +3,7 @@ require 'rkelly/visitable'
3
3
  require 'rkelly/visitors'
4
4
  require 'rkelly/parser'
5
5
  require 'rkelly/runtime'
6
+ require 'rkelly/syntax_error'
6
7
 
7
8
  module RKelly
8
9
  class << self
@@ -1,3 +1,3 @@
1
1
  module RKelly
2
- VERSION = '1.0.1'
2
+ VERSION = '1.0.3'
3
3
  end
@@ -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
- yyabort unless allow_auto_semi?(val.last)
2780
+ raise RKelly::SyntaxError unless allow_auto_semi?(val.last)
2781
2781
 
2782
2782
  result
2783
2783
  end
data/lib/rkelly/parser.rb CHANGED
@@ -40,6 +40,10 @@ module RKelly
40
40
  apply_comments(ast)
41
41
  end
42
42
 
43
+ def yyabort
44
+ raise "something bad happened, please report a bug with sample JavaScript"
45
+ end
46
+
43
47
  private
44
48
  def apply_comments(ast)
45
49
  ast_hash = Hash.new { |h,k| h[k] = [] }
@@ -0,0 +1,4 @@
1
+ module RKelly
2
+ class SyntaxError < ::SyntaxError
3
+ end
4
+ end
@@ -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(\w|\$)+/) do |type,value|
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 DotAcessor } +
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
  [
@@ -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
- version: 1.0.1
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: 2009-06-08 00:00:00 -07:00
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
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
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
- version: 1.12.2
24
- version:
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
- - aaronp@rubyforge.org
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.3.3
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.