Csc 4330/6330, Programming Language Concepts (Summer 2020)
Homework 3a (Due: 30 June (Tuesday); Late Submission by July 3 (Friday))
Handin under Assignment 3asudo handin4330 3a TokenTypes.py Token.py Lexer.py LexerTest.py Parser.py
Consider the simplified LISP Grammar (from Project 1) shown below:
lisp :
INT
| LPAREN ADD lisp lisp RPAREN
| LPAREN SUB lisp lisp RPAREN
| LPAREN MUL lisp lisp RPAREN
| LPAREN DIV lisp lisp RPAREN
| LPAREN CAR list RPAREN
list :
LPAREN CDR list RPAREN
| LPAREN seq RPAREN
seq :
lisp
| lisp seq
PART I: Lexical Analyzer
Write a Lexer program in Python without using the PLY system to generate the tokens for the LISP language.
Write it as a class with a constructor and a lex() method so that the Parser program can use it.
Here is the test program (LexerTest.py):
import sys
from Lexer import *
from TokenTypes import *
def main():
input = sys.argv[1]
lexer = Lexer(input)
print("Tokenizing ",end="")
print(input)
while True:
t = lexer.lex()
if t.get_token().value == TokenTypes.EOF.value:
break
main()
and a sample run:
macbook-pro:hw3a raj$ python3 LexerTest.py "(+ (car (1 2 3 4)) 20)" Tokenizing (+ (car (1 2 3 4)) 20) Next Token is: TokenTypes.LPAREN, Next lexeme is ( Next Token is: TokenTypes.ADD, Next lexeme is + Next Token is: TokenTypes.LPAREN, Next lexeme is ( Next Token is: TokenTypes.CAR, Next lexeme is CAR Next Token is: TokenTypes.LPAREN, Next lexeme is ( Next Token is: TokenTypes.INT, Next lexeme is 1 Next Token is: TokenTypes.INT, Next lexeme is 2 Next Token is: TokenTypes.INT, Next lexeme is 3 Next Token is: TokenTypes.INT, Next lexeme is 4 Next Token is: TokenTypes.RPAREN, Next lexeme is ) Next Token is: TokenTypes.RPAREN, Next lexeme is ) Next Token is: TokenTypes.INT, Next lexeme is 20 Next Token is: TokenTypes.RPAREN, Next lexeme is ) Next Token is: TokenTypes.EOF, Next lexeme is -1
PART II: Recursive Descent Parser
Write a Recursive Descent Parser in Python (Parser.py). Here are couple of sample runs:
macbook-pro:hw3a raj$ python3 Parser.py "(+ (car (1 2 3 4)) 20)" Next Token is: TokenTypes.LPAREN, Next lexeme is ( Enter lisp Next Token is: TokenTypes.ADD, Next lexeme is + Next Token is: TokenTypes.LPAREN, Next lexeme is ( Enter lisp Next Token is: TokenTypes.CAR, Next lexeme is CAR Next Token is: TokenTypes.LPAREN, Next lexeme is ( Enter list Next Token is: TokenTypes.INT, Next lexeme is 1 Enter seq Enter lisp Next Token is: TokenTypes.INT, Next lexeme is 2 Exit lisp Enter lisp Next Token is: TokenTypes.INT, Next lexeme is 3 Exit lisp Enter lisp Next Token is: TokenTypes.INT, Next lexeme is 4 Exit lisp Enter lisp Next Token is: TokenTypes.RPAREN, Next lexeme is ) Exit lisp Exit seq Next Token is: TokenTypes.RPAREN, Next lexeme is ) Exit list Next Token is: TokenTypes.INT, Next lexeme is 20 Exit lisp Enter lisp Next Token is: TokenTypes.RPAREN, Next lexeme is ) Exit lisp Next Token is: TokenTypes.EOF, Next lexeme is -1 Exit lisp PARSE SUCCEEDED macbook-pro:hw3a raj$ python3 Parser.py "(+ (car (1 2 3 4)) )" Next Token is: TokenTypes.LPAREN, Next lexeme is ( Enter lisp Next Token is: TokenTypes.ADD, Next lexeme is + Next Token is: TokenTypes.LPAREN, Next lexeme is ( Enter lisp Next Token is: TokenTypes.CAR, Next lexeme is CAR Next Token is: TokenTypes.LPAREN, Next lexeme is ( Enter list Next Token is: TokenTypes.INT, Next lexeme is 1 Enter seq Enter lisp Next Token is: TokenTypes.INT, Next lexeme is 2 Exit lisp Enter lisp Next Token is: TokenTypes.INT, Next lexeme is 3 Exit lisp Enter lisp Next Token is: TokenTypes.INT, Next lexeme is 4 Exit lisp Enter lisp Next Token is: TokenTypes.RPAREN, Next lexeme is ) Exit lisp Exit seq Next Token is: TokenTypes.RPAREN, Next lexeme is ) Exit list Next Token is: TokenTypes.RPAREN, Next lexeme is ) Exit lisp Enter lisp SYNTAX ERROR: Expecting LPAREN