class Mustermann::AST::Transformer::ArrayTransform
@!visibility private
Inserts with_look_ahead nodes wherever appropriate
def create_lookahead(elements, *args)
turn look ahead buffer into look ahead node
def create_lookahead(elements, *args) return elements unless elements.size > 1 [Node[:with_look_ahead].new(elements, *args, start: elements.first.start, stop: elements.last.stop)] end
def expect_lookahead?(element)
can the current element deal with a look-ahead?
def expect_lookahead?(element) return element.class == Node[:capture] unless element.is_a? Node[:group] element.payload.all? { |e| expect_lookahead?(e) } end
def list_for(element)
helper method for deciding where to put an element for now
def list_for(element) expect_lookahead?(element) ? lookahead_buffer : payload end
def lookahead?(element, in_lookahead = false)
can the given element be used in a look-ahead?
def lookahead?(element, in_lookahead = false) case element when Node[:char] then in_lookahead when Node[:group] then lookahead_payload?(element.payload, in_lookahead) when Node[:optional] then lookahead?(element.payload, true) or expect_lookahead?(element.payload) end end
def lookahead_buffer
buffer for potential look ahead
def lookahead_buffer @lookahead_buffer ||= [] end
def lookahead_payload?(payload, in_lookahead)
does the list of elements look look-ahead-ish to you?
def lookahead_payload?(payload, in_lookahead) return unless payload[0..-2].all? { |e| lookahead?(e, in_lookahead) } expect_lookahead?(payload.last) or lookahead?(payload.last, in_lookahead) end
def payload
the new array
def payload @payload ||= [] end
def track(element)
handle a single element from the array
def track(element) return list_for(element) << element if lookahead_buffer.empty? return lookahead_buffer << element if lookahead? element lookahead = lookahead_buffer.dup lookahead = create_lookahead(lookahead, false) if element.is_a? Node[:separator] lookahead_buffer.clear payload.concat(lookahead) << element end
def translate
transform the array
def translate each { |e| track t(e) } payload.concat create_lookahead(lookahead_buffer, true) end