From 379a016621e3c965e8da75ca9c8aeba29316d532 Mon Sep 17 00:00:00 2001 From: David Bailey Date: Thu, 13 Apr 2023 10:01:30 +0200 Subject: [PATCH] feat: :sparkles: properly implement parser engine module --- lib/comfpile/engines/parser_engine.rb | 110 +++++++++++--------------- 1 file changed, 44 insertions(+), 66 deletions(-) diff --git a/lib/comfpile/engines/parser_engine.rb b/lib/comfpile/engines/parser_engine.rb index fff70b9..2c02990 100644 --- a/lib/comfpile/engines/parser_engine.rb +++ b/lib/comfpile/engines/parser_engine.rb @@ -1,7 +1,8 @@ require_relative '../artefact.rb' +require_relative '../artefact_engine.rb' -module Compfile +module Comfpile class ParserArtefact < Comfpile::Artefact def initialize(*args, **opts) super(*args) @@ -34,11 +35,10 @@ module Compfile output else - @parsed_parameters[key] || [] + @parsed_parameters[keys] || [] end end - # # Try to find a relative or absolute source file # artefact. # Used to resolve the include, require and reference @@ -60,18 +60,16 @@ module Compfile if(name.is_a? Array) name.map do |n| resolve_sourcefile(n, optional: optional) - end - - name.compact + end.compact else own_dir = File.dirname(@target) - relative_file = File.join(own_dir, name) + relative_file = File.join(own_dir, name).gsub(/^\.\//, '') if not craft_artefact(:sourcefile, relative_file).nil? relative_file elsif not craft_artefact(:sourcefile, name).nil? name - elsif optional + elsif not optional relative_file else nil @@ -82,94 +80,73 @@ module Compfile def sourcefile_parse_step log "Parsing file #{@target}..." + param_count = 0 + File.readlines(@parent_artefact[:file]).each do |line| @search_regexes.each do |r| - match = r.match line - next if match.nil? + next if r[:regex].nil? - key = match[:key] - value = match[:value] + match = r[:regex].match line + next if match.nil? + match = match.named_captures + + key = match['key'] || r[:key] + value = match['value'] || r[:value] next if key.nil? log "Found k/v pair: '#{key}' '#{value}'", :debug + param_count += 1 @parsed_parameters[key] ||= [] @parsed_parameters[key] << value end end - log "Parsing completed, found #{@parsed_parameters.keys.size} parameters!" + log "Parsing completed, found #{param_count} parameters!" end def sourcefile_dependency_step - included_artefacts = resolve_sourcefile find_parsed_parameters 'include' - required_artefacts = resolve_sourcefile find_parsed_parameters 'require' - referenced_artefacts = resolve_sourcefile find_parsed_parameters 'reference' + included_artefacts = resolve_sourcefile find_parsed_parameters('include'), optional: true + required_artefacts = resolve_sourcefile find_parsed_parameters('require') + referenced_artefacts = resolve_sourcefile find_parsed_parameters('reference') - included_artefacts.each { |a| include_artefact :parsed, a } - required_artefacts.each { |a| require_artefact :parsed, a } - referenced_artefacts.each { |a| reference_artefact :parsed, a } + included_artefacts.each { |a| include_artefact :parsed, a, wait_if_exists: false } + required_artefacts.each { |a| require_artefact :parsed, a, wait_if_exists: false } + referenced_artefacts.each { |a| reference_artefact :parsed, a, wait_if_exists: false, required: true } - log "Generated dependencies. Included #{included_artefacts.size}, required #{required_artefact.size} and referenced #{referenced_artefacts.size}." + log "Generated dependencies. Included #{included_artefacts.size}, required #{required_artefacts.size} and referenced #{referenced_artefacts.size}." end end class ParserEngine < ArtefactEngine + # + # Initialize a new ParserEngine + # + # This engine has the task of generating single-file parser artefacts, + # which check for comfpile parameters that will be extracted from the sourcefile. + # Each file will recursively craft other files it requires and add them, either as + # fully included, required, or referenced file. + # + # @param [] core + # @param [] **options + # def initialize(core, **options) super(core, **options) - @input_file_regex = options[:allowed_files] + @input_file_regex = options[:file_regex] + @search_regexes = options[:search_regexes] - @require_regex = options[:require_reg] - @include_regex = options[:include_reg] + raise ArgumentError, "Missing input file regex!" unless @input_file_regex.is_a? Regexp + raise ArgumentError, "Missing regex parsing array!" unless @search_regexes.is_a? Array end def generate_parser_artefact(stage, target) match = @input_file_regex.match target return nil if match.nil? - a = Artefact.new(@core, self, stage, target) - - a.parent_artefact(:sourcefile, target) - - a.add_step do - - @parameters[:included_files] = [] - @parameters[:required_files] = [] - - File.readlines(@parent_artefact[:file]) do |l| - case l - when @require_regex - filename = $~[:file] - - own_dir = File.dirname(@target) - relative_file = File.join(own_dir, filename) - - unless craft_artefact(:sourcefile, relative_file).nil? - @parameters[:required_files] << require_artefact(:parsed, relative_file) - else - @parameters[:required_files] << require_artefact(:parsed, filename) - end - - when @include_regex - filename = $~[:file] - - own_dir = File.dirname(@target) - relative_file = File.join(own_dir, filename) - - unless craft_artefact(:sourcefile, relative_file).nil? - @parameters[:included_files] << craft_artefact(:parsed, relative_file) - else - @parameters[:included_files] << craft_artefact(:parsed, filename) - end - end - end - end - end - - def generate_dependency_artefact(stage, target) - + ParserArtefact.new(@core, self, stage, target, + search_regexes: @search_regexes) end def craft(stage, target) @@ -177,9 +154,10 @@ module Compfile when :parsed generate_parser_artefact(stage, target) when :dependency_list - + nil else nil end end - end \ No newline at end of file + end +end \ No newline at end of file