Class: Parser
- Inherits:
-
Object
- Object
- Parser
- Defined in:
- lib/Parser.rb
Overview
This class handles all parsing operations for this application. It makes extensive use of the ParseHelper module to accomplish this.
Instance Method Summary collapse
-
#parse(filearray) ⇒ Object
Takes an array of lines (filearray) - presumably from an EDF file - and parses them, dynamically creating a data structure by defining the connections between Inst objects as they are created.
Instance Method Details
#parse(filearray) ⇒ Object
Takes an array of lines (filearray) - presumably from an EDF file - and parses them, dynamically creating a data structure by defining the connections between Inst objects as they are created.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/Parser.rb', line 5 def parse(filearray) # read through our array to find and store the start and end points filearray.each_with_index do |line,index| line.strip! # store linecounts as indexes into the array (zero based) @startline = index if line =~ /interface/ if line =~ /design root/ @endline = index - 2 break end end # chop invalid parts off of array filearray = filearray.slice(@startline..@endline) arrplace = 0 arrlength = filearray.length - 1 valid_edf = [] tmpstr = "" @insts = {} while arrplace <= arrlength # see if we have a keyword on the current line if filearray[arrplace] =~ /\A\(port\s+|\A\(instance|\A\(net/ # we do, see if its parens are matched if ParseHelper.parens_check(filearray[arrplace]) # they are, so put the string into the array valid_edf << filearray[arrplace] else # they are not, so write the array location to a temp string tmpstr << filearray[arrplace] # see if we are at the end of the array break if arrplace + 1 >= arrlength # if not keep trying to match parens arrplace += 1 tmpstr << filearray[arrplace] # replace this with paren check while !ParseHelper.parens_check(tmpstr) break if arrplace + 1 >= arrlength arrplace += 1 tmpstr << filearray[arrplace] end valid_edf << tmpstr tmpstr = "" end # look at next place arrplace += 1 else arrplace += 1 end end valid_edf.each do |l| # for the first keyword port if l =~ /\A\(port\s+/ # if there are multiple members if l =~ /(\w+)(\s+)(\d+)(\(direction)(\s)(input|output)/ instnum = $3.to_i insttype = $6.capitalize instname = $1.downcase # generate names for each member inames = ParseHelper.member_inst_names(instnum,instname) # puts "Creating #{instnum} Insts of type #{insttype} named #{inames.join(", ")}" # create the inst objects of the proper type and store in insts hash inames.each do |i| @insts[i] = Object.const_get(insttype).new(i) end # if there are no members elsif l =~ /(\w+)(\s)(\(direction)(\s)(input|output)/ insttype = $5.capitalize instname = $1.downcase # puts "Creating an Inst of type #{insttype} named #{instname}" # create the inst objects of the proper type and store in insts hash @insts["#{instname}"] = Object.const_get(insttype).new(instname) else throw "Error Parsing Ports" end # for the second keyword, "instance" elsif l =~ /(\A\(instance\s+)(\w+)(\(viewRef)(\s)(viewnamedefault\(cellRef)(\s)(\w+)/ insttype = $7.capitalize instname = $2.downcase # create the inst objects of the proper type and store them in the hash # puts "Creating an Inst of type #{insttype} named #{instname}" @insts["#{instname}"] = Object.const_get(insttype).new(instname) elsif l =~ /(\A\(net\sNet\d+\(joined)(.*)/ # get the names for the joined ports in individual arrays # make this get_port_names method modify names for bufz ports on the fly ports = ParseHelper.get_port_names($2,@insts) # look for output ports to find the master # if inst type is bufz then automatically set it as a masterport # I have the inst name and the port name availible to me separately outputports = [] inputports = [] unless ports.length <= 1 ports.each do |p| # split portnames into inst name and port name splitport = ParseHelper.portname_split(p) # if the portname is out we have a bufz output port if splitport[1] == "out" # we know this is an output so add it to output outputports << p # otherwise check to see if this might be a output port of another type elsif @insts[splitport[0]].get_port(splitport[1]).type == "out" # we know this is an output so add it to output outputports << p else # otherwise it is an input inputports << p end end # this assumes there is only one input port # since bufz is treated as a unit this should be true # if it is not there will be errors - but they will be the fault # of the circuit designer op = ParseHelper.portname_split(outputports.first) inputports.each do |p| # puts "Cross-Connecting #{op} to #{p}" # convert port names to separate inst names and port names ip = ParseHelper.portname_split(p) # cross connect ports # puts "connecting #{ip[0]} on #{ip[1]} to #{op[0]} on #{op[1]}" @insts[ip[0]].get_port(ip[1]).add_connection(@insts[op[0]].get_port(op[1])) # puts "connecting #{op[0]} on #{op[1]} to #{ip[0]} on #{ip[1]}" @insts[op[0]].get_port(op[1]).add_connection(@insts[ip[0]].get_port(ip[1])) end end else throw "Error Parsing Nets/Instances" end end @insts end |