Class: EBNFPegParser

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

Constant Summary

Constants included from EBNF::Terminals

EBNF::Terminals::CHAR, EBNF::Terminals::HEX, EBNF::Terminals::LHS, EBNF::Terminals::O_RANGE, EBNF::Terminals::PASS, EBNF::Terminals::POSTFIX, EBNF::Terminals::RANGE, EBNF::Terminals::RANGE_NOT_LHS, EBNF::Terminals::R_CHAR, EBNF::Terminals::STRING1, EBNF::Terminals::STRING2, EBNF::Terminals::SYMBOL, EBNF::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, #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).



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
# File 'examples/ebnf-peg-parser/parser.rb', line 273

def initialize(input, **options, &block)
  # If the `level` option is set, instantiate a logger for collecting trace information.
  if options.key?(:level)
    options[:logger] ||= Logger.new(STDERR).
      tap {|x| x.level = options[:level]}.
      tap {|x| x.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, EBNFPegMeta::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
  @ast
end

Instance Attribute Details

#astArray<EBNF::Rule> (readonly)

Abstract syntax tree from parse

Returns:



18
19
20
# File 'examples/ebnf-peg-parser/parser.rb', line 18

def ast
  @ast
end

Instance Method Details

#to_sxp(**options) ⇒ String

Output formatted S-Expression of grammar

Returns:

  • (String)


315
316
317
318
319
# File 'examples/ebnf-peg-parser/parser.rb', line 315

def to_sxp(**options)
  require 'sxp' unless defined?(SXP)
  # Output rules as a formatted S-Expression
  SXP::Generator.string(@ast.map(&:for_sxp))
end