Class: EBNF::Parser

Inherits:
Object
  • Object
show all
Includes:
EBNF::PEG::Parser, Terminals
Defined in:
lib/ebnf/parser.rb

Constant Summary

Constants included from Terminals

Terminals::CHAR, Terminals::HEX, Terminals::LHS, Terminals::O_RANGE, Terminals::PASS, Terminals::POSTFIX, Terminals::RANGE, Terminals::R_CHAR, Terminals::STRING1, Terminals::STRING2, Terminals::SYMBOL, Terminals::SYMBOL_BASE

Instance Attribute Summary collapse

Attributes included from EBNF::PEG::Parser

#packrat, #scanner, #whitespace

Instance Method Summary collapse

Methods included from EBNF::PEG::Parser

#clear_packrat, #debug, #depth, #error, #find_rule, included, #onFinish, #onStart, #onTerminal, #parse, #prod_data, #progress, #terminal_options, #terminal_regexp, #update_furthest_failure, #warn

Constructor Details

#initialize(input, **options, &block) ⇒ EBNFParser

## Parser invocation. On start, yield ourselves if a block is given, otherwise, return this parser instance

Parameters:

  • input (#read, #to_s)
  • options (Hash{Symbol => Object})

Options Hash (**options):

  • :level (Boolean)

    Trace level. 0(debug), 1(info), 2(warn), 3(error).


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
# File 'lib/ebnf/parser.rb', line 265

def initialize(input, **options, &block)
  # If the `level` option is set, instantiate a logger for collecting trace information.
  if options.has_key?(:level)
    options[:logger] = Logger.new(STDERR)
    options[:logger].level = options[:level]
    options[:logger].formatter = lambda {|severity, datetime, progname, msg| "#{severity} #{msg}\n"}
  end

  # Read input, if necessary, which will be used in a Scanner.
  @input = input.respond_to?(:read) ? input.read : input.to_s

  parsing_terminals = false
  @ast = []
  parse(@input, :ebnf, EBNFMeta::RULES,
                       # Use an optimized Regexp for whitespace
                       whitespace: EBNF::Terminals::PASS,
                       **options
  ) do |context, *data|
    rule = case context
    when :terminals
      # After parsing `@terminals`
      # This changes the state of the parser to treat subsequent rules as terminals.
      parsing_terminals = true
      rule = EBNF::Rule.new(nil, nil, data.first, kind: :terminals)
    when :pass
      # After parsing `@pass`
      # This defines a specific rule for whitespace.
      rule = EBNF::Rule.new(nil, nil, data.first, kind: :pass)
    when :rule
      # A rule which has already been turned into a `Rule` object.
      rule = data.first
      rule.kind = :terminal if parsing_terminals
      rule
    end
    @ast << rule if rule
  end
rescue EBNF::PEG::Parser::Error => e
  raise SyntaxError, e.message
end

Instance Attribute Details

#astArray<EBNF::Rule> (readonly)

Abstract syntax tree from parse

Returns:


12
13
14
# File 'lib/ebnf/parser.rb', line 12

def ast
  @ast
end