Class: JsDuck::JsLiteralParser

Inherits:
Object
  • Object
show all
Defined in:
lib/jsduck/js_literal_parser.rb

Overview

Parser for JavaScript literals: numbers, strings, booleans, regexes, arrays, objects.

Almost like a JSON parser, but regexes are also valid values and object keys don’t need to be quoted.

Direct Known Subclasses

JsParser

Instance Method Summary collapse

Constructor Details

#initialize(input) ⇒ JsLiteralParser

Returns a new instance of JsLiteralParser.



11
12
13
# File 'lib/jsduck/js_literal_parser.rb', line 11

def initialize(input)
  @lex = Lexer.new(input)
end

Instance Method Details

#array_literalObject



44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/jsduck/js_literal_parser.rb', line 44

def array_literal
  match("[")
  r = []
  while (lit = literal)
    r << lit
    break unless look(",")
    match(",")
  end
  return unless look("]")
  match("]")
  return {:type => :array, :value => r}
end

#literalObject

Parses a literal.

Returns a Ruby hash representing this literal. For example parsing this:

[5, "foo"]

Returns the following structure:

{:type => :array, :value => [
    {:type => :number, :value => "5"},
    {:type => :string, :value => "foo"}
]}


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/jsduck/js_literal_parser.rb', line 28

def literal
  if look(:number)
    match(:number)
  elsif look(:string)
    match(:string)
  elsif look(:regex)
    match(:regex)
  elsif look("[")
    array_literal
  elsif look("{")
    object_literal
  elsif look(:ident) && (look("true") || look("false") || look("undefined") || look("null"))
    match(:ident)
  end
end

#look(*args) ⇒ Object



101
102
103
# File 'lib/jsduck/js_literal_parser.rb', line 101

def look(*args)
  @lex.look(*args)
end

#match(*args) ⇒ Object

Matches all arguments, returns the value of last match When the whole sequence doesn’t match, throws exception



91
92
93
94
95
96
97
98
99
# File 'lib/jsduck/js_literal_parser.rb', line 91

def match(*args)
  if look(*args)
    last = nil
    args.length.times { last = @lex.next(true) }
    last
  else
    throw "Expected: " + args.join(", ")
  end
end

#object_literalObject



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/jsduck/js_literal_parser.rb', line 57

def object_literal
  match("{")
  r = []
  while (look(:ident) || look(:string))
    lit = object_literal_pair
    return unless lit
    r << lit
    break unless look(",")
    match(",")
  end

  return unless look("}")
  match("}")
  return {:type => :object, :value => r}
end

#object_literal_pairObject



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/jsduck/js_literal_parser.rb', line 73

def object_literal_pair
  if look(:ident)
    key = match(:ident)
  elsif look(:string)
    key = match(:string)
  end

  return unless look(":")
  match(":")

  value = literal
  return unless value

  return {:key => key, :value => value}
end