def LRParse(TokenList: List[Token]) -> SyntaxTree: """ 对Token序列进行LR(1)分析, 生成对应的语法树 :param TokenList: :return: """ StateStack = stack() # 状态栈 CharacterStack = stack() # 符号栈 StateStack.push(0) # 初始状态 pos = 0 while pos < len(TokenList): # 遍历每个Token token = TokenList[pos] flag = False # 判断这个Actionkey在不在Action表,不在就报错 NowActionKey = ActionKey(StateStack.top(), token.type) if NowActionKey in ActionTable: NowActionVal = ActionTable[NowActionKey] flag = True elif ActionKey(StateStack.top(), TokenType.OTHERS) in ActionTable: NowActionVal = ActionTable[ActionKey(StateStack.top(), TokenType.OTHERS)] flag = True else: raise LRParsingErr(pos, NowActionKey, "unexpected token") if flag: action, ID = NowActionVal.operation, NowActionVal.num # print(action, ID) # 移进 if action == Operation.SHIFT: # 此时ID代表将要移进的状态 StateStack.push(ID) CharacterStack.push(TreeNode(token)) pos += 1 # 规约 elif action == Operation.REDUCE: # 此时ID代表将要规约的产生式 ReduceExp = ExpressionTable[ID] # 当前产生式 ReduceExpLen = len(ReduceExp.expression) # 产生式后面部分的长度 NonTerminalTreeNode = TreeNode(ReduceExp.symbol) # 产生一个节点,代表当前终结符/非终结符 for i in range(ReduceExpLen): StateStack.pop() NonTerminalTreeNode.children.append(CharacterStack.top()) # 从符号栈和状态中的内容取出len个,记录符号栈取出的内容 CharacterStack.pop() NowGotoKey = GotoKey(StateStack.top(), ReduceExp.symbol) NonTerminalTreeNode.children.reverse() # 出栈顺序是逆序,需要反转 if NowGotoKey in GotoTable: StateStack.push(GotoTable[NowGotoKey]) # 查找goto表是否有符合要求的Key CharacterStack.push(NonTerminalTreeNode) else: raise LRParsingErr(pos, NowGotoKey, "unknown goto key") # 接受 else: return SyntaxTree(CharacterStack.top()) return SyntaxTree()
def DFS(self, start_vertex): start_vertex = self.get_vertex(start_vertex) if start_vertex is None: raise Exception("The vertex is not present in the graph.") visited = [False] * len(self._vertices) traversed = [] s = stack() s.push(start_vertex) while not s.isEmpty(): #this loop goes on until every node is traversed v = s.pop() key = v.get_key() if not visited[key]: visited[key] = True traversed.append(key) for neighbor in v.get_connections(): if not visited[neighbor[0].get_key()]: s.push(neighbor[0]) return traversed
def Get_DepthOrder(self): accum = [] x = stack() x.push(self) while (1): r = x.pop() if r == False: break accum += [r.GetVal()] for i in r.GetSuccessors(): x.push(i) return accum
def makeRunway(inFile): runway = stack() # Open file to read runwayFile = open(inFile, "r") for line in runwayFile: # Make a plane of each line thisPlane = makePlane(line) # Place plane in stack push(runway, thisPlane) runwayFile.close() return runway
def quickSort(S): ''' len() method: O(1) ''' n = len(S) # Store the number of elements in the list if n < 2: # If the number of elements is less than 2 return S ''' For n elements, push operation: O(1) ''' x = stack([(0, n - 1)]) # Push the list into the stack ''' Iteration while condition holds: O(nlogn), dependent on the iteration times ''' while x: # While the list is in the stack ''' Pop operation: O(1) ''' e, p = low, high = x.pop( ) # Set e and p equal to low, set high equal to the last element pushed into the stack elem = S[ e] # Set elem equal to the value of the element in the list stored in index e pivot = S[ p] # Set pivot equal to the value of the element in the list stored in index p ''' Iteration while condition holds: O(nlogn) ''' while p > e: # Iterate while the value of p is greater than the value of e if elem > pivot: # If the value of elem is greater than the pivot S[p] = elem # Store elem in the element of the list at index p p -= 1 # Change the boundary p of the list: move leftward S[e] = elem = S[ p] # Set S[e] and the value of elem equal to S[p] else: # If the value of elem is less than the pivot e += 1 # Change the boundary e of the list: move rightward elem = S[ e] # Set the value of elem equal to the value of the element in the list at index e S[p] = pivot # Set the value of the element in the list at index p equal to pivot lsize = p - low # Change the range length of low hsize = high - p # Change the range length of high if lsize <= hsize: # If the range length of low is less than or equal to the range length of high if 1 < lsize: ''' Push operations: O(1) ''' x.push( (p + 1, high)) # Push the list in the given range into the stack x.push( (low, p - 1)) # Push the list in the given range into the stack else: # If the range length of low is greater than the range length of high ''' Push operation: O(1) ''' x.push((low, p - 1)) # Push the list in the given range into the stack if 1 < hsize: ''' Push operation: O(1) ''' x.push((p + 1, high)) # Push the list in the given range into the stack return S # Return the sorted list
def level_reverse_order(root): if root is None: q = queue() s = stack() q.en_queue(root) node = None while not q.is_empty: node = q.de_queue if node.left is not None: q.en_queue(node.left) if node.right is not None: q.en_queue(node.right) s.push(node) while not s.is_empty: print(s.pop().get_data)
def base_conversion(number, base): digits = '0123456789ABCDEF' st = stack() while number > 0: remainder = number % base st.push(remainder) number = number // base converted_num = "" while not st.isEmpty(): converted_num = converted_num + str(digits[st.pop]) return converted_num
def dijkstra(self, source, destination): # initialize the distance of all nodes to infinity distance = [(sys.maxint, -1)] * len(self._vertices) #distance of source from source is 0 distance[source] = (0, 0) # initially none of the nodes is visited visited = [False] * len(self._vertices) fringe = [source] #yet to be visited nodes in the same level # while there are still entries in the fringe while fringe: # find node with min distance in fringe as current vertex current_vertex_key = self._min_distance(distance, fringe) fringe.remove(current_vertex_key) visited[current_vertex_key] = True current_vertex = self.get_vertex(current_vertex_key) for neighbor in current_vertex.get_connections(): neighbor_vertex = neighbor[0].get_key() neighbor_weight = neighbor[1] if neighbor_vertex not in fringe and visited[neighbor_vertex]: fringe.append(neighbor_vertex) if distance[neighbor_vertex][0] > distance[current_vertex_key][0] + neighbor_weight: distance[neighbor_vertex][0] = (distance[current_vertex_key][0] + neighbor_weight, current_vertex_key[0]) s = stack() x = destination while x!= source: s.push(x) x = distance[x][1] s.push(x) shortest_path = [] while not s.isEmpty(): shortest_path.append(s.pop()) return (distance)
def is_expresion_balanced(expresion): s = stack() is_balanced = True index = 0 while index < len(expresion) and is_balanced: exp = expresion[index] if exp in "({[": s.push(exp) else: if s.isEmpty(): is_balanced = False else: top = s.pop() if not is_match(top, exp): return False index += 1 if s.isEmpty() and is_balanced: return True else: return False
#Sort a stack using recursion #Allowed methods : peek, push , pop, isEmpty import stack s = stack() stack.push(5) stack.push(8) stack.push(1) stack.push(3) stack.push(6) stack.push(2) s2 = stack() def sort_stack(stack_list1, stack_list2): if len(stack_list1) == 1: stack_list2.append(stack_list1.pop()) return stack_list2 if stack_list1[0] > stack_list2[0]: stack_list1.append(stack_list2.pop()) else: sort_stack(stack_list2.pop(), stack_obj2.pop())
def __init__(self): self._stack_data = stack() self._stack_min = stack()
def key_return(self, key): """ Auto indentation when the return button is pressed """ cline = int(self.index(INSERT).split('.')[0]) lastcol = 0 char = self.get('%s.%d' % (cline, lastcol)) while char != '\n': lastcol += 1 char = self.get('%s.%d' % (cline, lastcol)) text = self.get('%s.%d' % (cline, 0), self.index(INSERT)) line = cline + 1 if len(text) > 1: #CASE OF ":" if text[-1] == ":" and text[-2] != ":" and\ text[-2] != ")" and text[-2] != "]" and text[-2] != "}": self.insert(INSERT, "\n") indent = re.search(r"^(?P<indent>[ ]*)", text).group("indent") self.insert('%s.%d' % (line, 0), indent + " ") return "break" #CASE OF ): or ]: or }: if text[-1] == ":" and (text[-2] == ")" or\ text[-2] == "]" or text[-2] == "}"): curr_index = self.index(INSERT) self.insert(INSERT, "\n") indent = 0 start = "1.0" open_stack = stack() close_stack = stack() while start != curr_index: if self.get(start) == "(" or\ self.get(start) == "[" or\ self.get(start) == "{": open_stack.push(start) elif self.get(start) == ")" or\ self.get(start) == "]" or\ self.get(start) == "}": close_stack.push(start) start = self.index(start + "+1c") if not open_stack.empty(): paren_line = int(open_stack.top().split('.')[0]) indent_col = 0 c = self.get('%s.%d' % (paren_line, indent_col)) while c == " ": indent += 1 indent_col += 1 c = self.get('%s.%d' % (paren_line, indent_col)) if self.get(self.index(INSERT)) == " ": indent -= 1 self.insert('%s.%d' % (line, 0), indent * " " + " ") return "break" # CASE OF "," INSIDE SINGLE/MULTIPLE PAREN/BRACKETS/BRACES elif text[-1] == "," or text[-2] == ", ": curr_index = self.index(INSERT) self.insert(INSERT, "\n") indent = len( re.search(r"^(?P<indent>[ ]*)", text).group("indent")) start = "1.0" open_stack = stack() close_stack = stack() while start != curr_index: if self.get(start) == "(" or\ self.get(start) == "[" or\ self.get(start) == "{": open_stack.push(start) elif self.get(start) == ")" or\ self.get(start) == "]" or\ self.get(start) == "}": close_stack.push(start) if not open_stack.empty() and not close_stack.empty(): if (self.get(open_stack.top()) == "(" and\ self.get (self.index(close_stack.top())) == ")") or\ (self.get (self.index(open_stack.top())) == "[" and\ self.get (self.index(close_stack.top())) == "]") or\ (self.get (self.index(open_stack.top())) == "{" and\ self.get (self.index(close_stack.top())) == "}"): open_stack.pop() close_stack.pop() start = self.index(start + "+1c") if not open_stack.empty(): indent = int(open_stack.top().split('.')[1]) + 1 if self.get(self.index(INSERT)) == " ": indent -= 1 self.insert('%s.%d' % (line, 0), indent * " ") return "break" #CASE OF ), ], } elif text[-1] == ")" or text[-1] == "]" or text[-1] == "}": curr_index = self.index(INSERT) self.insert(INSERT, "\n") indent = 0 start = "1.0" open_stack = stack() close_stack = stack() while start != curr_index: if self.get(start) == "(" or\ self.get(start) == "[" or\ self.get(start) == "{": open_stack.push(start) elif self.get(start) == ")" or\ self.get(start) == "]" or\ self.get(start) == "}": close_stack.push(start) start = self.index(start + "+1c") if not open_stack.empty(): paren_line = int(open_stack.top().split('.')[0]) indent_col = 0 c = self.get('%s.%d' % (paren_line, indent_col)) while c == " ": indent += 1 indent_col += 1 c = self.get('%s.%d' % (paren_line, indent_col)) if self.get(self.index(INSERT)) == "": indent -= 1 self.insert('%s.%d' % (line, 0), indent * " ") return "break" #CASE OF RETURN/YIELD/RAISE start = '%s.%d' % (cline, 0) end = self.index(INSERT) return_index = self.search("return", start, stopindex=end) yield_index = self.search("yield", start, stopindex=end) raise_index = self.search("raise", start, stopindex=end) if return_index or yield_index or raise_index: if return_index: indent = int(return_index.split('.')[1]) elif yield_index: indent = int(yield_index.split('.')[1]) else: indent = int(raise_index.split('.')[1]) if indent > 0: indent -= 4 self.insert(INSERT, "\n") self.insert('%s.%d' % (line, 0), indent * " ") return "break" #OTHER else: self.insert(INSERT, "\n") indent = re.search(r"^(?P<indent>[ ]*)", text).group("indent") if indent: if self.get(self.index(INSERT)) == "": indent = indent[:-1] self.insert('%s.%d' % (line, 0), indent) return "break"
def callback(self, result, *args): #Updating the position of the cursor index = self.index("insert") #for all chars that are > 79/line, highlight extra in red cline = self.index(INSERT).split('.')[0] lastcol = 0 char = self.get('%s.%d' % (cline, lastcol)) while char != '\n': lastcol += 1 char = self.get('%s.%d' % (cline, lastcol)) last_char = '%s.%d' % (cline, lastcol) first_char = '%s.%d' % (cline, 79) self.tag_remove("too_long", '%s.%d' % (cline, 0), '%s.%d' % (cline, 0) + " lineend") if lastcol > 79: self.tag_add("too_long", first_char, last_char) #Updating line and column on the status bar self.statusbar.lineCol(*index.split('.')) #Updating line numbers on the left side self.frame.linenumbers.redraw() #----------------------------------------------------------------# # As the cursor moves, this part takes care of highligting # # matching parentheses using a stack. # #----------------------------------------------------------------# self.tag_remove("paren_match", "1.0", END) ccline = int(self.index("insert").split('.')[0]) ccol = int(self.index("insert").split('.')[1]) - 1 char = self.get('%s.%d' % (ccline, ccol)) # If the cursor in right after an opening paren if (char == "(" or char == "[" or char == "{"): stack_index = stack() stack_char = stack() start = self.index("insert") while self.index(start) != self.index(END): line = int(self.index(start).split('.')[0]) col = int(self.index(start).split('.')[1]) - 1 if (self.get('%s.%d' % (line, col)) == "(" or self.get('%s.%d' % (line, col)) == "[" or self.get('%s.%d' % (line, col)) == "{"): stack_index.push(start + "-1c") stack_char.push(self.get('%s.%d' % (line, col))) elif (self.get('%s.%d' % (line, col)) == ")" and stack_char.empty() is False): if stack_char.size == 1 and stack_char.top() == "(": self.tag_add('paren_match', stack_index.top(), stack_index.top() + "+1c") self.tag_add('paren_match', start + "-1c", start) start = END elif stack_char.top() == "(": stack_index.pop() stack_char.pop() elif (self.get('%s.%d' % (line, col)) == "}" and stack_char.empty() is False): if stack_char.size == 1 and stack_char.top() == "{": self.tag_add('paren_match', stack_index.top(), stack_index.top() + "+1c") self.tag_add('paren_match', start + "-1c", start) start = END elif stack_char.top() == "{": stack_index.pop() stack_char.pop() elif (self.get('%s.%d' % (line, col)) == "]" and stack_char.empty() is False): if stack_char.size == 1 and stack_char.top() == "[": self.tag_add('paren_match', stack_index.top(), stack_index.top() + "+1c") self.tag_add('paren_match', start + "-1c", start) start = END elif stack_char.top() == "[": stack_index.pop() stack_char.pop() #CASE OF PAREN INSIDE STRING exp: print("hi(") elif (self.get('%s.%d' % (line, col)) == '"' or self.get('%s.%d' % (line, col)) == "'"): if self.get('%s.%d' % (line, col)) == '"': pos = self.search('"', start, stopindex=END) else: pos = self.search("'", start, stopindex=END) if not pos: break start = str(pos) + "+1c" start = start + "+1c" # If the cursor is on a closing paren if (char == ")" or char == "]" or char == "}"): stack_index = stack() #Stack for the indexes of parens stack_char = stack() #Stack for for parens start = self.index("insert") while self.index(start) != self.index("1.0"): line = int(self.index(start).split('.')[0]) col = int(self.index(start).split('.')[1]) - 1 if (self.get('%s.%d' % (line, col)) == ")" or self.get('%s.%d' % (line, col)) == "]" or self.get('%s.%d' % (line, col)) == "}"): stack_index.push(start + "-1c") stack_char.push(self.get('%s.%d' % (line, col))) elif (self.get('%s.%d' % (line, col)) == "(" and stack_char.empty() is False): if stack_char.size == 1 and stack_char.top() == ")": self.tag_add('paren_match', stack_index.top(), stack_index.top() + "+1c") self.tag_add('paren_match', start + "-1c", start) start = "1.0" elif stack_char.top() == ")": stack_index.pop() stack_char.pop() elif (self.get('%s.%d' % (line, col)) == "{" and stack_char.empty() is False): if stack_char.size == 1 and stack_char.top() == "}": self.tag_add('paren_match', stack_index.top(), stack_index.top() + "+1c") self.tag_add('paren_match', start + "-1c", start) start = "1.0" elif stack_char.top() == "}": stack_index.pop() stack_char.pop() elif (self.get('%s.%d' % (line, col)) == "[" and stack_char.empty() is False): if stack_char.size == 1 and stack_char.top() == "]": self.tag_add('paren_match', stack_index.top(), stack_index.top() + "+1c") self.tag_add('paren_match', start + "-1c", start) start = "1.0" elif stack_char.top() == "]": stack_index.pop() stack_char.pop() #CASE OF PAREN INSIDE STRING exp: print("hi(") elif (self.get('%s.%d' % (line, col)) == '"' or self.get('%s.%d' % (line, col)) == "'"): if self.get('%s.%d' % (line, col)) == '"': start = start + "-1c" line = int(self.index(start).split('.')[0]) col = int(self.index(start).split('.')[1]) - 1 while (self.get('%s.%d' % (line, col)) != '"' and self.index(start) != self.index("1.0")): start = start + "-1c" line = int(self.index(start).split('.')[0]) col = int(self.index(start).split('.')[1]) - 1 else: start = start + "-1c" line = int(self.index(start).split('.')[0]) col = int(self.index(start).split('.')[1]) - 1 while (self.get('%s.%d' % (line, col)) != "'" and self.index(start) != self.index("1.0")): start = start + "-1c" line = int(self.index(start).split('.')[0]) col = int(self.index(start).split('.')[1]) - 1 start = start + "-1c"
def __init__(self, *instructions): self.instructions = instructions def __repr__(self): return ', '.join([repr(x) for x in self.instructions]) def eval(self, stack): for x in self.instructions: out = x.eval(stack) return output(True, out.stack) class Line(Equality): def __init__(self, cond, instructions): self.cond = cond self.instructions = instructions def __repr__(self): return 'Line( '+repr(self.cond)+', '+repr(self.instructions)+' )' def eval(self, stack): if self.cond.eval(stack): out = self.instructions.eval(stack) stack = out.stack return output(True, stack) if __name__ == '__main__': stack = stack([x for x in range(100, 110)]) print(Line(Condition('*', Num('42')), Instructions(Procedure('DUP')))) print(Line(Condition('*', Num('42')), Instructions(Procedure('DUP'))).eval(stack).stack.__repr__())
from stack import * s = stack() a = list(input().split()) def isOperand(self, ch): return ch.isalpha() def notGreater(self, op): precedence = {'+': 1, '-': 1, '*': 2, '/': 2, '^': 3} a = precedence[op] b = s.peek() return True if a >= b else False for i in a: if self.isOperand(i): print(i, end='') elif i == '(': s.push(i) elif i == ')': while (not s.isEmpty() and s.peek != '('): print(s.pop(), end='') if (s.isEmpty()): print('Braces unmatched') else: s.pop()
__author__ = 'newScanTron' from BaseBall import * from stack import * ballCount = 0 ball_stack = stack() user_input = input("how many pitches would you lik to throw?") while ball_stack.size() < int(user_input): pitch = BaseBall() ball_stack.push(pitch) while not ball_stack.isEmpty(): print(ball_stack.pop())
def test_case_push_pop(self): """Pushes seguidos de pops 1000 vezes""" def test(clk, reset, enable, push_pop, input_1, output_1, output_2): def push_pop_method(val=0, pp=True, push_pop=push_pop, enable=enable, input_1=input_1): enable.next = 1 input_1.next = val push_pop.next = pp def clean_flags_method(reset=reset, enable=enable, input_1=input_1, push_pop=push_pop): reset.next = 0 enable.next = 0 push_pop.next = 0 input_1.next = 0 def print_status(flag=VIEW_STATUS, output_1=output_1, output_2=output_2): if flag: print output_1 print output_2 ####################### ## INICIO DOS TESTES ## ####################### for test in range(1000): fake_stack = [] for i in range(STACK_LEN): # Randomic generation numbers randomic_number = randrange(200) previous_randomic_number = 0 if fake_stack: # != [] previous_randomic_number = fake_stack[-1] # Push fake stack fake_stack.append(randomic_number) # Push in the actual stack push_pop_method(randomic_number, 0) yield clk.posedge yield clk.negedge clean_flags_method() print_status() # Verify the transaction self.assertEqual(output_1, randomic_number) self.assertEqual(output_2, previous_randomic_number) for i in range(STACK_LEN): # Pop stack fake_stack.pop() current_stack_top = 0 next_stack_top = 0 if fake_stack: current_stack_top = fake_stack[-1] if len(fake_stack) > 1: next_stack_top = fake_stack[-2] # Pop actual stack push_pop_method(10, True) yield clk.posedge yield clk.negedge clean_flags_method() print_status() # Verify the transaction self.assertEqual(output_1, current_stack_top) self.assertEqual(output_2, next_stack_top) raise StopSimulation clk_s = Signal(bool(1)) reset_s, enable_s = [Signal(bool(0)) for i in range(2)] push_pop_s = Signal(1) output_1_s, output_2_s = [Signal(0) for i in range(2)] input_1_s = Signal(intbv(0)[32:]) clkgen = clk_gen(clk_s) check = test(clk_s, reset_s, enable_s, push_pop_s, input_1_s, output_1_s, output_2_s) device = stack(clk_s, reset_s, enable_s, push_pop_s, input_1_s, output_1_s, output_2_s) sim = Simulation(clkgen, device, check) sim.run(quiet=1)
while not s_a.empty(): loop_count += 1 x = s_a.pop() push_stack_by_order(x, s_h, s_a) #stack_order(s_a, s_h) while not s_h.empty(): s_a.push(s_h.pop()) print'loop_count is %d' %(loop_count) if __name__ == '__main__': sys.setrecursionlimit(10240) num = int(sys.argv[1]) s_a = stack() s_h = stack() # for i in xrange(0, num): # x = random.randint(0, 10000) # s_a.push(x) for i in xrange(num, -1, -1): s_a.push(i) t = time.time() s_a.dump() stack_order(s_a, s_h) s_a.dump() usage = time.time() - t print 'usage: %f' %(usage)
if action == 0 and prohibited != M_R and not stack_mid.empty(): if stack_right.empty() or stack_mid.peek() < stack_right.peek(): action = M_R prohibited = R_M if action == 0: action = R_M prohibited = M_R move(action, stack_left, stack_mid, stack_right) if __name__ == '__main__': if len(sys.argv) < 2: print 'Usage: python ./hanoi_stack.py number' sys.exit(0) N = int(sys.argv[1]) stack_left = stack() stack_right = stack() stack_mid = stack() for i in xrange(N, 0, -1): stack_left.push(i) stack_left.dump() hanoi_stack(N, stack_left, stack_mid, stack_right) stack_right.dump()
""" This is a python script to test the Stack class """ import stack from stack import * from string import * s1 = stack() s2 = stack() # filling first stack filename = 'list1.txt' inputFile = open(filename) for line in inputFile: s1.push(line) # filling second stack filename = 'list2.txt' inputFile = open(filename) for line in inputFile: s2.push(line) # printing both the stacks # print stack one print " Stack one has" print s1 # print stack two print " Stack two has" print s2 # concatenating two stacks s3 = s1 + s2 # printing stack three
def main(): # ******************************************** # Check command line argument # ******************************************** if len(sys.argv) > 4: # Save filename FILE = sys.argv[1] DOT_FILE = sys.argv[2] CUR_SIG = sys.argv[3] FSM_SIG = sys.argv[4] else: # Insufficient number of args, exit with error print "Incorrect argument usage!! Aborting..." print "Correct usage :\n ./extractStates.py <vhdFile> <dotFile> <curSig> <fsmSig>" print "Where:" print " <vhdFile> is the name of the VHDL file to parse" print " <dotFile> is the name of the DOT file to export" print " <curSig> is the VHDL signal used to represent current FSM state (current state)" print " <fsmSig> is the VHDL signal used to control FSM transitions (next state)" sys.exit(2) # ************************************************************* # Setup regular expression patterns # ************************************************************* # Used to search for the beginning of an FSM type definition (enumerated type) # Of the form: "type <typeName> is" fsmTypeDefSearch = re.compile('type (.*) is') # Used to search for the end of an FSM type definition # Of the form: ");" endTypeDefSearch = re.compile('\);') # Used to search for each name of an enumerated type # Of the form: " <enum>," fsmTypeSearch = re.compile('\s*(\w*)\,?') # Used to search for a beginning parentheses on a line # Of the form: "(" beginParenSearch = re.compile('\((\s)*') # Used to search for a blank line blankLineSearch = re.compile('(^|\r\n)\s*(\r\n|$)') # Used to search for the beginning of a state (when clause) # Of the form: "when <stateName> => " stateSearch = re.compile('when\s*(\w*)\s*=>') # Used to search for a transition definition # Of the form: "<FSM_SIG> <= <NEXT_STATE>;" transitionSearch = re.compile(FSM_SIG+'\s*<=\s*(\w*);') # Used to search for the beginning of an FSM (case statement) # Of the form: "case (<sig>) is" fsmBeginSearch = re.compile('case\s*\((.*)\)\s*is') # Used to search for the end of an FSM (case statement) # Of the form: "end case;" fsmEndSearch = re.compile('end case;') # *************************************************************** # Open up the VHDL file and read in the lines # *************************************************************** infile = open(FILE,"r") lines = infile.readlines() infile.close() # ******************************************** # Initialize program state # ******************************************** # Flag to signal when the FSM has been found fsmFound = 0 # Counter for the number of states encountered numStates = 0 # Counter for the number of type-definition states found (for an enumeration) num_tdef_states = 0 # Flag to signal when the type-definition has been found tdef_flag = 0 # Counter for the current line number lineCount = 0 # Variable to hold the last state that has been encountered (so any transitions are coming from this state) lastState = -999 # Array to hold states encountered states = [] # Array to hold type-definition states that have been encountered tdef_states = [] # Array to hold the source of all transitions transitions_from = [] # Array to hold the destination of all transitions transitions_to = [] # Array to hold the line number of each transition (line number in the source program) transitions_lineNum = [] # Stack of encountered case statements caseStack = stack() # ******************************************** # Parse VHDL line by line # ******************************************** for line in lines: lineCount = lineCount + 1 # Parse the VHDL file if tdef_flag == 0: # Check pertinent reg-ex's m = stateSearch.search(line) tdef = fsmTypeDefSearch.search(line) trans = transitionSearch.search(line) fsm = fsmBeginSearch.search(line) fsm_end = fsmEndSearch.search(line) # If the beginning of a case statement is found, check if it is the one corresponding to the FSM if fsm > -1: caseStack.push(fsm.group(1)) # If the end of a case statement is found if fsm_end > -1: if (caseStack.num_elements() > 0): el = caseStack.pop() # If a new state is found if m > -1: # Only update last state if the current "case" scope is that of the FSM and not just some conditional logic if (caseStack.num_elements() > 0): if (caseStack.top() == CUR_SIG): if (fsmFound == 0): print "FSM Found, enabling state extraction..." fsmFound = 1 lastState = m.group(1) states.append(m.group(1)) numStates = numStates + 1 # If a transition is found, store it if trans > -1: # Wait until FSM has been found if fsmFound: transitions_from.append(lastState) transitions_to.append(trans.group(1)) transitions_lineNum.append(lineCount) # If an type definition is found, set the flag to capture it if tdef > -1: tdef_flag = 1 else: # Parse the FSM type definition # Do all the reg-ex searches bp = beginParenSearch.search(line) bl = blankLineSearch.search(line) t = fsmTypeSearch.search(line) et = endTypeDefSearch.search(line) # If blank line, ignore if bl > -1: tdef_flag = 1 # If beginning parentheses, ignore elif bp > -1: tdef_flag = 1 # If end of type definition, exit elif et > -1: tdef_flag = 0 # Otherwise, grab the state name else: tdef_states.append(t.group(1)) num_tdef_states = num_tdef_states + 1 tdef_flag = 1 # If while looping the FSM was never found then exit with an error if (not fsmFound): raise "Error", "FSM Not Found!!!" # ******************************************** # Create DOT file # ******************************************** print "Creating DOT file..." # Initialize data structure that will become the DOT file dotArray = [] dotArray.append("digraph G {") # Add all transitions for i in range(len(transitions_from)): newLine = " "+transitions_from[i]+" -> "+transitions_to[i] + " [label =\"Line#"+str(transitions_lineNum[i])+"\"]" dotArray.append(newLine) # Add in the last line of the DOT file dotArray.append("}") # Write output file outFile = open(DOT_FILE, "w") for line in dotArray: outFile.write(line+"\n") outFile.close() print "State extraction complete."