class BlifUtils::Parser
Public Class Methods
parse(fileName, quiet: false)
click to toggle source
# File lib/blifutils/parser.rb, line 116 def self.parse (fileName, quiet: false) processedFileNames = [] ast = self.parse_recursive(File.expand_path(fileName), processedFileNames, quiet) return ast end
parse_string(str, quiet: false)
click to toggle source
# File lib/blifutils/parser.rb, line 123 def self.parse_string (str, quiet: false) lexems = BlifUtils::Language::Lexer::lex(str) begin ast = BlifUtils::Language::Parser::parse(lexems) rescue RLTK::NotInLanguage => e print_parse_error(e.current, 'String not in grammar.') rescue RLTK::BadToken => e print_parse_error(e.faultyToken, "Unexpected token: \"#{e.faultyToken.type.to_s}\". Token not present in grammar definition.") end # Delete file references from the AST ast.modelList.delete_if do |elem| if elem.kind_of?(BlifUtils::AST::SubfileReference) then STDERR.puts "WARNING: Ignoring \".search #{elem.fileName}\"" unless quiet true else false end end ast.modelList.each do |model| model.commands.delete_if do |com| if com.kind_of?(BlifUtils::AST::SubfileReference) then STDERR.puts "WARNING: Ignoring \".search #{com.fileName}\"" unless quiet true else false end end end return ast end
Private Class Methods
parse_file(fileName, quiet = false)
click to toggle source
# File lib/blifutils/parser.rb, line 179 def self.parse_file (fileName, quiet = false) puts "Parsing file \"#{fileName}\"..." unless quiet lexems = BlifUtils::Language::Lexer::lex_file(fileName) begin ast = BlifUtils::Language::Parser::parse(lexems) rescue RLTK::NotInLanguage => e print_parse_error(e.current, 'String not in grammar.') rescue RLTK::BadToken => e print_parse_error(e.faultyToken, "Unexpected token: \"#{e.faultyToken.type.to_s}\". Token not present in grammar definition.") end return ast end
parse_recursive(fileName, processedFileNames, quiet = false)
click to toggle source
# File lib/blifutils/parser.rb, line 195 def self.parse_recursive (fileName, processedFileNames, quiet = false) return BlifUtils::AST::TranslationUnit.new if processedFileNames.include?(fileName) processedFileNames << fileName # Parse the file ast = self.parse_file(fileName, quiet) # Gather new file to parse newFileToParseList = [] ast.modelList.each do |element| if element.kind_of?(BlifUtils::AST::SubfileReference) then # file reference outside a model newFileToParseList << element.fileName else # it is a Model element.commands.select{|elm| elm.kind_of?(BlifUtils::AST::SubfileReference)}.each do |com| newFileToParseList << com.fileName end end end # Delete file references from the AST ast.modelList.delete_if{|elem| elem.kind_of?(BlifUtils::AST::SubfileReference)} ast.modelList.each do |model| model.commands.delete_if{|com| com.kind_of?(BlifUtils::AST::SubfileReference)} end # Get absolute path of new file to parse dirname = File.dirname(fileName) newFileToParseList.collect!{|fn| File.expand_path(fn, dirname)} # Parse new files newFileToParseList.each do |newFileName| newAst = self.parse_recursive(newFileName, processedFileNames, quiet) newAst.modelList.each do |newModel| if ast.modelList.collect{|model| model.name}.include?(newModel.name) then abort "ERROR: Model \"#{newModel.name}\" is redefined" end ast.modelList << newModel end end return ast end
print_parse_error(token, errorString)
click to toggle source
# File lib/blifutils/parser.rb, line 162 def self.print_parse_error (token, errorString) unless token.position.nil? then fileName = token.position.file_name line = token.position.line_number column = token.position.line_offset STDERR.puts "ERROR: Parse error at line #{line}, column #{column+1}, from file \"#{fileName}\":\n#{errorString}" str = File.read(fileName).lines.to_a[line-1].gsub(/\t/,' ') STDERR.puts (line.to_s + ': ') + str abort ' '*(line.to_s.length + 2) + ('~'*column + '^') else STDERR.puts "Parse error:" abort errorString end end