feat: 🚧 continue implementing a proper parser engine
This commit is contained in:
parent
e107825c59
commit
d415aa6860
1 changed files with 106 additions and 3 deletions
|
@ -1,15 +1,118 @@
|
||||||
|
|
||||||
|
require_relative '../artefact.rb'
|
||||||
|
|
||||||
module Compfile
|
module Compfile
|
||||||
class ParserArtefact < Artefact
|
class ParserArtefact < Comfpile::Artefact
|
||||||
def initialize(*args, **opts)
|
def initialize(*args, **opts)
|
||||||
super(*args, **opts)
|
super(*args)
|
||||||
|
|
||||||
|
@search_regexes = opts[:search_regexes]
|
||||||
|
|
||||||
|
@parsed_parameters = {}
|
||||||
|
|
||||||
parent_artefact :sourcefile, @target
|
parent_artefact :sourcefile, @target
|
||||||
|
|
||||||
add_step do
|
add_step do
|
||||||
|
sourcefile_parse_step
|
||||||
|
sourcefile_dependency_step
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Attempts to find the set of values for a given
|
||||||
|
# parameter key.
|
||||||
|
#
|
||||||
|
# @param [String, Array<String>] keys Key, or array of keys, to look for
|
||||||
|
#
|
||||||
|
# @return [Array<String>] Array of values found for this key
|
||||||
|
#
|
||||||
|
def find_parsed_parameters(keys)
|
||||||
|
if keys.is_a? Array
|
||||||
|
output = []
|
||||||
|
keys.each do |key|
|
||||||
|
output += @parsed_parameters[key] || []
|
||||||
|
end
|
||||||
|
|
||||||
|
output
|
||||||
|
else
|
||||||
|
@parsed_parameters[key] || []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Try to find a relative or absolute source file
|
||||||
|
# artefact.
|
||||||
|
# Used to resolve the include, require and reference
|
||||||
|
# statements and find relative and/or absolute source
|
||||||
|
# files with matching name. Similar to how C++'s
|
||||||
|
# include statement it will check relative, then
|
||||||
|
# globally.
|
||||||
|
#
|
||||||
|
# @param [String, Array<String>] name Path of the sourcefile to look for
|
||||||
|
# @param [Boolean] optional If true, will also check for absolute
|
||||||
|
# source file, and will discard the file if it can't be found.
|
||||||
|
# Useful for e.g. C/C++ header files that may not be in the search
|
||||||
|
# path of comfpile.
|
||||||
|
#
|
||||||
|
# @return [String] Resolved path of the sourcefile. Relative
|
||||||
|
# if a relative file is found, else absolute.
|
||||||
|
#
|
||||||
|
def resolve_sourcefile(name, optional: false)
|
||||||
|
if(name.is_a? Array)
|
||||||
|
name.map do |n|
|
||||||
|
resolve_sourcefile(n, optional: optional)
|
||||||
|
end
|
||||||
|
|
||||||
|
name.compact
|
||||||
|
else
|
||||||
|
own_dir = File.dirname(@target)
|
||||||
|
relative_file = File.join(own_dir, name)
|
||||||
|
|
||||||
|
if not craft_artefact(:sourcefile, relative_file).nil?
|
||||||
|
relative_file
|
||||||
|
elsif not craft_artefact(:sourcefile, name).nil?
|
||||||
|
name
|
||||||
|
elsif optional
|
||||||
|
relative_file
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def sourcefile_parse_step
|
||||||
|
log "Parsing file #{@target}..."
|
||||||
|
|
||||||
|
File.readlines(@parent_artefact[:file]).each do |line|
|
||||||
|
@search_regexes.each do |r|
|
||||||
|
match = r.match line
|
||||||
|
next if match.nil?
|
||||||
|
|
||||||
|
key = match[:key]
|
||||||
|
value = match[:value]
|
||||||
|
|
||||||
|
next if key.nil?
|
||||||
|
|
||||||
|
log "Found k/v pair: '#{key}' '#{value}'", :debug
|
||||||
|
|
||||||
|
@parsed_parameters[key] ||= []
|
||||||
|
@parsed_parameters[key] << value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
log "Parsing completed, found #{@parsed_parameters.keys.size} 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.each { |a| include_artefact :parsed, a }
|
||||||
|
required_artefacts.each { |a| require_artefact :parsed, a }
|
||||||
|
referenced_artefacts.each { |a| reference_artefact :parsed, a }
|
||||||
|
|
||||||
|
log "Generated dependencies. Included #{included_artefacts.size}, required #{required_artefact.size} and referenced #{referenced_artefacts.size}."
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class ParserEngine < ArtefactEngine
|
class ParserEngine < ArtefactEngine
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue