class Recognizer(): def __init__(self, filename): self.file = open(filename) self.pending = None self.lexer = Lexer(self.file) def fatal(self, problem, line): print("LINE: "+str(line)+"\nERROR: "+problem) exit(1) def parse(self): # print("In parse") self.advance() self.program() self.match("END_OF_INPUT") # print("Done") def check(self, t): # print("Check: "+self.pending.ltype+" vs "+t) return self.pending.ltype == t def advance(self): # print("In advance") old = self.pending self.pending = self.lexer.lex() # print("New Lexeme is "+self.pending.ltype) return old def match(self, t) : # print("Match: "+t) if(self.check(t)): # print("Token: "+str(self.pending)) return self.advance() self.fatal("Syntax Error. Expected "+str(t)+" , Received "+str(self.pending), self.lexer.lineNumber) # program : definition # | definition program def program(self): # print("In program") self.definition() if (self.programPending()): self.program() def programPending(self): # print("In programPending") return self.definitionPending() # definition : variableDefinition # | functionDefinition # | idDef SEMI def definition(self): # print("In definition") if(self.variableDefinitionPending()): self.variableDefinition() elif(self.functionDefinitionPending()): self.functionDefinition() elif(self.idDefPending()): self.idDef() self.match("SEMI") def definitionPending(self): # print("In definitionPending") return self.variableDefinitionPending() or self.functionDefinitionPending() or self.idDefPending() # variableDefinition : VAR ID EQUAL expr SEMI def variableDefinition(self): # print("In variableDefinition") self.match("VAR") self.match("ID") self.match("EQUAL") self.expr() self.match("SEMI") def variableDefinitionPending(self): # print("In variableDefinitionPending") return self.check("VAR") # functionDefinition : FUNCTION ID OPAREN optParamList CPAREN block def functionDefinition(self): # print("In functionDefinition") self.match("FUNCTION") self.match("ID") self.match("OPAREN") self.optParamList() self.match("CPAREN") self.block() def functionDefinitionPending(self): # print("In functionDefinitionPending") return self.check("FUNCTION") # optParamList : EMPTY # | paramList def optParamList(self): # print("In optParamList") if(self.paramListPending()): self.paramList() # paramList : ID # | ID COMMA paramList def paramList(self): # print("In paramList") self.match("ID") if (self.check("COMMA")): self.match("COMMA") self.paramList() def paramListPending(self): # print("In paramListPending") return self.check("ID") # optExprList : EMPTY # | exprList def optExprList(self): # print("In optExprList") if(self.exprListPending()): self.exprList() # exprList : expr # | expr COMMA exprList def exprList(self): # print("In exprList") self.expr() if (self.check("COMMA")): self.match("COMMA") self.exprList() def exprListPending(self): # print("In exprListPending") return self.exprPending() # expr : primary # | primary operator expr def expr(self): # print("In expr") self.primary() if(self.operatorPending()): self.operator() self.expr() def exprPending(self): # print("In exprPending") return self.primaryPending() # primary : idDef # | STRING # | INTEGER # | NOT primary # | OPAREN expr CPAREN # | k_lambda # | functionDefinition # | OBRACKET optExprList CBRACKET def primary(self): # print("In primary") if (self.idDefPending()): self.idDef() elif (self.check("STRING")): self.match("STRING") elif (self.check("INTEGER")): self.match("INTEGER") elif (self.check("NOT")): self.match("NOT") self.primary() elif (self.check("OPAREN")): self.match("OPAREN") self.expr() self.match("CPAREN") elif (self.k_lambdaPending()): self.k_lambda() elif (self.functionDefinitionPending()): self.functionDefinition() elif (self.check("OBRACKET")): self.match("OBRACKET") self.optExprList() self.match("OBRACKET") def primaryPending(self): # print("In primaryPending") return self.idDefPending() or self.check("STRING") or self.check("INTEGER") or self.check("NOT") or self.check("OPAREN") or self.k_lambdaPending() or self.functionDefinitionPending() or self.check("OBRACKET") # idDef : ID # | ID OPAREN optExprList CPAREN # | ID OBRACKET expr CBRACKET def idDef(self): # print("In idDef") self.match("ID") if (self.check("OPAREN")): self.match("OPAREN") self.optExprList() self.match("CPAREN") elif (self.check("OBRACKET")): self.match("OBRACKET") self.expr() self.match("CBRACKET") def idDefPending(self): # print("In idDefPending") return self.check("ID") # operator : EQUAL # | NOTEQUAL # | GREATER # | LESS # | GREATEREQUAL # | LESSEQUAL # | PLUS # | MINUS # | MULTIPLY # | DIVIDE # | POWER # | AND # | OR # | DOUBLEEQUAL def operator(self): # print("In operator") if(self.check("EQUAL")): self.match("EQUAL") elif(self.check("NOTEQUAL")): self.match("NOTEQUAL") elif(self.check("GREATER")): self.match("GREATER") elif(self.check("LESS")): self.match("LESS") elif(self.check("GREATEREQUAL")): self.match("GREATEREQUAL") elif(self.check("LESSEQUAL")): self.match("LESSEQUAL") elif(self.check("PLUS")): self.match("PLUS") elif(self.check("MINUS")): self.match("MINUS") elif(self.check("MULTIPLY")): self.match("MULTIPLY") elif(self.check("DIVIDE")): self.match("DIVIDE") elif(self.check("POWER")): self.match("POWER") elif(self.check("AND")): self.match("AND") elif(self.check("OR")): self.match("OR") elif(self.check("ASSIGN")): self.match("ASSIGN") def operatorPending(self): # print("In operatorPending") return self.check("EQUAL") or self.check("NOTEQUAL") or self.check("GREATER") or self.check("LESS") or self.check("GREATEREQUAL") or self.check("LESSEQUAL") or self.check("PLUS") or self.check("MINUS") or self.check("MULTIPLY") or self.check("DIVIDE") or self.check("POWER") or self.check("AND") or self.check("OR") or self.check("ASSIGN") # block : OBRACE optStatementList CBRACE def block(self): # print("In block") self.match("OBRACE") self.optStatementList() self.match("CBRACE") def blockPending(self): # print("In blockPending") return self.check("OBRACE") # optStatementList : EMPTY # | statementList def optStatementList(self): # print("In optStatementList") if (self.statementListPending()): self.statementList() # statementList : statement # | statement statementList def statementList(self): # print("In statementList") self.statement() if(self.statementListPending()): self.statementList() def statementListPending(self): # print("In statementListPending") return self.statementPending() # statement : variableDefinition # | functionDefinition # | expr SEMI # | whileLoop # | ifStatement # | RETURN expr SEMI def statement(self): # print("In statement") if(self.variableDefinitionPending()): self.variableDefinition() elif(self.functionDefinitionPending()): self.functionDefinition() elif(self.exprPending()): self.expr() self.match("SEMI") elif(self.whileLoopPending()): self.whileLoop() elif(self.ifStatementPending()): self.ifStatement() elif(self.check("RETURN")): self.match("RETURN") self.expr() self.match("SEMI") def statementPending(self): # print("In statementPending") return self.variableDefinitionPending() or self.functionDefinitionPending() or self.exprPending() or self.whileLoopPending() or self.ifStatementPending() or self.check("RETURN") # whileLoop : WHILE OPAREN expr CPAREN block def whileLoop(self): # print("In whileLoop") self.match("WHILE") self.match("OPAREN") self.expr() self.match("CPAREN") self.block() def whileLoopPending(self): # print("In whileLoopPending") return self.check("WHILE") # ifStatement : IF OPAREN expr CPAREN block optElseStatement def ifStatement(self): # print("In ifStatement") self.match("IF") self.match("OPAREN") self.expr() self.match("CPAREN") self.block() self.optElseStatement() def ifStatementPending(self): # print("In ifStatementPending") return self.check("IF") # optElseStatement : EMPTY # | elseStatement def optElseStatement(self): # print("In optElseStatement") if (self.elseStatementPending()): self.elseStatement() # elseStatement : ELSE block # | ELSE ifStatement def elseStatement(self): # print("In elseStatement") self.match("ELSE") if(self.blockPending()): self.block() elif(self.ifStatementPending()): self.ifStatement() def elseStatementPending(self): # print("In elseStatementPending") return self.check("ELSE") # k_lambda : LAMBDA OPAREN optParamList CPAREN block def k_lambda(self): # print("In k_lambda") self.match("LAMBDA") self.match("OPAREN") self.optParamList() self.match("CPAREN") self.block() def k_lambdaPending(self): # print("In k_lambdaPending") return self.check("LAMBDA")
from lex import Lexer from parse import Parser from codegen import CodeGen fname = "input.toy" with open(fname) as f: text_input = f.read() lexer = Lexer().get_lexer() tokens = lexer.lex(text_input) codegen = CodeGen() module = codegen.module builder = codegen.builder printf = codegen.printf #~ pg = Parser(module, builder, printf) pg1 = Parser() pg1.parse() parser = pg1.get_parser() parser.parse(tokens) codegen.create_ir() #~ codegen.save_ir("output.ll")
dot.edge(p_name, name) for n in node.params: see_node(name, n, dot) see_node(name, node.body, dot) for n in node.localvars: see_node(name, n, dot) elif type(node) == CompoundStmtNode: dot.node(name, str(node.kind)) dot.edge(p_name, name) for n in node.stmts: see_node(name, n, dot) elif type(node) == IfStmtNode: dot.node(name, str(node.kind)) dot.edge(p_name, name) see_node(name, node.cond, dot) see_node(name, node.then, dot) if not node.els is None: see_node(name, node.els, dot) if __name__ == '__main__': path = './t1.c' l = Lexer(filename(path), read_file(path)) l.lex() l.see_tokens() p = Parser(l.tokens) p.parse() see_ast(p.ast)
class Recognizer(): def __init__(self, filename): self.file = open(filename) self.pending = None self.lexer = Lexer(self.file) def fatal(self, problem, line): print("LINE: " + str(line) + "\nERROR: " + problem) exit(1) def parse(self): # print("In parse") self.advance() self.program() self.match("END_OF_INPUT") # print("Done") def check(self, t): # print("Check: "+self.pending.ltype+" vs "+t) return self.pending.ltype == t def advance(self): # print("In advance") old = self.pending self.pending = self.lexer.lex() # print("New Lexeme is "+self.pending.ltype) return old def match(self, t): # print("Match: "+t) if (self.check(t)): # print("Token: "+str(self.pending)) return self.advance() self.fatal( "Syntax Error. Expected " + str(t) + " , Received " + str(self.pending), self.lexer.lineNumber) # program : definition # | definition program def program(self): # print("In program") self.definition() if (self.programPending()): self.program() def programPending(self): # print("In programPending") return self.definitionPending() # definition : variableDefinition # | functionDefinition # | idDef SEMI def definition(self): # print("In definition") if (self.variableDefinitionPending()): self.variableDefinition() elif (self.functionDefinitionPending()): self.functionDefinition() elif (self.idDefPending()): self.idDef() self.match("SEMI") def definitionPending(self): # print("In definitionPending") return self.variableDefinitionPending( ) or self.functionDefinitionPending() or self.idDefPending() # variableDefinition : VAR ID EQUAL expr SEMI def variableDefinition(self): # print("In variableDefinition") self.match("VAR") self.match("ID") self.match("EQUAL") self.expr() self.match("SEMI") def variableDefinitionPending(self): # print("In variableDefinitionPending") return self.check("VAR") # functionDefinition : FUNCTION ID OPAREN optParamList CPAREN block def functionDefinition(self): # print("In functionDefinition") self.match("FUNCTION") self.match("ID") self.match("OPAREN") self.optParamList() self.match("CPAREN") self.block() def functionDefinitionPending(self): # print("In functionDefinitionPending") return self.check("FUNCTION") # optParamList : EMPTY # | paramList def optParamList(self): # print("In optParamList") if (self.paramListPending()): self.paramList() # paramList : ID # | ID COMMA paramList def paramList(self): # print("In paramList") self.match("ID") if (self.check("COMMA")): self.match("COMMA") self.paramList() def paramListPending(self): # print("In paramListPending") return self.check("ID") # optExprList : EMPTY # | exprList def optExprList(self): # print("In optExprList") if (self.exprListPending()): self.exprList() # exprList : expr # | expr COMMA exprList def exprList(self): # print("In exprList") self.expr() if (self.check("COMMA")): self.match("COMMA") self.exprList() def exprListPending(self): # print("In exprListPending") return self.exprPending() # expr : primary # | primary operator expr def expr(self): # print("In expr") self.primary() if (self.operatorPending()): self.operator() self.expr() def exprPending(self): # print("In exprPending") return self.primaryPending() # primary : idDef # | STRING # | INTEGER # | NOT primary # | OPAREN expr CPAREN # | k_lambda # | functionDefinition # | OBRACKET optExprList CBRACKET def primary(self): # print("In primary") if (self.idDefPending()): self.idDef() elif (self.check("STRING")): self.match("STRING") elif (self.check("INTEGER")): self.match("INTEGER") elif (self.check("NOT")): self.match("NOT") self.primary() elif (self.check("OPAREN")): self.match("OPAREN") self.expr() self.match("CPAREN") elif (self.k_lambdaPending()): self.k_lambda() elif (self.functionDefinitionPending()): self.functionDefinition() elif (self.check("OBRACKET")): self.match("OBRACKET") self.optExprList() self.match("OBRACKET") def primaryPending(self): # print("In primaryPending") return self.idDefPending() or self.check("STRING") or self.check( "INTEGER") or self.check("NOT") or self.check( "OPAREN") or self.k_lambdaPending( ) or self.functionDefinitionPending() or self.check("OBRACKET") # idDef : ID # | ID OPAREN optExprList CPAREN # | ID OBRACKET expr CBRACKET def idDef(self): # print("In idDef") self.match("ID") if (self.check("OPAREN")): self.match("OPAREN") self.optExprList() self.match("CPAREN") elif (self.check("OBRACKET")): self.match("OBRACKET") self.expr() self.match("CBRACKET") def idDefPending(self): # print("In idDefPending") return self.check("ID") # operator : EQUAL # | NOTEQUAL # | GREATER # | LESS # | GREATEREQUAL # | LESSEQUAL # | PLUS # | MINUS # | MULTIPLY # | DIVIDE # | POWER # | AND # | OR # | DOUBLEEQUAL def operator(self): # print("In operator") if (self.check("EQUAL")): self.match("EQUAL") elif (self.check("NOTEQUAL")): self.match("NOTEQUAL") elif (self.check("GREATER")): self.match("GREATER") elif (self.check("LESS")): self.match("LESS") elif (self.check("GREATEREQUAL")): self.match("GREATEREQUAL") elif (self.check("LESSEQUAL")): self.match("LESSEQUAL") elif (self.check("PLUS")): self.match("PLUS") elif (self.check("MINUS")): self.match("MINUS") elif (self.check("MULTIPLY")): self.match("MULTIPLY") elif (self.check("DIVIDE")): self.match("DIVIDE") elif (self.check("POWER")): self.match("POWER") elif (self.check("AND")): self.match("AND") elif (self.check("OR")): self.match("OR") elif (self.check("ASSIGN")): self.match("ASSIGN") def operatorPending(self): # print("In operatorPending") return self.check("EQUAL") or self.check("NOTEQUAL") or self.check( "GREATER") or self.check("LESS") or self.check( "GREATEREQUAL") or self.check("LESSEQUAL") or self.check( "PLUS") or self.check("MINUS") or self.check( "MULTIPLY") or self.check("DIVIDE") or self.check( "POWER") or self.check("AND") or self.check( "OR") or self.check("ASSIGN") # block : OBRACE optStatementList CBRACE def block(self): # print("In block") self.match("OBRACE") self.optStatementList() self.match("CBRACE") def blockPending(self): # print("In blockPending") return self.check("OBRACE") # optStatementList : EMPTY # | statementList def optStatementList(self): # print("In optStatementList") if (self.statementListPending()): self.statementList() # statementList : statement # | statement statementList def statementList(self): # print("In statementList") self.statement() if (self.statementListPending()): self.statementList() def statementListPending(self): # print("In statementListPending") return self.statementPending() # statement : variableDefinition # | functionDefinition # | expr SEMI # | whileLoop # | ifStatement # | RETURN expr SEMI def statement(self): # print("In statement") if (self.variableDefinitionPending()): self.variableDefinition() elif (self.functionDefinitionPending()): self.functionDefinition() elif (self.exprPending()): self.expr() self.match("SEMI") elif (self.whileLoopPending()): self.whileLoop() elif (self.ifStatementPending()): self.ifStatement() elif (self.check("RETURN")): self.match("RETURN") self.expr() self.match("SEMI") def statementPending(self): # print("In statementPending") return self.variableDefinitionPending( ) or self.functionDefinitionPending() or self.exprPending( ) or self.whileLoopPending() or self.ifStatementPending( ) or self.check("RETURN") # whileLoop : WHILE OPAREN expr CPAREN block def whileLoop(self): # print("In whileLoop") self.match("WHILE") self.match("OPAREN") self.expr() self.match("CPAREN") self.block() def whileLoopPending(self): # print("In whileLoopPending") return self.check("WHILE") # ifStatement : IF OPAREN expr CPAREN block optElseStatement def ifStatement(self): # print("In ifStatement") self.match("IF") self.match("OPAREN") self.expr() self.match("CPAREN") self.block() self.optElseStatement() def ifStatementPending(self): # print("In ifStatementPending") return self.check("IF") # optElseStatement : EMPTY # | elseStatement def optElseStatement(self): # print("In optElseStatement") if (self.elseStatementPending()): self.elseStatement() # elseStatement : ELSE block # | ELSE ifStatement def elseStatement(self): # print("In elseStatement") self.match("ELSE") if (self.blockPending()): self.block() elif (self.ifStatementPending()): self.ifStatement() def elseStatementPending(self): # print("In elseStatementPending") return self.check("ELSE") # k_lambda : LAMBDA OPAREN optParamList CPAREN block def k_lambda(self): # print("In k_lambda") self.match("LAMBDA") self.match("OPAREN") self.optParamList() self.match("CPAREN") self.block() def k_lambdaPending(self): # print("In k_lambdaPending") return self.check("LAMBDA")
import sys sys.path.append("..") from lex import Lexer def filename(path): index = str(path).rfind('/') + 1 name = path[index:] return name def read_file(path): with open(path, 'r') as f: return f.read() if __name__ == '__main__': path = './t1.c' lexer = Lexer(filename(path), read_file(path)) lexer.lex() lexer.see_tokens()
class Parser(): def __init__(self, filename): self.file = open(filename) self.pending = None self.lexer = Lexer(self.file) def fatal(self, problem, line): print("LINE: "+str(line)+"\nERROR: "+problem) exit(1) def parse(self): # print("In parse") self.advance() root = self.program() eof = self.match("END_OF_INPUT") return self.cons("PARSE", root, eof) # print("Done") def check(self, t): # print("Check: "+self.pending.ltype+" vs "+t) return self.pending.ltype == t def advance(self): # print("In advance") old = self.pending self.pending = self.lexer.lex() # print("New Lexeme is "+self.pending.ltype) return old def match(self, t) : # print("Match: "+t) if(self.check(t)): # print("Token: "+str(self.pending)) return self.advance() self.fatal("Syntax Error. Expected "+str(t)+" , Received "+str(self.pending.lvalue), self.lexer.lineNumber) def cons(self, value, left, right): return Lexeme(value, value, left, right) # ============================================================================= # GRAMMAR PORTION OF THE PARSING CLASS # ============================================================================= # program : definition # | definition program def program(self): # print("In program") d = self.definition() if (self.programPending()): p = self.program() return self.cons("PROGRAM", d, self.cons("JOIN", p, None)) return self.cons("PROGRAM", d, None) # definition : variableDefinition # | functionDefinition # | idDef SEMI def definition(self): # print("In definition") if(self.variableDefinitionPending()): v =self.variableDefinition() return self.cons("DEFINITION", v, None) elif(self.functionDefinitionPending()): f = self.functionDefinition() return self.cons("DEFINITION", f, None) # variableDefinition : VAR ID EQUAL expr SEMI def variableDefinition(self): # print("In variableDefinition") v = self.match("VAR") i = self.match("ID") eq = self.match("EQUAL") e = self.expr() s = self.match("SEMI") return self.cons("VARDEF", v, self.cons("JOIN", i, self.cons("JOIN", eq, self.cons("JOIN", e, self.cons("JOIN", s, None))))) # functionDefinition : FUNCTION ID OPAREN optParamList CPAREN block def functionDefinition(self): # print("In functionDefinition") f = self.match("FUNCTION") e = self.match("ID") o = self.match("OPAREN") op = self.optParamList() c = self.match("CPAREN") b = self.block() return self.cons("FUNCDEF", f, self.cons("JOIN", e, self.cons("JOIN", o, self.cons("JOIN", op, self.cons("JOIN", c, self.cons("JOIN", b, None)))))) # idDef : ID # | ID OPAREN optExprList CPAREN # | ID OBRACKET expr CBRACKET def idDef(self): # print("In idDef") i = self.match("ID") if (self.check("OPAREN")): o = self.match("OPAREN") e = self.optExprList() c = self.match("CPAREN") return self.cons("FUNCCALL", i, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) elif (self.check("OBRACKET")): o = self.match("OBRACKET") e = self.expr() c = self.match("CBRACKET") return self.cons("ARRAYACCESS", i, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) else: return self.cons("IDDEF", i, None) # optParamList : EMPTY # | paramList def optParamList(self): # print("In optParamList") if(self.paramListPending()): p = self.paramList() return self.cons("OPTPARAMLIST", p, None) return self.cons("OPTPARAMLIST", None, None) # paramList : ID # | ID COMMA paramList def paramList(self): # print("In paramList") i = self.match("ID") if (self.check("COMMA")): c = self.match("COMMA") p = self.paramList() return self.cons("PARAMLIST", i, self.cons("JOIN", c, self.cons("JOIN", p, None))) return self.cons("PARAMLIST", i, None) # optExprList : EMPTY # | exprList def optExprList(self): # print("In optExprList") if(self.exprListPending()): e = self.exprList() return self.cons("OPTEXPRLIST", e, None) return self.cons("OPTEXPRLIST", None, None) # exprList : expr # | expr COMMA exprList def exprList(self): # print("In exprList") e = self.expr() if (self.check("COMMA")): c = self.match("COMMA") ex = self.exprList() return self.cons("EXPRLIST", e, self.cons("JOIN", c, self.cons("JOIN", ex, None))) return self.cons("EXPRLIST", e, None) # expr : primary # | primary operator expr def expr(self): # print("In expr") p = self.primary() if(self.operatorPending()): o = self.operator() e = self.expr() return Lexeme("EXPR", "EXPR", Lexeme("OPERATOR", o, p, e)) return self.cons("EXPR", p, None) # primary : idDef # | STRING # | INTEGER # | NOT primary # | OPAREN expr CPAREN # | k_lambda # | functionDefinition # | OBRACKET optExprList CBRACKET # | NIL # | BOOLEAN # | PRINT OPAREN exprList CPAREN # | APPEND OPAREN exprList CPAREN # | REMOVE OPAREN exprList CPAREN # | SET OPAREN exprList CPAREN # | LENGTH OPAREN exprList CPAREN def primary(self): # print("In primary") if (self.idDefPending()): p = self.idDef() return self.cons("PRIMARY", p, None) elif (self.check("STRING")): p = self.match("STRING") return self.cons("PRIMARY", p, None) elif (self.check("INTEGER")): p = self.match("INTEGER") return self.cons("PRIMARY", p, None) elif (self.check("NOT")): n = self.match("NOT") p = self.primary() return self.cons("PRIMARY", n, self.cons("JOIN", p, None)) elif (self.check("OPAREN")): o = self.match("OPAREN") e = self.expr() c = self.match("CPAREN") return self.cons("PRIMARY", o, self.cons("JOIN", e, self.cons("JOIN", c, None))) elif (self.k_lambdaPending()): p = self.k_lambda() return self.cons("PRIMARY", p, None) elif (self.functionDefinitionPending()): p = self.functionDefinition() return self.cons("PRIMARY", p, None) elif (self.check("OBRACKET")): o = self.match("OBRACKET") e = self.optExprList() c = self.match("CBRACKET") return self.cons("PRIMARY", o, self.cons("JOIN", e, self.cons("JOIN", c, None))) elif (self.check("NIL")): n = self.match("NIL") return self.cons("PRIMARY", n, None) elif (self.check("BOOLEAN")): b = self.match("BOOLEAN") return self.cons("PRIMARY", b, None) elif (self.check("PRINT")): f = self.match("PRINT") o = self.match("OPAREN") e = self.exprList() c = self.match("CPAREN") return self.cons("PRINT", f, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) elif (self.check("APPEND")): f = self.match("APPEND") o = self.match("OPAREN") e = self.exprList() c = self.match("CPAREN") return self.cons("APPEND", f, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) elif (self.check("INSERT")): f = self.match("INSERT") o = self.match("OPAREN") e = self.exprList() c = self.match("CPAREN") return self.cons("INSERT", f, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) elif (self.check("REMOVE")): f = self.match("REMOVE") o = self.match("OPAREN") e = self.exprList() c = self.match("CPAREN") return self.cons("REMOVE", f, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) elif (self.check("SET")): f = self.match("SET") o = self.match("OPAREN") e = self.exprList() c = self.match("CPAREN") return self.cons("SET", f, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) elif (self.check("LENGTH")): f = self.match("LENGTH") o = self.match("OPAREN") e = self.exprList() c = self.match("CPAREN") return self.cons("LENGTH", f, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) # operator : EQUAL # | NOTEQUAL # | GREATER # | LESS # | GREATEREQUAL # | LESSEQUAL # | PLUS # | MINUS # | MULTIPLY # | DIVIDE # | INTEGERDIVIDE # | POWER # | AND # | OR # | DOUBLEEQUAL def operator(self): # print("In operator") if(self.check("EQUAL")): op = self.match("EQUAL") return self.cons("EQUAL", op, None) elif(self.check("NOTEQUAL")): op = self.match("NOTEQUAL") return self.cons("NOTEQUAL", op, None) elif(self.check("GREATER")): op = self.match("GREATER") return self.cons("GREATER", op, None) elif(self.check("LESS")): op = self.match("LESS") return self.cons("LESS", op, None) elif(self.check("GREATEREQUAL")): op = self.match("GREATEREQUAL") return self.cons("GREATEREQUAL", op, None) elif(self.check("LESSEQUAL")): op = self.match("LESSEQUAL") return self.cons("LESSEQUAL", op, None) elif(self.check("PLUS")): op = self.match("PLUS") return self.cons("PLUS", op, None) elif(self.check("MINUS")): op = self.match("MINUS") return self.cons("MINUS", op, None) elif(self.check("MULTIPLY")): op = self.match("MULTIPLY") return self.cons("MULTIPLY", op, None) elif(self.check("DIVIDE")): op = self.match("DIVIDE") return self.cons("DIVIDE", op, None) elif(self.check("INTEGERDIVIDE")): op = self.match("INTEGERDIVIDE") return self.cons("INTEGERDIVIDE", op, None) elif(self.check("POWER")): op = self.match("POWER") return self.cons("POWER", op, None) elif(self.check("AND")): op = self.match("AND") return self.cons("AND", op, None) elif(self.check("OR")): op = self.match("OR") return self.cons("OR", op, None) elif(self.check("ASSIGN")): op = self.match("ASSIGN") return self.cons("ASSIGN", op, None) elif(self.check("DOUBLEEQUAL")): op = self.match("DOUBLEEQUAL") return self.cons("DOUBLEEQUAL", op, None) # block : OBRACE optStatementList CBRACE def block(self): # print("In block") o = self.match("OBRACE") s = self.optStatementList() c = self.match("CBRACE") return self.cons("BLOCK", o, self.cons("JOIN", s, self.cons("JOIN", c, None))) # optStatementList : EMPTY # | statementList def optStatementList(self): # print("In optStatementList") if (self.statementListPending()): s = self.statementList() return self.cons("OPTSTATEMENTLIST", s, None) return self.cons("OPTSTATEMENTLIST", None, None) # statementList : statement # | statement statementList def statementList(self): # print("In statementList") s= self.statement() if(self.statementListPending()): sl = self.statementList() return self.cons("STATEMENTLIST", s, self.cons("JOIN", sl, None)) return self.cons("STATEMENTLIST", s, None) # statement : variableDefinition # | functionDefinition # | expr SEMI # | whileLoop # | ifStatement # | RETURN expr SEMI def statement(self): # print("In statement") if(self.variableDefinitionPending()): v = self.variableDefinition() return self.cons("STATEMENT", v, None) elif(self.functionDefinitionPending()): f = self.functionDefinition() return self.cons("STATEMENT", f, None) elif(self.exprPending()): e = self.expr() s = self.match("SEMI") return self.cons("STATEMENT", e, self.cons("JOIN", s, None)) elif(self.whileLoopPending()): w = self.whileLoop() return self.cons("STATEMENT", w, None) elif(self.ifStatementPending()): i = self.ifStatement() return self.cons("STATEMENT", i, None) elif(self.check("RETURN")): r = self.match("RETURN") e = self.expr() s = self.match("SEMI") return self.cons("STATEMENT", r ,self.cons("JOIN", e, self.cons("JOIN", s, None))) # whileLoop : WHILE OPAREN expr CPAREN block def whileLoop(self): # print("In whileLoop") w = self.match("WHILE") o = self.match("OPAREN") e = self.expr() c = self.match("CPAREN") b = self.block() return self.cons("WHILELOOP", w ,self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, self.cons("JOIN", b, None))))) # ifStatement : IF OPAREN expr CPAREN block optElseStatement def ifStatement(self): # print("In ifStatement") i = self.match("IF") o = self.match("OPAREN") e = self.expr() c = self.match("CPAREN") b = self.block() oe = self.optElseStatement() return self.cons("IFSTATEMENT", i ,self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, self.cons("JOIN", b, self.cons("JOIN", oe, None)))))) # optElseStatement : EMPTY # | elseStatement def optElseStatement(self): # print("In optElseStatement") if (self.elseStatementPending()): e = self.elseStatement() return self.cons("OPTELSESTATEMENT", e, None) return self.cons("OPTELSESTATEMENT", None, None) # elseStatement : ELSE block # | ELSE ifStatement def elseStatement(self): # print("In elseStatement") e = self.match("ELSE") if(self.blockPending()): b = self.block() return self.cons("ELSESTATEMENT", e, self.cons("JOIN", b, None)) elif(self.ifStatementPending()): i = self.ifStatement() return self.cons("ELSESTATEMENT", e, self.cons("JOIN", i, None)) # k_lambda : LAMBDA OPAREN optParamList CPAREN block def k_lambda(self): # print("In k_lambda") l = self.match("LAMBDA") o = self.match("OPAREN") op = self.optParamList() c = self.match("CPAREN") b = self.block() return self.cons("LAMBDA", l ,self.cons("JOIN", o, self.cons("JOIN", op, self.cons("JOIN", c, self.cons("JOIN", b, None))))) # ============================================================================= # Pending Statements # ============================================================================= def programPending(self): # print("In programPending") return self.definitionPending() def definitionPending(self): # print("In definitionPending") return self.variableDefinitionPending() or self.functionDefinitionPending() or self.idDefPending() def variableDefinitionPending(self): # print("In variableDefinitionPending") return self.check("VAR") def functionDefinitionPending(self): # print("In functionDefinitionPending") return self.check("FUNCTION") def idDefPending(self): # print("In idDefPending") return self.check("ID") def paramListPending(self): # print("In paramListPending") return self.check("ID") def exprListPending(self): # print("In exprListPending") return self.exprPending() def exprPending(self): # print("In exprPending") return self.primaryPending() def primaryPending(self): # print("In primaryPending") return self.idDefPending() or self.check("STRING") or self.check("INTEGER") or self.check("NOT") or self.check("OPAREN") or self.k_lambdaPending() or self.functionDefinitionPending() or self.check("OBRACKET") or self.check("NIL") or self.check("BOOLEAN") or self.check("PRINT") or self.check("APPEND") or self.check("INSERT") or self.check("REMOVE") or self.check("SET") or self.check("LENGTH") def operatorPending(self): # print("In operatorPending") return self.check("EQUAL") or self.check("NOTEQUAL") or self.check("GREATER") or self.check("LESS") or self.check("GREATEREQUAL") or self.check("LESSEQUAL") or self.check("PLUS") or self.check("MINUS") or self.check("MULTIPLY") or self.check("DIVIDE") or self.check("INTEGERDIVIDE") or self.check("POWER") or self.check("AND") or self.check("OR") or self.check("ASSIGN") or self.check("DOUBLEEQUAL") def blockPending(self): # print("In blockPending") return self.check("OBRACE") def statementListPending(self): # print("In statementListPending") return self.statementPending() def statementPending(self): # print("In statementPending") return self.variableDefinitionPending() or self.functionDefinitionPending() or self.exprPending() or self.whileLoopPending() or self.ifStatementPending() or self.check("RETURN") def whileLoopPending(self): # print("In whileLoopPending") return self.check("WHILE") def ifStatementPending(self): # print("In ifStatementPending") return self.check("IF") def elseStatementPending(self): # print("In elseStatementPending") return self.check("ELSE") def k_lambdaPending(self): # print("In k_lambdaPending") return self.check("LAMBDA")
class Parser(object): def __init__(self, prog): self.lexer = Lexer(prog) self.tokens = self.lexer.lex() self.peeked = False self.prev = None self.tok = self.next_token() self.eof = False self.parsing_declr = False def next_token(self): try: typ, val = tok = self.tokens.next() except StopIteration: self.eof = True return if typ not in operators: return Symbol(tok) elif typ == '{': return LeftBrace(self) elif typ == '(': return LeftParen(self) elif typ == '[': return LeftBracket(self) elif typ == ',': return Comma(self) elif typ in values: return Value(tok) elif typ == 'sizeof': return Sizeof(self) else: return Operator(self, typ) def advance(self): self.prev = self.tok if not self.peeked: self.tok = self.next_token() else: self.peeked = False self.tok = self.peekedTok def peek(self): self.peeked = True self.peekedTok = self.next_token() return self.peekedTok def error(self, msg=None): if msg is None: msg = 'Unexpected "%s"' % repr(self.tok) raise SyntaxError("Error detected at line %d - %s"% (self.lexer.line, msg)) def accept(self, typ): if self.eof: self.error("Unexpected EOF") return self.tok.is_(typ) def expect(self, typ): if not self.accept(typ): self.error() self.advance() def expression(self, rbp=0): t = self.tok self.advance() left = t.nud() while rbp < self.tok.lbp: t = self.tok self.advance() left = t.led(left) return left def parse_declr_expr(self, typ, e): ''' parse an expression as declaration; e.g. "int *x[8]" when treated as expression will be parsed as `PrefixExpr(op='*', expr=Index(array='x', index=8))`, which we want to transform into this: `Array(Pointer(typ='int'), cap=8)` ''' while is_type_modifier(e): if type(e) == ast.Index: cap = int(e.index.val) if e.index is not None else None typ = ast.Array(typ=typ, cap=cap) e = e.array else: typ = ast.Pointer(typ=typ) e = e.expr if type(e) == ast.CallExpr: return self.parse_declr_expr( ast.Function(ret=typ or 'void', args=e.args, body=None), e.func) else: return ast.Declaration(typ=typ, name=e) def ctype(self): if self.accept('struct'): typ = self.struct() elif type(self.tok) == Symbol: if self.tok.typ not in prim_types: self.error("Invalid type '%s'"% self.tok.typ) typ = self.tok.typ self.advance() else: self.error() return typ def declaration(self): ''' parse delcaration ''' self.parsing_declr = True base_typ = self.ctype() if type(base_typ) == ast.Struct and self.accept(';'): return base_typ; declr_expr = self.expression() if type(declr_expr) == ast.ChainExpr: self.error("Multi-declaration not supported") declr = self.parse_declr_expr(base_typ, declr_expr) self.parsing_declr = False if self.accept('='): self.advance(); val = self.expression() return ast.DeclrAssign(declr, val) else: return declr def is_declaration(self): ''' helper function to tell if a statement is a declaration ''' is_dec = False if self.accept('IDENT'): lookahead = self.peek() is_dec = lookahead.is_('*') or lookahead.is_('IDENT') elif type(self.tok) == Symbol: is_dec = self.tok.typ in prim_types or self.tok.typ == 'struct' return is_dec def for_(self): self.expect('for') self.expect('(') init = cond = cont = None if not self.accept(';'): init = self.expression() self.expect(';') else: self.advance() if not self.accept(';'): cond = self.expression() self.expect(';') else: self.advance() if not self.accept(')'): cont = self.expression() self.expect(')') else: self.advance() body = self.statement() return ast.For(init, cond, cont, body) def while_(self): self.expect('while') self.expect('(') cond = self.expression() self.expect(')') body = self.statement() return ast.While(cond, body) def if_(self): self.expect('if') self.expect('(') cond = self.expression() self.expect(')') conseq = self.statement() alt = None if self.accept('else'): self.advance() alt = self.statement() return ast.If(cond, conseq, alt) def parse_function(self, declr): func = declr.typ return ast.Declaration( typ=ast.Function( ret=func.ret, args=func.args, body=self.block()), name=declr.name) def return_(self): self.expect('return') ret_val = None if not self.accept(';'): ret_val = self.expression() self.expect(';') return ast.Return(ret_val) def statement(self, is_global=False): if self.accept(';'): self.advance() return ast.EmptyStmt() elif self.accept('return'): return self.return_() elif self.accept('break'): self.advance() brk = ast.Break() self.expect(';') return brk elif self.accept('continue'): self.advance() cont = ast.Continue() self.expect(';') return cont elif self.accept('{'): return self.block() elif self.accept('for'): return self.for_() elif self.accept('while'): return self.while_() elif self.accept('if'): return self.if_() elif self.is_declaration(): declr = self.declaration() if (type(declr) == ast.Declaration and type(declr.typ) == ast.Function and self.accept('{')): return self.parse_function(declr) else: self.expect(';') return declr else: expr = self.expression() self.expect(';') return expr def block(self): self.expect('{') stmts = [] while not self.accept('}'): stmts.append(self.statement()) self.expect('}') return ast.Block(stmts) def arg_list(self): self.expect('(') args = [] while not self.accept(')'): typ = self.ctype() name = self.name() args.append(ast.Declaration(name, typ)) if not self.accept(')'): self.expect(',') self.expect(')') return args def struct(self): self.expect('struct') name = None fields = None if self.accept('IDENT'): name = self.tok self.advance() if self.accept('{'): fields = [] self.expect('{') while not self.accept('}'): field = self.declaration() if type(field) != ast.Declaration: self.error() fields.append(field) if not self.accept('}'): self.expect(';') self.expect('}') if name is None: self.error("Anonymous sturct unsupported") return ast.Struct(name, tuple(fields) if fields is not None else None) def program(self): declrs = [] while not self.eof: declrs.append(self.statement()) return declrs
class Parser(): def __init__(self, filename): self.file = open(filename) self.pending = None self.lexer = Lexer(self.file) def fatal(self, problem, line): print("LINE: " + str(line) + "\nERROR: " + problem) exit(1) def parse(self): # print("In parse") self.advance() root = self.program() eof = self.match("END_OF_INPUT") return self.cons("PARSE", root, eof) # print("Done") def check(self, t): # print("Check: "+self.pending.ltype+" vs "+t) return self.pending.ltype == t def advance(self): # print("In advance") old = self.pending self.pending = self.lexer.lex() # print("New Lexeme is "+self.pending.ltype) return old def match(self, t): # print("Match: "+t) if (self.check(t)): # print("Token: "+str(self.pending)) return self.advance() self.fatal( "Syntax Error. Expected " + str(t) + " , Received " + str(self.pending.lvalue), self.lexer.lineNumber) def cons(self, value, left, right): return Lexeme(value, value, left, right) # ============================================================================= # GRAMMAR PORTION OF THE PARSING CLASS # ============================================================================= # program : definition # | definition program def program(self): # print("In program") d = self.definition() if (self.programPending()): p = self.program() return self.cons("PROGRAM", d, self.cons("JOIN", p, None)) return self.cons("PROGRAM", d, None) # definition : variableDefinition # | functionDefinition # | idDef SEMI def definition(self): # print("In definition") if (self.variableDefinitionPending()): v = self.variableDefinition() return self.cons("DEFINITION", v, None) elif (self.functionDefinitionPending()): f = self.functionDefinition() return self.cons("DEFINITION", f, None) # variableDefinition : VAR ID EQUAL expr SEMI def variableDefinition(self): # print("In variableDefinition") v = self.match("VAR") i = self.match("ID") eq = self.match("EQUAL") e = self.expr() s = self.match("SEMI") return self.cons( "VARDEF", v, self.cons( "JOIN", i, self.cons("JOIN", eq, self.cons("JOIN", e, self.cons("JOIN", s, None))))) # functionDefinition : FUNCTION ID OPAREN optParamList CPAREN block def functionDefinition(self): # print("In functionDefinition") f = self.match("FUNCTION") e = self.match("ID") o = self.match("OPAREN") op = self.optParamList() c = self.match("CPAREN") b = self.block() return self.cons( "FUNCDEF", f, self.cons( "JOIN", e, self.cons( "JOIN", o, self.cons("JOIN", op, self.cons("JOIN", c, self.cons("JOIN", b, None)))))) # idDef : ID # | ID OPAREN optExprList CPAREN # | ID OBRACKET expr CBRACKET def idDef(self): # print("In idDef") i = self.match("ID") if (self.check("OPAREN")): o = self.match("OPAREN") e = self.optExprList() c = self.match("CPAREN") return self.cons( "FUNCCALL", i, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) elif (self.check("OBRACKET")): o = self.match("OBRACKET") e = self.expr() c = self.match("CBRACKET") return self.cons( "ARRAYACCESS", i, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) else: return self.cons("IDDEF", i, None) # optParamList : EMPTY # | paramList def optParamList(self): # print("In optParamList") if (self.paramListPending()): p = self.paramList() return self.cons("OPTPARAMLIST", p, None) return self.cons("OPTPARAMLIST", None, None) # paramList : ID # | ID COMMA paramList def paramList(self): # print("In paramList") i = self.match("ID") if (self.check("COMMA")): c = self.match("COMMA") p = self.paramList() return self.cons("PARAMLIST", i, self.cons("JOIN", c, self.cons("JOIN", p, None))) return self.cons("PARAMLIST", i, None) # optExprList : EMPTY # | exprList def optExprList(self): # print("In optExprList") if (self.exprListPending()): e = self.exprList() return self.cons("OPTEXPRLIST", e, None) return self.cons("OPTEXPRLIST", None, None) # exprList : expr # | expr COMMA exprList def exprList(self): # print("In exprList") e = self.expr() if (self.check("COMMA")): c = self.match("COMMA") ex = self.exprList() return self.cons("EXPRLIST", e, self.cons("JOIN", c, self.cons("JOIN", ex, None))) return self.cons("EXPRLIST", e, None) # expr : primary # | primary operator expr def expr(self): # print("In expr") p = self.primary() if (self.operatorPending()): o = self.operator() e = self.expr() return Lexeme("EXPR", "EXPR", Lexeme("OPERATOR", o, p, e)) return self.cons("EXPR", p, None) # primary : idDef # | STRING # | INTEGER # | NOT primary # | OPAREN expr CPAREN # | k_lambda # | functionDefinition # | OBRACKET optExprList CBRACKET # | NIL # | BOOLEAN # | PRINT OPAREN exprList CPAREN # | APPEND OPAREN exprList CPAREN # | REMOVE OPAREN exprList CPAREN # | SET OPAREN exprList CPAREN # | LENGTH OPAREN exprList CPAREN def primary(self): # print("In primary") if (self.idDefPending()): p = self.idDef() return self.cons("PRIMARY", p, None) elif (self.check("STRING")): p = self.match("STRING") return self.cons("PRIMARY", p, None) elif (self.check("INTEGER")): p = self.match("INTEGER") return self.cons("PRIMARY", p, None) elif (self.check("NOT")): n = self.match("NOT") p = self.primary() return self.cons("PRIMARY", n, self.cons("JOIN", p, None)) elif (self.check("OPAREN")): o = self.match("OPAREN") e = self.expr() c = self.match("CPAREN") return self.cons("PRIMARY", o, self.cons("JOIN", e, self.cons("JOIN", c, None))) elif (self.k_lambdaPending()): p = self.k_lambda() return self.cons("PRIMARY", p, None) elif (self.functionDefinitionPending()): p = self.functionDefinition() return self.cons("PRIMARY", p, None) elif (self.check("OBRACKET")): o = self.match("OBRACKET") e = self.optExprList() c = self.match("CBRACKET") return self.cons("PRIMARY", o, self.cons("JOIN", e, self.cons("JOIN", c, None))) elif (self.check("NIL")): n = self.match("NIL") return self.cons("PRIMARY", n, None) elif (self.check("BOOLEAN")): b = self.match("BOOLEAN") return self.cons("PRIMARY", b, None) elif (self.check("PRINT")): f = self.match("PRINT") o = self.match("OPAREN") e = self.exprList() c = self.match("CPAREN") return self.cons( "PRINT", f, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) elif (self.check("APPEND")): f = self.match("APPEND") o = self.match("OPAREN") e = self.exprList() c = self.match("CPAREN") return self.cons( "APPEND", f, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) elif (self.check("INSERT")): f = self.match("INSERT") o = self.match("OPAREN") e = self.exprList() c = self.match("CPAREN") return self.cons( "INSERT", f, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) elif (self.check("REMOVE")): f = self.match("REMOVE") o = self.match("OPAREN") e = self.exprList() c = self.match("CPAREN") return self.cons( "REMOVE", f, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) elif (self.check("SET")): f = self.match("SET") o = self.match("OPAREN") e = self.exprList() c = self.match("CPAREN") return self.cons( "SET", f, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) elif (self.check("LENGTH")): f = self.match("LENGTH") o = self.match("OPAREN") e = self.exprList() c = self.match("CPAREN") return self.cons( "LENGTH", f, self.cons("JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, None)))) # operator : EQUAL # | NOTEQUAL # | GREATER # | LESS # | GREATEREQUAL # | LESSEQUAL # | PLUS # | MINUS # | MULTIPLY # | DIVIDE # | INTEGERDIVIDE # | POWER # | AND # | OR # | DOUBLEEQUAL def operator(self): # print("In operator") if (self.check("EQUAL")): op = self.match("EQUAL") return self.cons("EQUAL", op, None) elif (self.check("NOTEQUAL")): op = self.match("NOTEQUAL") return self.cons("NOTEQUAL", op, None) elif (self.check("GREATER")): op = self.match("GREATER") return self.cons("GREATER", op, None) elif (self.check("LESS")): op = self.match("LESS") return self.cons("LESS", op, None) elif (self.check("GREATEREQUAL")): op = self.match("GREATEREQUAL") return self.cons("GREATEREQUAL", op, None) elif (self.check("LESSEQUAL")): op = self.match("LESSEQUAL") return self.cons("LESSEQUAL", op, None) elif (self.check("PLUS")): op = self.match("PLUS") return self.cons("PLUS", op, None) elif (self.check("MINUS")): op = self.match("MINUS") return self.cons("MINUS", op, None) elif (self.check("MULTIPLY")): op = self.match("MULTIPLY") return self.cons("MULTIPLY", op, None) elif (self.check("DIVIDE")): op = self.match("DIVIDE") return self.cons("DIVIDE", op, None) elif (self.check("INTEGERDIVIDE")): op = self.match("INTEGERDIVIDE") return self.cons("INTEGERDIVIDE", op, None) elif (self.check("POWER")): op = self.match("POWER") return self.cons("POWER", op, None) elif (self.check("AND")): op = self.match("AND") return self.cons("AND", op, None) elif (self.check("OR")): op = self.match("OR") return self.cons("OR", op, None) elif (self.check("ASSIGN")): op = self.match("ASSIGN") return self.cons("ASSIGN", op, None) elif (self.check("DOUBLEEQUAL")): op = self.match("DOUBLEEQUAL") return self.cons("DOUBLEEQUAL", op, None) # block : OBRACE optStatementList CBRACE def block(self): # print("In block") o = self.match("OBRACE") s = self.optStatementList() c = self.match("CBRACE") return self.cons("BLOCK", o, self.cons("JOIN", s, self.cons("JOIN", c, None))) # optStatementList : EMPTY # | statementList def optStatementList(self): # print("In optStatementList") if (self.statementListPending()): s = self.statementList() return self.cons("OPTSTATEMENTLIST", s, None) return self.cons("OPTSTATEMENTLIST", None, None) # statementList : statement # | statement statementList def statementList(self): # print("In statementList") s = self.statement() if (self.statementListPending()): sl = self.statementList() return self.cons("STATEMENTLIST", s, self.cons("JOIN", sl, None)) return self.cons("STATEMENTLIST", s, None) # statement : variableDefinition # | functionDefinition # | expr SEMI # | whileLoop # | ifStatement # | RETURN expr SEMI def statement(self): # print("In statement") if (self.variableDefinitionPending()): v = self.variableDefinition() return self.cons("STATEMENT", v, None) elif (self.functionDefinitionPending()): f = self.functionDefinition() return self.cons("STATEMENT", f, None) elif (self.exprPending()): e = self.expr() s = self.match("SEMI") return self.cons("STATEMENT", e, self.cons("JOIN", s, None)) elif (self.whileLoopPending()): w = self.whileLoop() return self.cons("STATEMENT", w, None) elif (self.ifStatementPending()): i = self.ifStatement() return self.cons("STATEMENT", i, None) elif (self.check("RETURN")): r = self.match("RETURN") e = self.expr() s = self.match("SEMI") return self.cons("STATEMENT", r, self.cons("JOIN", e, self.cons("JOIN", s, None))) # whileLoop : WHILE OPAREN expr CPAREN block def whileLoop(self): # print("In whileLoop") w = self.match("WHILE") o = self.match("OPAREN") e = self.expr() c = self.match("CPAREN") b = self.block() return self.cons( "WHILELOOP", w, self.cons( "JOIN", o, self.cons("JOIN", e, self.cons("JOIN", c, self.cons("JOIN", b, None))))) # ifStatement : IF OPAREN expr CPAREN block optElseStatement def ifStatement(self): # print("In ifStatement") i = self.match("IF") o = self.match("OPAREN") e = self.expr() c = self.match("CPAREN") b = self.block() oe = self.optElseStatement() return self.cons( "IFSTATEMENT", i, self.cons( "JOIN", o, self.cons( "JOIN", e, self.cons( "JOIN", c, self.cons("JOIN", b, self.cons("JOIN", oe, None)))))) # optElseStatement : EMPTY # | elseStatement def optElseStatement(self): # print("In optElseStatement") if (self.elseStatementPending()): e = self.elseStatement() return self.cons("OPTELSESTATEMENT", e, None) return self.cons("OPTELSESTATEMENT", None, None) # elseStatement : ELSE block # | ELSE ifStatement def elseStatement(self): # print("In elseStatement") e = self.match("ELSE") if (self.blockPending()): b = self.block() return self.cons("ELSESTATEMENT", e, self.cons("JOIN", b, None)) elif (self.ifStatementPending()): i = self.ifStatement() return self.cons("ELSESTATEMENT", e, self.cons("JOIN", i, None)) # k_lambda : LAMBDA OPAREN optParamList CPAREN block def k_lambda(self): # print("In k_lambda") l = self.match("LAMBDA") o = self.match("OPAREN") op = self.optParamList() c = self.match("CPAREN") b = self.block() return self.cons( "LAMBDA", l, self.cons( "JOIN", o, self.cons("JOIN", op, self.cons("JOIN", c, self.cons("JOIN", b, None))))) # ============================================================================= # Pending Statements # ============================================================================= def programPending(self): # print("In programPending") return self.definitionPending() def definitionPending(self): # print("In definitionPending") return self.variableDefinitionPending( ) or self.functionDefinitionPending() or self.idDefPending() def variableDefinitionPending(self): # print("In variableDefinitionPending") return self.check("VAR") def functionDefinitionPending(self): # print("In functionDefinitionPending") return self.check("FUNCTION") def idDefPending(self): # print("In idDefPending") return self.check("ID") def paramListPending(self): # print("In paramListPending") return self.check("ID") def exprListPending(self): # print("In exprListPending") return self.exprPending() def exprPending(self): # print("In exprPending") return self.primaryPending() def primaryPending(self): # print("In primaryPending") return self.idDefPending() or self.check("STRING") or self.check( "INTEGER" ) or self.check("NOT") or self.check("OPAREN") or self.k_lambdaPending( ) or self.functionDefinitionPending() or self.check( "OBRACKET") or self.check("NIL") or self.check( "BOOLEAN") or self.check("PRINT") or self.check( "APPEND") or self.check("INSERT") or self.check( "REMOVE") or self.check("SET") or self.check("LENGTH") def operatorPending(self): # print("In operatorPending") return self.check("EQUAL") or self.check("NOTEQUAL") or self.check( "GREATER") or self.check("LESS") or self.check( "GREATEREQUAL") or self.check("LESSEQUAL") or self.check( "PLUS") or self.check("MINUS") or self.check( "MULTIPLY") or self.check("DIVIDE") or self.check( "INTEGERDIVIDE") or self.check( "POWER") or self.check("AND") or self.check( "OR") or self.check( "ASSIGN") or self.check("DOUBLEEQUAL") def blockPending(self): # print("In blockPending") return self.check("OBRACE") def statementListPending(self): # print("In statementListPending") return self.statementPending() def statementPending(self): # print("In statementPending") return self.variableDefinitionPending( ) or self.functionDefinitionPending() or self.exprPending( ) or self.whileLoopPending() or self.ifStatementPending( ) or self.check("RETURN") def whileLoopPending(self): # print("In whileLoopPending") return self.check("WHILE") def ifStatementPending(self): # print("In ifStatementPending") return self.check("IF") def elseStatementPending(self): # print("In elseStatementPending") return self.check("ELSE") def k_lambdaPending(self): # print("In k_lambdaPending") return self.check("LAMBDA")
def scanner(file): lexer = Lexer(file) pending = lexer.lex() while (pending.ltype != "END_OF_INPUT"): print(pending) pending = lexer.lex()