class RKelly::Parser

Constants

TOKENIZER

Attributes

logger[RW]

Public Class Methods

new() click to toggle source
# File lib/rkelly/parser.rb, line 26
def initialize
  @tokens = []
  @logger = nil
  @terminator = false
  @prev_token = nil
  @comments = []
end

Public Instance Methods

parse(javascript, filename = nil) click to toggle source

Parse javascript and return an AST

# File lib/rkelly/parser.rb, line 35
def parse(javascript, filename = nil)
  @tokens = TOKENIZER.raw_tokens(javascript)
  @position = 0
  @filename = filename
  ast = do_parse
  apply_comments(ast)
end
yyabort() click to toggle source
# File lib/rkelly/parser.rb, line 43
def yyabort
  raise "something bad happened, please report a bug with sample JavaScript"
end

Private Instance Methods

apply_comments(ast) click to toggle source
# File lib/rkelly/parser.rb, line 48
def apply_comments(ast)
  ast_hash = Hash.new { |h,k| h[k] = [] }
  (ast || []).each { |n|
    next unless n.line
    ast_hash[n.line] << n
  }
  max = ast_hash.keys.sort.last
  @comments.each do |comment|
    node = nil
    comment.line.upto(max) do |line|
      if ast_hash.key?(line)
        node = ast_hash[line].first
        break
      end
    end
    node.comments << comment if node
  end if max
  ast
end
next_token() click to toggle source
# File lib/rkelly/parser.rb, line 76
def next_token
  @terminator = false
  begin
    return [false, false] if @position >= @tokens.length
    n_token = @tokens[@position]
    @position += 1
    case @tokens[@position - 1].name
    when :COMMENT
      @comments << n_token
      @terminator = true if n_token.value =~ /^\/\//
    when :S
      @terminator = true if n_token.value =~ /[\r\n]/
    end
  end while([:COMMENT, :S].include?(n_token.name))

  if @terminator &&
      ((@prev_token && %w[continue break return throw].include?(@prev_token.value)) ||
       (n_token && %w[++ --].include?(n_token.value)))
    @position -= 1
    return (@prev_token = RKelly::Token.new(';', ';')).to_racc_token
  end

  @prev_token = n_token
  v = n_token.to_racc_token
  v[1] = n_token
  v
end
on_error(error_token_id, error_value, value_stack) click to toggle source
# File lib/rkelly/parser.rb, line 68
def on_error(error_token_id, error_value, value_stack)
  if logger
    logger.error(token_to_str(error_token_id))
    logger.error("error value: #{error_value}")
    logger.error("error stack: #{value_stack}")
  end
end