Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

I need the necessary corrections made to the Lexer & Parser code so that when running the Lisp program, after inputting (if (> 2 3)

I need the necessary corrections made to the Lexer & Parser code so that when running the Lisp program, after inputting

(if (> 2 3) 40 50) (or (> 2 3) (> 3 2)) (and (> 2 3) (> 3 2))

I get the following output:

LISP: (if (> 2 3) 40 50); 50.0 LISP: (or (> 2 3) (> 3 2)); True LISP: (and (> 2 3) (> 3 2)); False

# Lexer

import ply.lex as lex

t_SC = r';' t_LP = r'\(' t_RP = r'\)'

reserved = {'cdr' : 'CDR', 'car':'CAR', 'cons':'CONS', 'allow':'ALLOW'}

t_P = r'\+' t_M = r'-' t_T = r'\*' t_D = r'/'

tokens = ['NUM', 'ID', 'LP', 'RP', 'P', 'M', 'T', 'D', 'SC'] + list(reserved.values())

def t_NUM(t): r'[-+]?[0-9]+(\.([0-9]+)?)?' t.type = 'NUM' t.value = float(t.value) return t

def t_ID(t): r'[a-zA-Z][_a-zA-Z0-9]*' t_val = t.value.lower() if (t_val in reserved.keys()): t.type = reserved[t_val] else: t.type = 'ID' return t

t_ignore = " \t"

def t_error(t): print(f"Illegal character {t.value[0]}") raise Exception('LEXER ERROR')

lexer = lex.lex()

data = ''' [25/(3*40) + {300-20} -16.5] {(300-250)<(400-500)} 20 & 30 | 50 # This is a comment ''' lexer.input(data)

if __name__ == '__main__':

s = '(+ (car (2 3 4)) (car (cdr (cdr (9 8 7 6)))))' s1 = '(* (car (2 4 (+ 2 4) 8)) (/ 27 9));' lexer.input(s1)

while True: tok = lexer.token() if not tok: break print(tok)

# Parser

import ply.yacc as yacc from LispLexer import tokens

def p_LISP_Start(p): 'lispStart : lisplist SC' p[0] = p[1]

def p_LISPLIST_1(p): 'lisplist : lisp' p[0] = p[1]

def p_LISPLIST_2(p): 'lisplist : list' p[0] = p[1]

def p_LISP_1(p): 'lisp : NUM' p[0] = ['num',p[1]]

def p_LISP_2(p): 'lisp : ID' p[0] = ['id',p[1]]

def p_LISP_3(p): 'lisp : LP P lisp lisp RP' p[0] = ['+', p[3], p[4]]

def p_LISP_4(p): 'lisp : LP M lisp lisp RP' p[0] = ['-', p[3], p[4]]

def p_LISP_5(p): 'lisp : LP T lisp lisp RP' p[0] = ['*', p[3], p[4]]

def p_LISP_6(p): 'lisp : LP D lisp lisp RP' p[0] = ['/', p[3], p[4]]

def p_LISP_7(p): 'lisp : LP CAR list RP' p[0] = ['car', p[3]]

def p_LISP_8(p): 'lisp : LP ALLOW LP assigns RP lisp RP' p[0] = ['allow', p[4], p[6]] def p_ASSIGNS_1(p): 'assigns : assign' p[0] = [p[1]]

def p_ASSIGNS_2(p): 'assigns : assigns assign' p[0] = p[1] + [p[2]]

def p_ASSIGN(p): 'assign : LP ID lisp RP' p[0] = [p[2], p[3]]

def p_LIST_1(p): 'list : LP RP' p[0] = [[]]

def p_LIST_2(p): 'list : LP elements RP' p[0] = p[2]

def p_ELEMENTS_1(p): 'elements : lisp' p[0] = [p[1],[]]

def p_ELEMENTS_2(p): 'elements : lisp elements' p[0] = [p[1], p[2]]

def p_LIST_3(p): 'list : LP CDR list RP' p[0] = ['cdr', p[3]]

def p_LIST_4(p): 'list : LP CONS lisp list RP' p[0] = [p[3], p[4]]

def p_error(p): print("Syntax error in input!")

parser = yacc.yacc()

if __name__ == "__main__": l = ['34;', '(+ 20 30);', '(* (+ 1 2) (/ 8 4));', '(* (car (2 4 (+ 2 4) 8)) (/ 27 9));', '(+ (car (2 3 4)) (car (cdr (cdr (9 8 7 6)))));', '(+ x 4);', '(car (2 3 x y));', '(allow ((x 10) (y (+ 25 (car (20 30)))) (z (+ 10 23))) (+ x (car (y 20 z))) );', '(allow ((x 2)(y 4)) (+ x y));', '(allow ((x 10) (y (+ 25 (car (20 30)))) (z (+ 10 23))) (+ x (car (y 20 z))) );', '(car (cons 2 (cdr (10 20 30))));', '(cdr (1 2 3 4));']

l1 = ['(10 20 30)', '()', '(cdr (1 2 3 4))', '(cdr (cdr (cons 10 (20 30 (allow ((x 2)(y 4)) (+ x y))))))', '(cons 24 (30 (+ 20 20) 50))', '(cons (+ 3 4) ((+ 1 2) (* 1 2) (/20 2)))', '(cons 2 (cdr (10 20 30)))']

for data in l: print(parser.parse(data))

for data in l1: print(parser.parse(f'{data};'))

#Lisp

from LispParser import parser

def eval_expression(tree): if tree[0] == 'num': return (tree[1], 'OK')

if tree[0] == 'id': return (0, f'ERROR: Cannot evaluate ID {tree[1]}')

if tree[0] in ['+', '-', '*', '/']: v1, code1 = eval_expression(tree[1]) if (code1 != 'OK'): return (0, code1)

v2, code2 = eval_expression(tree[2]) if (code2 != 'OK'): return (0, code2)

if tree[0] == '+': result = v1+v2 elif tree[0] == '-': result = v1-v2 elif tree[0] == '*': result = v1*v2 else: if v2 == 0: return (0, "ERROR: Divided by 0!") result = v1/v2

return (result, 'OK')

if tree[0] == 'allow': sub = tree[2] for id_val in tree[1]: id = id_val[0] val, code = eval_expression(id_val[1]) if (code != 'OK'): return (0, code) sub = substitute(sub, id, val)

return eval_expression(sub)

return eval_list(tree)

def substitute(tree, id, val): tree1 = [] if (len(tree)>0 and tree[0] =='allow'): repls = tree[1] for repl in repls: if repl[0] == id: return tree

for node in tree: if (node == ['id', id]): tree1.append(['num', val]) else: if type(node) == list: tree1.append(substitute(node, id, val)) else: tree1.append(node) return tree1

def eval_list(tree): if (len(tree)>0) and tree[0] in ['car', 'cdr']: list1, code1 = eval_list(tree[1]) if (code1 != 'OK'): return (0, code1) if (list1 == []): return (0, f'{tree[0].upper()} of empty list Error!')

if (tree[0] == 'car'): return (list1[0], "OK") else: return (list1[1], "OK")

if tree != []: head, code = eval_expression(tree[0]) if (code == "OK"): tail, code1 = eval_list(tree[1]) if (code1 == "OK"): return ([head, tail], "OK") else: return (0, code1) else: return (0, code) else: return ([], "OK")

def grab_list(l): if (len(l)>1): return [l[0]] + grab_list(l[1]) else: return []

while(True): data = input("LISP: ") if (data[-1]!=';'): data+=';'

if (data == "exit;"): break

try: expr = parser.parse(data) val, code = eval_expression(expr) if (code == "OK"): if type(val) == list: val = grab_list(val) val = str(val).replace('[','(').replace(']',')').replace(',','')

print(f'The value is {val}') else: print(code) except Exception as e: print(e)

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Transactions On Large Scale Data And Knowledge Centered Systems Xxviii Special Issue On Database And Expert Systems Applications Lncs 9940

Authors: Abdelkader Hameurlain ,Josef Kung ,Roland Wagner ,Qimin Chen

1st Edition

3662534541, 978-3662534540

Students also viewed these Databases questions

Question

Types of cultural maps ?

Answered: 1 week ago

Question

Discuss the various types of leasing.

Answered: 1 week ago

Question

Define the term "Leasing"

Answered: 1 week ago

Question

What do you mean by Dividend ?

Answered: 1 week ago