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 { |name| rulename = name.to_s.sub(/^visit_/,"").gsub(/_([a-z])/) { $1.upcase } [rulename.to_sym,name.to_sym] } ] end |
Instance Method Details
#get_source(ctx) ⇒ Object
146 147 148 149 |
# File 'lib/expressir/express/visitor.rb', line 146 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 |
# File 'lib/expressir/express/visitor.rb', line 125 def get_source_pos(ctx) ranges = 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 { |item,acc| [ [item[0],acc[0]].min, [item[1],acc[1]].max ] } 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 { |k,v| if k.match(/^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 } ] Ctx.new nodes,name when Array ast.map { |v| v.length == 1 or raise "element of array invalid (#{v.keys})" to_ctx(v.values[0],v.keys[0]) } when nil nil else SimpleCtx.new ast,name end end |
#visit(ctx) ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/expressir/express/visitor.rb', line 157 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
151 152 153 154 155 |
# File 'lib/expressir/express/visitor.rb', line 151 def visit_ast(ast,name) ctx = to_ctx(ast,name) visit ctx end |