class EBNF::ABNF

Constants

ALPHA

Regular expressions for both “Core” and ABNF-specific terminals.

COMMENT
CRLF
C_NL
C_WSP
VCHAR
WSP

Attributes

parsed_rules[R]

Hash of generated {EBNF::Rule} objects by symbol

@return [Hash{Symbol => EBNF::Rule}]

Public Class Methods

new(input, **options) 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/abnf.rb, line 235
def initialize(input, **options)
  # 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

  @parsed_rules = {}

  # Parses into `@parsed_rules`
  parse(@input,
        :rulelist,        # Starting rule
        ABNFMeta::RULES,  # PEG rules
        whitespace: '',   # No implicit whitespace
        **options)
rescue EBNF::PEG::Parser::Error => e
  raise SyntaxError, e.message
end

Public Instance Methods

ast() click to toggle source

The AST includes the parsed rules along with built-in rules for ABNF used within the parsed grammar.

@return [Array<EBNF::Rule>]

# File lib/ebnf/abnf.rb, line 262
def ast
  # Add built-in rules for standard ABNF rules not
  parsed_rules.values.map(&:symbols).flatten.uniq.each do |sym|
    rule = ABNFCore::RULES.detect {|r| r.sym == sym}
    parsed_rules[sym] ||= rule if rule
  end

  parsed_rules.values
end

Private Instance Methods

hex_or_string(characters) click to toggle source

Generate a combination of seq and string to represent a sequence of characters

@param [Array<String>] characters @return [String,Array]

# File lib/ebnf/abnf.rb, line 277
def hex_or_string(characters)
  seq = [:seq]
  str_result = ""
  characters.each do |c|
    if VCHAR.match?(c)
      str_result << c
    else
      if str_result.length > 0
        seq << str_result
        str_result = ""
      end
      seq << [:hex, "#x%x" % c.codepoints.first]
    end
  end
  seq << str_result if str_result.length > 0

  # Either return the sequence, or a string
  if seq.length == 2 && seq.last.is_a?(String)
    seq.last
  else
    seq
  end
end