Class: Expressir::Express::Visitor
- Inherits:
-
Object
- Object
- Expressir::Express::Visitor
- Defined in:
- lib/expressir/express/visitor.rb
Defined Under Namespace
Instance Method Summary collapse
- #get_source(ctx) ⇒ Object
- #get_source_pos(ctx) ⇒ Object
-
#initialize(source, include_source: nil) ⇒ Visitor
constructor
A new instance of Visitor.
- #to_ctx(ast, name = :unnamed) ⇒ Object
- #visit(ctx) ⇒ Object
- #visit_ast(ast, name) ⇒ Object
Constructor Details
#initialize(source, include_source: nil) ⇒ Visitor
Returns a new instance of Visitor.
84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/expressir/express/visitor.rb', line 84 def initialize(source, include_source: nil) @source = source @include_source = include_source @attached_remark_tokens = Set.new @visit_methods = Hash[ private_methods.grep(/^visit_/).map do |name| rulename = name.to_s.sub(/^visit_/, "").gsub(/_([a-z])/) { $1.upcase } [rulename.to_sym, name.to_sym] end ] end |
Instance Method Details
#get_source(ctx) ⇒ Object
147 148 149 150 |
# File 'lib/expressir/express/visitor.rb', line 147 def get_source(ctx) a, b = get_source_pos ctx @source[a..b - 1].strip end |
#get_source_pos(ctx) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/expressir/express/visitor.rb', line 125 def get_source_pos(ctx) nil ranges = case ctx when Ctx ctx.source_pos and return ctx.source_pos # cache ctx.values.map { |item| get_source_pos(item) } when SimpleCtx return nil unless ctx.data.respond_to? :offset [[ctx.data.offset, ctx.data.offset + ctx.data.length]] when Array ctx.map { |item| get_source_pos(item) } else raise "unknown type in Ctx tree: #{ctx}" end source_pos = ranges.compact.reduce do |item, acc| [[item[0], acc[0]].min, [item[1], acc[1]].max] end Ctx === ctx and ctx.source_pos = source_pos source_pos end |
#to_ctx(ast, name = :unnamed) ⇒ Object
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 123 |
# File 'lib/expressir/express/visitor.rb', line 98 def to_ctx(ast, name = :unnamed) case ast when Hash nodes = Hash[ ast.map do |k, v| if k =~ /^listOf_(.*)$/ itemkey = $1.to_sym ary = Array === v ? v : [v] [itemkey, to_ctx(ary.select { |v| v[itemkey] }.map { |v| v.slice(itemkey) })] else [k, to_ctx(v, k)] end end ] Ctx.new nodes, name when Array ast.map do |v| v.length == 1 or raise "element of array invalid (#{v.keys})" to_ctx(v.values[0], v.keys[0]) end when nil nil else SimpleCtx.new ast, name end end |
#visit(ctx) ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/expressir/express/visitor.rb', line 158 def visit(ctx) if Array === ctx return ctx.map { |el| visit el } end node = ctx if @visit_methods[ctx.name] node = send(@visit_methods[ctx.name], ctx) if @include_source && node.respond_to?(:source) node.source = get_source ctx end end attach_remarks(ctx, node) node end |
#visit_ast(ast, name) ⇒ Object
152 153 154 155 156 |
# File 'lib/expressir/express/visitor.rb', line 152 def visit_ast(ast, name) ctx = to_ctx(ast, name) visit ctx end |