我在制作一个将给定中缀表达式转换为后缀的程序时遇到了一些问题。我首先用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)"))))
到目前为止,在中缀到后缀函数中,我已经到达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
目前没有回答
相关问题 更多 >
编程相关推荐