Sha256: 8cd97da3b3762af5a87e61dd36f443c193a3cdd08471c5aaa60b53db2df00695

Contents?: true

Size: 1.37 KB

Versions: 3

Compression:

Stored size: 1.37 KB

Contents

module Sexpr
  module Grammar
    module Matching

      def root_rule
        rules[root]
      end

      def [](rule_name)
        rules[rule_name]
      end

      def match?(sexp)
        root_rule.match?(sexp)
      end
      alias :=== :match?

      private

      def compile_rules(rules)
        Hash[rules.map{|k,v|
          [k.to_sym, compile_rule(k.to_sym, v)]
        }]
      end

      def compile_rule(name, defn)
        case rule = compile_rule_defn(defn)
        when Matcher::Terminal, Matcher::Alternative
          rule
        else
          Matcher::Rule.new(name, rule)
        end
      end

      def compile_rule_defn(arg, grammar = self)
        case arg
        when Matcher
          arg
        when Regexp, TrueClass, FalseClass, NilClass
          Matcher::Terminal.new arg
        when lambda{|x| x.is_a?(Array) && x.size == 1 && x.first.is_a?(Array)}
          Matcher::Sequence.new arg.first.map{|s| compile_rule_defn(s) }
        when Array
          Matcher::Alternative.new arg.map{|s| compile_rule_defn(s)}
        when /([\?\+\*])$/
          Matcher::Many.new compile_rule_defn($`), $1
        when /^[a-z][a-z_]+$/
          Matcher::Reference.new arg.to_sym, grammar
        else
          raise ArgumentError, "Invalid rule definition: #{arg.inspect}", caller
        end
      end

    end # module Matching
  end # module Grammar
end # module Sexpr

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
sexpr-0.5.0 lib/sexpr/grammar/matching.rb
sexpr-0.4.0 lib/sexpr/grammar/matching.rb
sexpr-0.3.0 lib/sexpr/grammar/matching.rb