python - 麻烦制作中缀到后缀转换器臂组件
问题描述
我在制作将给定中缀表达式转换为后缀的程序时遇到了一些麻烦。我首先用 python 编写了程序,它工作得很好,现在我正试图将它翻译成 Arm。这是 Python 代码:
OPERATORS = ['+', '-', '*', '/', '(', ')', '^'] # set of operators
PRIORITY = {'+':1, '-':1, '*':2, '/':2, '^':3} # dictionary having priorities
operation = "+-*/^"
def infix_to_postfix(expression):
stack = [] # initially stack empty
output = '' # initially output empty
for ch in expression:
if ch not in OPERATORS: # if an operand then put it directly in postfix expression
output+= ch
elif ch=='(': # else operators should be put in stack
stack.append('(')
elif ch==')':
while stack and stack[-1]!= '(':
output+=stack.pop()
stack.pop()
else:
# lesser priority can't be on top on higher or equal priority
# so pop and put in output
while stack and stack[-1]!='(' and PRIORITY[ch]<=PRIORITY[stack[-1]]:
output+=stack.pop()
stack.append(ch)
while stack:
output+=stack.pop()
result = ""
for i in range(len(output)):
if output[i] in OPERATORS and output[i-1] != " ":
result += " "
result += output[i]
elif output[i] in OPERATORS:
result += output[i]
result += " "
else:
result += output[i]
return result
def evaluate(prefexp):
arg = prefexp.split(" ")
stack = []
for token in arg:
if token not in OPERATORS:
stack.append(token)
else:
o1 = stack.pop()
o2 = stack.pop()
if token == "+":
w = float(o2) + float(o1)
if token == "-":
w = float(o2) - float(o1)
if token == "*":
w = float(o2) * float(o1)
if token == "/":
w = float(o2) / float(o1)
if token == "^":
w = float(o2) ** float(o1)
stack.append(w)
return stack.pop()
def addSpaces(infexpr):
output = ""
for i in infexpr:
if i in operation:
output += " "
output += i
return output
print(infix_to_postfix("3*(5+3)"))
#print(evaluate(infix_to_postfix(addSpaces("38^2+5*(6+4)"))))
到目前为止,在 infix_to_postfix 函数中,我已经了解了 for 循环中的最后一个 else。在那之前,我对它进行了测试,我很确定它可以按预期工作。当我尝试在 for 循环中实现最后的 else 时,就会出现问题。
如果该函数中 for 循环之后的所有内容都被注释掉并且它在表达式 3*(5+3) 上运行,它会给出 353+。但是当我在我的手臂上运行它时,我得到 35(*3+.
这是我的手臂翻译:
//Converts Infix expression given from command line
//into postfix
.data
.balign 4
operators: .asciz "+-o*/o()o^"
.balign 4
//builds the prefix string
prefix: .space 100
.balign 4
return: .word 0
.global main
.global printf
//PERMANENT REGISTERS
//r0 contains address of infix expression
//r1 contains length of stack
//r2 contains address of prefix
//r3 contains current character in infix expression
//r4 contains address of operators
//r5 contains precedence of infix in operators
//r7 contains bottom element of stack
//TEMPORARY REGISTERS: r6, r8, r9
main:
ldr r0, [r1, #4] //load infix expression from command line
ldr r1, =return //save link register
str lr, [r1]
mov r1, #0 //length of stack
ldr r2, =prefix //load address of prefix onto r2
InfixParse:
ldrb r3, [r0] //contains current character in infix expression
cmp r3, #0 //if current character is null, end of infix expression reached
beq end //go to end
ldr r4, =operators //load address of operators string onto r4
mov r5, #0 //initialize precedence of infix
//checks if current character is an operator
//also determines precedence #
InOperator:
ldrb r6, [r4] //load current character in operator string to r6
cmp r6, #0 //check if end of operators string
beq NotInOperator //if end of string reached, character not an operator
cmp r6, r3 //compare character in operator to that of infix
beq IsOperator //if equal branch to isoperator
add r4, r4, #1 //increment address of operator string
add r5, r5, #1 //increment precedence # of infix character
b InOperator //loop back to inoperator branch
//if not an operator store operand in prefix
NotInOperator:
strb r3, [r2] //store character into current address of prefix string
add r2, r2, #1 //increment address of prefix string
add r0, r0, #1 //increment address of infix string
b InfixParse //start next iteration of InfixParse
//if is operator check if operator is (, ), or
//something else
IsOperator:
cmp r3, #40 //check if operator is (
beq IsLeftParen
cmp r3, #41 //check if operator is )
beq IsRightParen
b OtherOperator //if something else branch to otheroperator
//if infix character is left parentheses
//push '(' onto stack
IsLeftParen:
push {r3} //push onto stack
add r1, r1, #1 //increment length of stack
cmp r1, #1 //if stack was empty
moveq r7, r3 //store bottom element of stack in r7
add r0, r0, #1 //increment address of infix string
b InfixParse //loop back to InfixParse
//if infix character is right parentheses
//pop from the stack and add it to the prefix string
//until either the stack is empty or bottom of stack is
//left parentheses
IsRightParen:
sub r6, r7, #40 //store diff ascii of ( and ascii of r7, the last element in stack
mul r8, r6, r1 //if r8 is 0, either r7 is ( or r1 is 0 => stack is empty
cmp r8, #0 //if r8 is 0
beq EndOfParen //branch out of loop
ldrb r8, [sp], #4 //pop from stack, store it in r8
strb r8, [r2] //store r8 into prefix
add r2, r2, #1 //increment address of prefix
sub r1, r1, #1 //decrement length of stack
b IsRightParen //loop back to IsRightParen
//when exited out of above loop
//pop from the stack
EndOfParen:
pop {r6} //pop
sub r1, r1, #1 //decrement length
add r0, r0, #1 //increment address of infix
b InfixParse //loop back to InfixParse
//if some other operator
//pop from stack until either
//stack is empty
//bottom of stack is (
//or the operator on the bottom of the stack has a lower
//precedence than the current operator is found
OtherOperator:
sub r6, r7, #40 //store diff ascii of ( and ascii of r7, the last element in stack
mul r8, r6, r1 //if r8 is 0, either r7 is ( or r1 is 0 => stack is empty
mov r9, r8 //save this value in r9
mov r6, #0 //stores precedence of operator on bottom of stack
ldr r4, =operators //load address of operator string onto r4
PrecedenceCheck:
ldrb r8, [r4] //load current operator character onto r8
cmp r8, #0 //if null character end of string reached
beq Popping //exit loop
cmp r8, r7 //compare operator character to character of bottom of stack
beq Popping //exit loop
add r6, r6, #1 //increment precedence counter
add r4, r4, #1 //increment address of operator string
b PrecedenceCheck //loop back to PrecedenceCheck
Popping:
cmp r6, #9 //since (, ), aren't real operators
moveq r6, #6 //^ is pushed before them
sub r6, r5, r6 //subtract precedence of infix char and of bottom of stack
cmp r6, #1 //if difference greater than one, precedence of infix char
bgt Pushing //is greater than of bottom of stack, exit loop
cmp r9, #0 //if stack is empty or bottom of stack is (
beq Pushing //also exit loop
ldrb r6, [sp], #4 //pop off stack
strb r6, [r2] //store it in prefix string
add r2, r2, #1 //increment address of prefix string
sub r1, r1, #1 //decrement length of stack
b OtherOperator //loop back to OtherOperator
//once out of loop, push infix char onto stack
Pushing:
push {r3} //pushes infix char on stack
add r1, r1, #1 //increment size of stack
cmp r1, #1 //if stack was empty
moveq r7, r3 //store bottom of stack onto r7
add r0, r0, #1 //increment address of infix string
b InfixParse //loop back to InfixParse
end:
ldr r0, =prefix //print out prefix string
bl printf
ldr lr, =return //restore link register
ldr lr, [lr]
bx lr //exit
解决方案
推荐阅读
- c# - 为什么克隆后精灵不可见?
- python - 在 Python 中连接列表中的 2 个项目
- javascript - 如何正确遍历渲染中的对象?
- python - 我的 Tkinter 按钮命令只运行一次循环
- python - Pyqt5 QTreeWidget CurrentItemChanged 信号发送整数作为前一项
- arrays - MongoDB中的计数查询
- python - 如何在python中引发多个异常
- android - 如何在 Android Things 中关闭 Raspberry Pi 屏幕
- c# - 如何正确处理 C# Cmdlet helpmessage 本地化的资源
- python - 如何基于平台动态改变 Kivy 窗口尺寸