中缀到后缀转换器臂组件故障

2024-04-29 00:32:13 发布

您现在位置: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)"))))
        

到目前为止,在中缀到后缀函数中,我已经到达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 

Tags: oftoinoutputstringifisstack