Class: RDoc::Fortran95parser

Inherits:
Object
  • Object
show all
Extended by:
ParserFactory
Defined in:
lib/rdoc/parsers/parse_f95.rb

Overview

See rdoc/parsers/parse_f95.rb

Defined Under Namespace

Classes: Fortran95Definition

Constant Summary collapse

COMMENTS_ARE_UPPER =
"false"

Comments are below source code

"true"

Comments are upper source code

false
INTERNAL_ALIAS_MES =

Internal alias message

"Alias for"
EXTERNAL_ALIAS_MES =

External alias message

"The entity is"
@@external_aliases =
[]
@@public_methods =
[]

Instance Method Summary collapse

Methods included from ParserFactory

alias_extension, can_parse, parse_files_matching, parser_for

Constructor Details

#initialize(top_level, file_name, body, options, stats) ⇒ Fortran95parser

prepare to parse a Fortran 95 file



195
196
197
198
199
200
201
202
# File 'lib/rdoc/parsers/parse_f95.rb', line 195

def initialize(top_level, file_name, body, options, stats)
  @body = body
  @stats = stats
  @file_name  = file_name
  @options = options
  @top_level = top_level
  @progress = $stderr unless options.quiet
end

Instance Method Details

#scanObject

define code constructs



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
# File 'lib/rdoc/parsers/parse_f95.rb', line 205

def scan

  # remove private comment
  remaining_code = remove_private_comments(@body)

  # continuation lines are united to one line
  remaining_code = united_to_one_line(remaining_code)

  # semicolons are replaced to line feed
  remaining_code = semicolon_to_linefeed(remaining_code)

  # collect comment for file entity
  whole_comment, remaining_code = collect_first_comment(remaining_code)
  @top_level.comment = whole_comment

  # String "remaining_code" is converted to Array "remaining_lines"
  remaining_lines = remaining_code.split("\n")

  # "module" or "program" parts are parsed (new)
  #
  level_depth = 0
  block_searching_flag = nil
  block_searching_lines = []
  pre_comment = []
  module_program_trailing = ""
  module_program_name = ""
  other_block_level_depth = 0
  other_block_searching_flag = nil
  remaining_lines.collect!{|line|
    if !block_searching_flag && !other_block_searching_flag
      if line =~ /^\s*?module\s+(\w+)\s*?(!.*?)?$/i
        block_searching_flag = :module
        block_searching_lines << line
        module_program_name = $1
        module_program_trailing = find_comments($2)
        next false
      elsif line =~ /^\s*?program\s+(\w+)\s*?(!.*?)?$/i ||
             line =~ /^\s*?\w/ && !block_start?(line)
        block_searching_flag = :program
        block_searching_lines << line
        module_program_name = $1 || ""
        module_program_trailing = find_comments($2)
        next false

      elsif block_start?(line)
        other_block_searching_flag = true
        next line

      elsif line =~ /^\s*?!\s?(.*)/
        pre_comment << line
        next line
      else
        pre_comment = []
        next line
      end
    elsif other_block_searching_flag
      other_block_level_depth += 1 if block_start?(line)
      other_block_level_depth -= 1 if block_end?(line)
      if other_block_level_depth < 0
        other_block_level_depth = 0
        other_block_searching_flag = nil
      end
      next line
    end

    block_searching_lines << line
    level_depth += 1 if block_start?(line)
    level_depth -= 1 if block_end?(line)
    if level_depth >= 0
      next false
    end

    # "module_program_code" is formatted.
    # ":nodoc:" flag is checked.
    #
    module_program_code = block_searching_lines.join("\n")
    module_program_code = remove_empty_head_lines(module_program_code)
    if module_program_trailing =~ /^:nodoc:/
      # next loop to search next block
      level_depth = 0
      block_searching_flag = false
      block_searching_lines = []
      pre_comment = []
      next false
    end

    # NormalClass is created, and added to @top_level
    #
    if block_searching_flag == :module
      module_name = module_program_name
      module_code = module_program_code
      module_trailing = module_program_trailing
      progress "m"
      @stats.num_modules += 1
      f9x_module = @top_level.add_module NormalClass, module_name
      f9x_module.record_location @top_level

      f9x_comment = COMMENTS_ARE_UPPER ? 
        find_comments(pre_comment.join("\n"))  + "\n" + module_trailing :
          module_trailing + "\n" + find_comments(module_code.sub(/^.*$\n/i, ''))
      f9x_module.comment = f9x_comment
      parse_program_or_module(f9x_module, module_code)

      TopLevel.all_files.each do |name, toplevel|
        if toplevel.include_includes?(module_name, @options.ignore_case)
          if !toplevel.include_requires?(@file_name, @options.ignore_case)
            toplevel.add_require(Require.new(@file_name, ""))
          end
        end
        toplevel.each_classmodule{|m|
          if m.include_includes?(module_name, @options.ignore_case)
            if !m.include_requires?(@file_name, @options.ignore_case)
              m.add_require(Require.new(@file_name, ""))
            end
          end
        }
      end
    elsif block_searching_flag == :program
      program_name = module_program_name
      program_code = module_program_code
      program_trailing = module_program_trailing
      progress "p"
      program_comment = COMMENTS_ARE_UPPER ? 
        find_comments(pre_comment.join("\n")) + "\n" + program_trailing : 
          program_trailing + "\n" + find_comments(program_code.sub(/^.*$\n/i, ''))
      program_comment = "\n\n= <i>Program</i> <tt>#{program_name}</tt>\n\n" \
                        + program_comment
      @top_level.comment << program_comment
      parse_program_or_module(@top_level, program_code, :private)
    end

    # next loop to search next block
    level_depth = 0
    block_searching_flag = false
    block_searching_lines = []
    pre_comment = []
    next false
  }

  remaining_lines.delete_if{ |line|
    line == false
  }

  # External subprograms and functions are parsed
  #
  parse_program_or_module(@top_level, remaining_lines.join("\n"),
                          :public, true)

  @top_level
end