class RKelly::Parser

Constants

SEMICOLON_TOKEN
TOKENIZER

Attributes

logger[RW]

Public Class Methods

new() click to toggle source
# File lib/rkelly/parser.rb, line 31
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 40
def parse(javascript, filename = nil)
  @tokens = TOKENIZER.raw_tokens(javascript)
  @position = 0
  @filename = filename
  ast = do_parse
  ast.comments = @comments if ast
  ast
end
stopped_at() click to toggle source

When parsing finishes without all tokens being parsed, returns the token at which the parsing stopped. Returns nil when parser reached to the very last token (but possibly still failed as it expeced more tokens).

Useful for pin-pointing the position of a syntax error.

# File lib/rkelly/parser.rb, line 59
def stopped_at
  if @position < @tokens.length
    @tokens[@position-1]
  else
    nil
  end
end
yyabort() click to toggle source
# File lib/rkelly/parser.rb, line 49
def yyabort
  raise "something bad happened, please report a bug with sample JavaScript"
end

Private Instance Methods

next_token() click to toggle source
# File lib/rkelly/parser.rb, line 78
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.start_with? "//"
    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 = SEMICOLON_TOKEN.dup).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