Class: BELParser::ASTGenerator

Inherits:
Object
  • Object
show all
Includes:
LineMapping
Defined in:
lib/bel_parser/ast_generator.rb

Overview

ASTGenerator yields AST results for each line in some IO. See ##each.

Constant Summary collapse

PARSERS =
[
  map_const.call(BELParser::Parsers::Common),
  map_const.call(BELParser::Parsers::Expression),
  map_const.call(BELParser::Parsers::BELScript)
].flatten!
LINE_CONTINUATOR =
"\\\n".freeze

Instance Method Summary collapse

Methods included from LineMapping

#map_lines, #normalize_line_terminator

Constructor Details

#initialize(io) ⇒ ASTGenerator

Returns a new instance of ASTGenerator.



20
21
22
# File 'lib/bel_parser/ast_generator.rb', line 20

def initialize(io)
  @io = io
end

Instance Method Details

#eachIO, #<Enumerator: #<BELParser::ASTGenerator#each

Yields AST results for each line of the IO.

[Integer, String, Array<AST::Node>]

yields line number, line,

and AST results as an {Array}

Examples:

Receive AST results in given block.

# doctest setup require 'bel_parser' self.class.include AST::Sexp

# example usage line_io = StringIO.new("\"AKT1\"\n") line    =
nil ast_res = nil ::BELParser::ASTGenerator.new.each(line_io)
{ |(line_number, line, results)|
  # do something
}

Receive AST results as an enumerator.

# doctest setup require 'bel_parser' self.class.include AST::Sexp

# example usage line_io = StringIO.new("\"AKT1\"\n") line,
ast_res = ::BELParser::ASTGenerator.new.each(line_io).first.to_a

Parameters:

  • io (IO)

    the IO-object to read each line from @yield

Returns:

  • (IO, #<Enumerator: #<BELParser::ASTGenerator#each)

    ] the IO object is returned if a block is given, otherwise an Enumerator object is returned that can be iterated with Enumerator#each



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/bel_parser/ast_generator.rb', line 48

def each # rubocop:disable MethodLength
  if block_given?
    line_number   = 1
    expanded_line = nil
    map_lines(@io.each_line.lazy).each do |line|
      if line.end_with?(LINE_CONTINUATOR)
        expanded_line = "#{expanded_line}#{line.chomp(LINE_CONTINUATOR)}"
      else
        expanded_line = "#{expanded_line}#{line}"

        ast_results = []
        PARSERS.map do |parser|
          parser.parse(expanded_line) { |ast| ast_results << ast }
        end

        yield [line_number, expanded_line, ast_results]

        line_number += 1
        expanded_line = nil
      end
    end
  else
    enum_for(:each)
  end
end