lib/jsduck/parser.rb in jsduck-0.2 vs lib/jsduck/parser.rb in jsduck-0.3
- old
+ new
@@ -1,20 +1,22 @@
require 'jsduck/lexer'
+require 'jsduck/doc_parser'
module JsDuck
class Parser
def initialize(input)
@lex = Lexer.new(input)
+ @doc_parser = DocParser.new
@docs = []
end
# Parses the whole JavaScript block and returns array where for
# each doc-comment there is a hash of three values: the comment
- # itself as string, number of the line where the comment starts,
- # and parsed structure of the code that immediately follows the
- # comment.
+ # structure created by DocParser, number of the line where the
+ # comment starts, and parsed structure of the code that
+ # immediately follows the comment.
#
# For example with the following JavaScript input:
#
# /**
# * @param {String} foo
@@ -24,11 +26,14 @@
#
# The return value of this function will be:
#
# [
# {
- # :comment => "/**\n * @param {String} foo\n */",
+ # :comment => [
+ # {:tagname => :default, :doc => "Method description"},
+ # {:tagname => :return, :type => "Number", :doc => ""},
+ # ],
# :linenr => 1,
# :code => {
# :type => :assignment,
# :left => ["MyClass", "doIt"],
# :right => {
@@ -43,14 +48,14 @@
# }
# ]
#
def parse
while !@lex.empty? do
- if look(:doc_comment) then
+ if look(:doc_comment)
comment = @lex.next(true)
@docs << {
- :comment => comment[:value],
+ :comment => @doc_parser.parse(comment[:value]),
:linenr => comment[:linenr],
:code => code_block
}
else
@lex.next
@@ -62,19 +67,22 @@
# The following is a recursive-descent parser for JavaScript that
# can possibly follow a doc-comment
# <code-block> := <function> | <var-declaration> | <assignment> | <property-literal>
def code_block
- if look("function") then
+ if look("function")
function
- elsif look("var") then
+ elsif look("var")
var_declaration
- elsif look(:ident, ":") || look(:string, ":") then
+ elsif look(:ident, ":") || look(:string, ":")
property_literal
- elsif look(:ident) || look("this") then
+ elsif look(",", :ident, ":") || look(",", :string, ":")
+ match(",")
+ property_literal
+ elsif look(:ident) || look("this")
maybe_assignment
- elsif look(:string) then
+ elsif look(:string)
{:type => :assignment, :left => [match(:string)]}
else
{:type => :nop}
end
end
@@ -113,11 +121,11 @@
end
# <maybe-assignment> := <ident-chain> [ "=" <expression> ]
def maybe_assignment
left = ident_chain
- if look("=") then
+ if look("=")
match("=")
right = expression
end
return {
:type => :assignment,
@@ -141,21 +149,21 @@
end
# <expression> := <function> | <ext-extend> | <literal>
# <literal> := <string> | <boolean> | <number> | <regex>
def expression
- if look("function") then
+ if look("function")
function
- elsif look("Ext", ".", "extend") then
+ elsif look("Ext", ".", "extend")
ext_extend
- elsif look(:string) then
+ elsif look(:string)
{:type => :literal, :class => "String"}
- elsif look("true") || look("false") then
+ elsif look("true") || look("false")
{:type => :literal, :class => "Boolean"}
- elsif look(:number) then
+ elsif look(:number)
{:type => :literal, :class => "Number"}
- elsif look(:regex) then
+ elsif look(:regex)
{:type => :literal, :class => "RegExp"}
end
end
# <ext-extend> := "Ext" "." "extend" "(" <ident-chain> "," ...
@@ -180,10 +188,10 @@
end
# Matches all arguments, returns the value of last match
# When the whole sequence doesn't match, throws exception
def match(*args)
- if look(*args) then
+ if look(*args)
last = nil
args.length.times { last = @lex.next }
last
else
throw "Expected: " + args.join(", ")