Class: ISOEBNFPegParser

Inherits:
Object
  • Object
show all
Includes:
EBNF::PEG::Parser
Defined in:
examples/isoebnf/parser.rb

Constant Summary collapse

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.

%r{
  [a-zA-Z0-9] | # letter | decimal digit
  ,           | # concatenate symbol
  =           | # defining symbol
  [\|\/!]     | # definition separator symbol
  \*\)        | # end comment symbol
  \)          | # end group symbol
  \]          | # end option symbol
  \}          | # end repeat symbol
  \-          | # except symbol
  #\'          | # first quote symbol
  \*          | # repetition symbol
  #\"          | # second quote symbol
  #\?          | # special sequence symbol
  \(\*        | # start comment symbol
  \(          | # start group symbol
  \[          | # start option symbol
  \{          | # start repeat symbol
  [;\.]       | # terminator symbol
  [:+_%@&$<>^\x20\x23\\`~]  # other character
}x
TERMINAL_CHARACTER =
%r{#{TERMINAL_CHARACTER_BASE}|['"\?]}
FIRST_TERMINAL_CHARACTER =
%r{#{TERMINAL_CHARACTER_BASE}|["\?]}
SECOND_TERMINAL_CHARACTER =
%r{#{TERMINAL_CHARACTER_BASE}|['\?]}
SPECIAL_SEQUENCE_CHARACTER =
%r{#{TERMINAL_CHARACTER_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).



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'examples/isoebnf/parser.rb', line 201

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,
         :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
  @ast
end

Instance Attribute Details

#astArray<EBNF::Rule> (readonly)

Abstract syntax tree from parse

Returns:



48
49
50
# File 'examples/isoebnf/parser.rb', line 48

def ast
  @ast
end

Instance Method Details

#to_sxp(**options) ⇒ String

Output formatted S-Expression of grammar

Returns:

  • (String)


235
236
237
238
239
# File 'examples/isoebnf/parser.rb', line 235

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