1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
require 'journey/visitors'
module Journey
module Nodes
class Node # :nodoc:
include Enumerable
attr_accessor :left, :memo
def initialize left
@left = left
@memo = nil
end
def each(&block)
Visitors::Each.new(block).accept(self)
end
def to_s
Visitors::String.new.accept(self)
end
def to_dot
Visitors::Dot.new.accept(self)
end
def to_sym
name.to_sym
end
def name
left.tr ':', ''
end
def type
raise NotImplementedError
end
def symbol?; false; end
def literal?; false; end
end
class Terminal < Node
alias :symbol :left
end
class Literal < Terminal
def literal?; true; end
def type; :LITERAL; end
end
class Dummy < Literal
def initialize x = Object.new
super
end
def literal?; false; end
end
%w{ Symbol Slash Dot }.each do |t|
class_eval %{
class #{t} < Terminal
def type; :#{t.upcase}; end
end
}
end
class Symbol < Terminal
attr_accessor :regexp
alias :symbol :regexp
DEFAULT_EXP = /[^\.\/\?]+/
def initialize left
super
@regexp = DEFAULT_EXP
end
def default_regexp?
regexp == DEFAULT_EXP
end
def symbol?; true; end
end
class Unary < Node
def children; [value] end
end
class Group < Unary
def type; :GROUP; end
end
class Star < Unary
def type; :STAR; end
end
class Binary < Node
attr_accessor :right
def initialize left, right
super(left)
@right = right
end
def children; [left, right] end
end
class Cat < Binary
def type; :CAT; end
end
class Or < Node
attr_reader :children
def initialize children
@children = children
end
def type; :OR; end
end
end
end
|