module Take class Unit class Compiler include PredictMatch attr_reader :parent def initialize(file, tokens) @file = file @tokens = tokens @enum = tokens.each @parent = nil end def compile @parent ||= begin @parent = AST::Parent.new(name: @file. gsub(/\..*\z/, "").gsub(/[\W]/, "_")) while peek do @parent.children << compile_group end @parent.source = sourcify([0, 0]) @parent end end def compile_group group = match(:group) node = AST::Group.new(name: group[1], source: sourcify(group)) until peek == :group_end part = compile_part node.children << part if part end match(:group_end) node end def compile_part predict :group => :group, :test => :test, :before => :before, :after => :after, :prefix => :prefix, :macro => :macro end def compile_test test = match(:test) body = match(:block) AST::Test.new(name: test[1], children: [AST::Block.new({ body: body[1], source: sourcify(body) })], source: sourcify(test)) end def compile_before before = match(:before) body = match(:block) AST::Before.new(name: before[1], children: [AST::Block.new({ body: body[1], source: sourcify(body) })], source: sourcify(before)) end def compile_after after = match(:after) body = match(:block) AST::After.new(name: after[1], children: [AST::Block.new({ body: body[1], source: sourcify(body) })], source: sourcify(after)) end def compile_prefix prefix = match(:prefix) body = match(:block) @parent.children << AST::Prefix.new( name: prefix[1], children: [AST::Block.new({ body: body[1], source: sourcify(body) })], source: sourcify(prefix)) nil end def compile_macro end private def input @enum end def sourcify(token) hash = Hash[[:line, :column].zip(token[-2..-1])] hash.merge(file: @file) end end end end