Added translation actions for Arithmetic expressions

This commit is contained in:
Mariano Uvalle 2019-04-05 03:09:08 +00:00
parent 5dfc8d2483
commit 81a2de075c
6 changed files with 689 additions and 396 deletions

View file

@ -1,15 +1,39 @@
import ply.lex as lex
import ply.yacc as yacc
import sys
from stack import Stack
resultQuadruplets = []
quadrupletIndex = 1
# Auxiliary stacks.
operandsStack = []
operatorsStack = []
jumpsStack = []
auxStack = []
avail = []
for i in range(50):
avail.append('T' + str(i))
# Operations related to the table of symbols
symbolsNames = []
symbolsTypes = []
symbols = {}
def addSymbol(name, symbolType):
symbolsNames.append(name)
symbolsTypes.append(symbolType)
# # Implementation using lists.
# def addSymbol(name, symbolType):
# symbolsNames.append(name)
# symbolsTypes.append(symbolType)
# Implementation using a dictionary
def addSymbol(name, symbolsTypes):
initialValue = 0 if symbolsTypes == 'integer' else 0.0
symbols[name] = [name, initialValue]
def peek(list):
if (len(list) == 0):
return None
return list[len(list) - 1]
tokens = [
'doubleColon',
@ -189,10 +213,13 @@ def p_S(p):
| exit
'''
# Adjust the action to support matrices
def p_Dimensional(p):
'''
Dimensional : id DimensionsOrEmpty
'''
p[0] = p[1]
def p_DimensionsOrEmpty(p):
'''
@ -245,19 +272,21 @@ def p_IntOrEmpty(p):
def p_EA(p):
'''
EA : MultDiv
| EA SumOrSub MultDiv
| EA SumOrSub action_3 MultDiv action_4
'''
def p_SumOrSub(p):
'''
SumOrSub : plus
| minus
'''
p[0] = p[1]
def p_MultDiv(p):
'''
MultDiv : EAParens
| MultDiv MDSymbols EAParens
| MultDiv MDSymbols action_5 EAParens action_6
'''
def p_MDSymbols(p):
@ -265,6 +294,7 @@ def p_MDSymbols(p):
MDSymbols : mul
| div
'''
p[0] = p[1]
def p_EAParens(p):
'''
@ -293,9 +323,9 @@ def p_Equality(p):
def p_EItem(p):
'''
EItem : Dimensional
| int
| rea
EItem : Dimensional action_1
| int action_2
| rea action_2
'''
def p_EQSymbols(p):
@ -308,6 +338,51 @@ def p_EQSymbols(p):
| moreEquals
'''
def p_action_1(p):
"action_1 :"
operandsStack.append(p[-1])
def p_action_2(p):
"action_2 :"
operandsStack.append(p[-1])
def p_action_3(p):
"action_3 :"
operatorsStack.append(p[-1])
def p_action_4(p):
"action_4 :"
if (peek(operatorsStack) == '+' or peek(operatorsStack) == '-'):
global quadrupletIndex
operator = operatorsStack.pop()
operand2 = operandsStack.pop()
operand1 = operandsStack.pop()
temp = avail.pop(0)
operandsStack.append(temp)
resultQuadruplets.append(str(operator) + ' ' + str(operand1) + ' ' + str(operand2) + ' ' + str(temp) + '\n')
quadrupletIndex += 1
def p_action_5(p):
"action_5 :"
operatorsStack.append(p[-1])
def p_action_6(p):
"action_6 :"
if (peek(operatorsStack) == '*' or peek(operatorsStack) == '/'):
global quadrupletIndex
operator = operatorsStack.pop()
operand2 = operandsStack.pop()
operand1 = operandsStack.pop()
temp = avail.pop(0)
operandsStack.append(temp)
resultQuadruplets.append(str(operator) + ' ' + str(operand1) + ' ' + str(operand2) + ' ' + str(temp) + '\n')
quadrupletIndex += 1
def p_error(p):
print('XXX Invalid program')
print(p)
@ -317,11 +392,18 @@ parser = yacc.yacc()
if (len(sys.argv) > 1):
programName = sys.argv[1]
programFile = open(programName, "r")
resultFile = open(programName + '.out', "w+")
# This is neccessary because the read method parses literal ends
# of lines as \\n instead of \n.
program = programFile.read().replace('\\n', '\n')
parser.parse(program)
print(resultQuadruplets)
resultFile.writelines(resultQuadruplets)
# Close the files.
programFile.close()
resultFile.close()
else:
raise Exception('''
No file name was provided.