Created
May 20, 2020 17:06
-
-
Save angristan/fa7ba0819fd517d1046cac64c0216c2c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ply.yacc as yacc | |
import ply.lex as lex | |
from genereTreeGraphviz2 import printTreeGraph | |
tokens = ( | |
'NUMBER', 'MINUS', | |
'PLUS', 'TIMES', 'DIVIDE', | |
'LPAREN', 'RPAREN', 'PRINT', | |
'EQUALS', 'NAME', 'IF', 'SEMICOLON', | |
'GTH', 'LTH', 'GTHOREQUAL', 'LTHOREQUAL', 'EQUALEQUAL', 'NOTEQUAL', ) | |
# Tokens | |
t_PLUS = r'\+' | |
t_MINUS = r'-' | |
t_TIMES = r'\*' | |
t_DIVIDE = r'/' | |
t_LPAREN = r'\(' | |
t_RPAREN = r'\)' | |
t_SEMICOLON = r';' | |
t_PRINT = r'print' | |
t_EQUALS = r'=' | |
t_GTH = r'\>' | |
t_LTH = r'\<' | |
t_GTHOREQUAL = r'\>=' | |
t_LTHOREQUAL = r'\<=' | |
t_EQUALEQUAL = r'==' | |
t_NOTEQUAL = r'\!=' | |
def t_NUMBER(t): | |
r'\d+' | |
t.value = int(t.value) | |
return t | |
def t_IF(t): | |
r'if' | |
return t | |
# Ignored characters | |
t_ignore = " \t" | |
\ | |
def t_newline(t): | |
r'\n+' | |
t.lexer.lineno += t.value.count("\n") | |
def t_error(t): | |
print("Illegal character '%s'" % t.value[0]) | |
t.lexer.skip(1) | |
reserved = {'print': 'PRINT'} | |
def t_NAME(t): | |
r'[a-zA-Z_][a-zA-Z0-9_]*' | |
t.type = reserved.get(t.value, 'NAME') | |
return t | |
# Build the lexer | |
lex.lex() | |
precedence = ( | |
('left', 'PLUS', 'MINUS'), | |
('left', 'TIMES', 'DIVIDE'), | |
# ('right', 'SEMICOLON'), | |
) | |
myVars = {} | |
def p_start(p): | |
''' | |
start : block | |
''' | |
p[0] = ('START', p[1]) | |
print('Arbre de dérivation = ', p[0]) | |
printTreeGraph(p[1]) | |
print('result: ', eval(p[1])) | |
def p_expression_binop_plus(p): | |
'expression : expression PLUS expression' | |
p[0] = ('+', p[1], p[3]) | |
def p_expression_binop_minus(p): | |
'expression : expression MINUS expression' | |
p[0] = ('-', p[1], p[3]) | |
def p_expression_binop_times(p): | |
'expression : expression TIMES expression' | |
p[0] = ('*', p[1], p[3]) | |
def p_expression_binop_divide(p): | |
'expression : expression DIVIDE expression' | |
p[0] = ('/', p[1], p[3]) | |
def p_expression_group(p): | |
'expression : LPAREN expression RPAREN' | |
p[0] = p[2] | |
def p_print(p): | |
'statement : PRINT LPAREN expression RPAREN' | |
p[0] = ('print', p[3]) | |
def p_expression_number(p): | |
'expression : NUMBER' | |
p[0] = p[1] | |
# def p_statement_expr(p): | |
# '''statement : expression SEMICOLON ''' | |
# p[0] = p[1] | |
def p_block(p): | |
'''block : statement SEMICOLON block | |
| statement SEMICOLON''' | |
if len(p) == 4: | |
p[0] = ('block', p[1], p[3]) | |
else: | |
p[0] = ('block', p[1]) | |
def p_assignment(p): | |
"statement : NAME EQUALS expression" | |
myVars[p[1]] = p[3] | |
p[0] = ('assign', p[1], p[3]) | |
def p_expression_name(p): | |
"expression : NAME" | |
p[0] = myVars[p[1]] | |
def p_statement_comp_if(p): | |
'''expression : comparison | |
| if_statement''' | |
p[0] = p[1] | |
def p_IF(t): | |
'''if_statement : IF LPAREN comparison RPAREN''' | |
t[0] = t[3] | |
def p_expression_comparison(t): | |
'''comparison : expression GTH expression | |
| expression LTH expression | |
| expression GTHOREQUAL expression | |
| expression LTHOREQUAL expression | |
| expression EQUALEQUAL expression | |
| expression NOTEQUAL expression''' | |
if t[2] == '>': | |
if t[1] > t[3]: | |
t[0] = True | |
else: | |
t[0] = False | |
elif t[2] == '<': | |
if t[1] < t[3]: | |
t[0] = True | |
else: | |
t[0] = False | |
elif t[2] == '>=': | |
if t[1] >= t[3]: | |
t[0] = True | |
else: | |
t[0] = False | |
elif t[2] == '<=': | |
if t[1] <= t[3]: | |
t[0] = True | |
else: | |
t[0] = False | |
elif t[2] == '==': | |
if t[1] == t[3]: | |
t[0] = True | |
else: | |
t[0] = False | |
elif t[2] == '!=': | |
if t[1] != t[3]: | |
t[0] = True | |
else: | |
t[0] = False | |
def p_error(p): | |
print("Syntax error at '%s'" % p.value) | |
yacc.yacc() | |
def eval(t): | |
print('eval de ', t) | |
if type(t) is int or type(t) is bool: | |
return t | |
if type(t) is tuple: | |
if t[0] == '+': | |
return eval(t[1]) + eval(t[2]) | |
if t[0] == '-': | |
return eval(t[1]) - eval(t[2]) | |
if t[0] == '*': | |
return eval(t[1]) * eval(t[2]) | |
if t[0] == '/': | |
return eval(t[1]) / eval(t[2]) | |
if t[0] == 'print': | |
return eval(t[1]) | |
if t[0] == 'block': | |
return eval(t[1]) | |
return 'UNK' | |
# Multiline input | |
# while True: | |
# s = '' | |
# line = input('reap> ') | |
# while line != '': | |
# s += line | |
# line = input() | |
s='print(1+2);x=4;x=x+1;print(x);' | |
yacc.parse(s) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment