class EBNF::ISOEBNF

Constants

FIRST_TERMINAL_CHARACTER
SECOND_TERMINAL_CHARACTER
SPECIAL_SEQUENCE_CHARACTER
TERMINAL_CHARACTER
TERMINAL_CHARACTER_BASE

The base for terminal-character, which omits “‘”, ’“‘, and ’?‘. Could be more optimized, and one might quible with the overly-strictly defined character set, but it is correct.

Attributes

ast[R]

Abstract syntax tree from parse

@return [Array<EBNF::Rule>]

Public Class Methods

new(input, **options, &block) click to toggle source

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

@param [#read, to_s] input @param [Hash{Symbol => Object}] options @option options [Boolean] :level

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

@return [EBNFParser]

# File lib/ebnf/isoebnf.rb, line 197
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,
        :syntax,
        ISOEBNFMeta::RULES,
        whitespace: %r{([\x09-\x0d\x20]|(?:\(\*(?:(?:\*[^\)])|[^*])*\*\)))+},
        **options
  ) do |context, *data|
    rule = case context
    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