lib/ebnf/base.rb in ebnf-0.3.1 vs lib/ebnf/base.rb in ebnf-0.3.2

- old
+ new

@@ -117,34 +117,48 @@ # # @param [#read, #to_s] input # @param [Hash{Symbol => Object}] options # @option options [Boolean, Array] :debug # Output debug information to an array or STDOUT. + # @option options [Symbol] :format (:ebnf) + # Format of input, one of :ebnf, or :sxp def initialize(input, options = {}) - @options = options + @options = {:format => :ebnf}.merge(options) @lineno, @depth, @errors = 1, 0, [] terminal = false @ast = [] input = input.respond_to?(:read) ? input.read : input.to_s - scanner = StringScanner.new(input) - eachRule(scanner) do |r| - debug("rule string") {r.inspect} - case r - when /^@terminals/ - # Switch mode to parsing terminals - terminal = true - when /^@pass\s*(.*)$/m - # Ignore, as we can't use this for processing the EBNF grammar itself - else - rule = depth {ruleParts(r)} + case @options[:format] + when :sxp + require 'sxp' unless defined?(SXP) + @ast = SXP::Reader::Basic.read(input).map {|e| Rule.from_sxp(e)} + when :ebnf + scanner = StringScanner.new(input) - rule.kind = :terminal if terminal # Override after we've parsed @terminals - rule.orig = r - @ast << rule + eachRule(scanner) do |r| + debug("rule string") {r.inspect} + case r + when /^@terminals/ + # Switch mode to parsing terminals + terminal = true + when /^@pass\s*(.*)$/m + expr = expression($1).first + rule = Rule.new(nil, nil, expr, :kind => :pass) + rule.orig = expr + @ast << rule + else + rule = depth {ruleParts(r)} + + rule.kind = :terminal if terminal # Override after we've parsed @terminals + rule.orig = r + @ast << rule + end end + else + raise "unknown input format #{options[:format].inspect}" end end # Iterate over each rule or terminal, except empty # @param [:termina, :rule] kind @@ -156,9 +170,10 @@ ## # Write out parsed syntax string as an S-Expression # @return [String] def to_sxp + require 'sxp' unless defined?(SXP) SXP::Generator.string(ast.sort_by{|r| r.id.to_f}.map(&:for_sxp)) end def to_s; to_sxp; end def dup \ No newline at end of file