Method: EBNF::Base#initialize

Defined in:
lib/ebnf/base.rb

#initialize(input, format: :ebnf, **options) ⇒ Base

Parse the string or file input generating an abstract syntax tree in S-Expressions (similar to SPARQL SSE)

Parameters:

  • input (#read, #to_s)
  • format (Symbol) (defaults to: :ebnf)

    (:ebnf) Format of input, one of ‘:abnf`, `:ebnf`, `:isoebnf`, `:isoebnf`, `:native`, or `:sxp`. Use `:native` for the native EBNF parser, rather than the PEG parser.

  • options (Hash{Symbol => Object})

Options Hash (**options):

  • :debug (Boolean, Array)

    Output debug information to an array or $stdout.

  • :validate (Boolean, Array)

    Validate resulting grammar.



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/ebnf/base.rb', line 112

def initialize(input, format: :ebnf, **options)
  @options = options.dup
  @lineno, @depth, @errors = 1, 0, []
  @ast = []

  input = input.respond_to?(:read) ? input.read : input.to_s

  case format
  when :abnf
    abnf = ABNF.new(input, **options)
    @ast = abnf.ast
  when :ebnf
    ebnf = Parser.new(input, **options)
    @ast = ebnf.ast
  when :isoebnf
    iso = ISOEBNF.new(input, **options)
    @ast = iso.ast
  when :native
    terminals = false
    scanner = StringScanner.new(input)

    eachRule(scanner) do |r|
      debug("rule string") {r.inspect}
      case r
      when /^@terminals/
        # Switch mode to parsing terminals
        terminals = true
        rule = Rule.new(nil, nil, nil, kind: :terminals, ebnf: self)
        @ast << rule
      when /^@pass\s*(.*)$/m
        expr = expression($1).first
        rule = Rule.new(nil, nil, expr, kind: :pass, ebnf: self)
        rule.orig = expr
        @ast << rule
      else
        rule = depth {ruleParts(r)}

        rule.kind = :terminal if terminals # Override after we've parsed @terminals
        rule.orig = r
        @ast << rule
      end
    end
  when :sxp
    require 'sxp' unless defined?(SXP)
    @ast = SXP::Reader::Basic.read(input).map {|e| Rule.from_sxp(e)}
  else
    raise "unknown input format #{format.inspect}"
  end

  validate! if @options[:validate]
end