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(", ")