def test1(): input = "LET foobar = 123" lexer = Lexer(input) while lexer.peek() != '\0': print(lexer.curChar) lexer.nextChar()
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 test2(): input = "+- */" lexer = Lexer(input) token = lexer.getToken() print(token) while token.kind != TokenType.EOF: print(token.kind) token = lexer.getToken()
def __init__(self, source_code, productions, actions, gotos): self.productions = productions self.actions = actions self.gotos = gotos self.stack = Stack() self.lexer = Lexer(source_code) self.trees = [] self._is_accepted = False
def main(): argparser = argparse.ArgumentParser(description="Generate an AST DOT file.") argparser.add_argument("fname", help="Pascal source file") args = argparser.parse_args() fname = args.fname text = open(fname, "r").read() lexer = Lexer(text) parser = Parser(lexer) viz = ASTVisualizer(parser) content = viz.gendot() print(content)
def main(): print("Mini Java Compiler") if len(sys.argv) < 2: sys.exit("Error: Compiler needs source file as argument.") with pathlib.Path(sys.argv[1]).resolve().open(mode="r") as f: buffer = f.read() target_dir = pathlib.Path(__file__).parent.joinpath("../dumps") target_dir.mkdir(parents=True, exist_ok=True) print(f"{'':-<50}\nLexer Test") lexer = Lexer(buffer) with target_dir.joinpath("./tokens.txt").open("w") as f: print(f"{'Position':10}{'Stream':<10}{'Token name':20}{'Value':20}", file=f) for token in lexer.tokens(): print(token, file=f) print("Lexing completed.") print(f"{'':-<50}\nSymbol Table Test") symtable = SymbolTable(lexer) with target_dir.joinpath("./symtable.json").open("w") as f: json.dump(symtable.data, f, indent=4) print("Symbol table completed.") print(f"{'':-<50}\nParser Test") parser = Parser(lexer) ast = parser.program() print("Parsing completed.") print(f"{'':-<50}\nCode Generator Test") code_gen = CodeGen(ast) code = code_gen.generate_code() with target_dir.joinpath("./output.c").open("w") as f: print(code, file=f) print("Code generation completed.")
def main(): print("Teeny tiny compiler") if len(sys.argv) != 2: sys.exit("Error: Compiler needs source file as argument") with open(sys.argv[1], 'r') as inputFile: input = inputFile.read() # Initialize lexer and parser lexer = Lexer(input) parser = Parser(lexer) parser.program() # Start the parser print('Parsing completed')
def __init__(self, lexer: _Lexer): """SymbolTable constructor. Takes lexer or tokens argument to get the collection of tokens. Prioritizes parser if both are provided. Args: lexer: The lexer for generating collections of token. """ super().__init__() self.__tokens = lexer.tokens() self.__current_token = None self.__next_token = None self._advance() self._advance() self._generate()
def __init__(self, fileName, cFile): self.e = Error(fileName) self.nodeStack = [] self.fileName = fileName self.grammar = Grammar(open(fileName).read()) self.dfa = DFA(self.grammar) self.stack = [("DummySymbol", self.dfa.startState)] self.lexer = Lexer(cFile, cFile + ".lex") """ This bit's going to go away soon self.lexed = self.lexer.lexed self.lexed = [x for x in self.lexed.split("\n") if x != ''] self.lexed = [eval(x) for x in self.lexed] """ self.lexed = self.lexer.lexedList self.action = [] self.terminals = self.grammar.terminals self.actions = {} # construct action table for state in self.dfa.transitionTable: self.actions[state] = {} for on in self.dfa.transitionTable[state]: self.actions[state][on] = ("error") self.actions[state]["$"] = ("error") for state in self.dfa.transitionTable: if "DummyStart -> " + self.grammar.startSymbol + " " + itemSeparator in state: if state not in self.actions: self.actions[state] = {"$" : ("accept")} else: self.actions[state]["$"] = ("accept") for transition in self.dfa.transitionTable[state]: actionState = self.dfa.goto(state, transition) if any([itemSeparator + " " + transition in x for x in state]) and actionState is not None: if state not in self.actions: self.actions[state] = {transition : ("shift", actionState)} else: self.actions[state][transition] = ("shift", actionState) if any([x[-1] == itemSeparator for x in state]): matches = [x for x in state if x[-1] == itemSeparator] matches = [x for x in matches if transition in self.grammar.getFollowSet(x.partition(" ")[0])] for match in matches: if match.partition(" ")[0] != "DummyStart": reduceNum = len([x for x in match.partition(" -> ")[2].split(" ") if x != itemSeparator]) if state not in self.actions: self.actions[state] = {transition : ("reduce", match.partition(" ")[0], transition, reduceNum)} else: self.actions[state][transition] = ("reduce", match.partition(" ")[0], transition, reduceNum)
def main(): parser = argparse.ArgumentParser( description="SPI - Simple Pascal Interpreter") parser.add_argument("inputfile", help="Pascal source file") parser.add_argument( "--scope", help="Print scope information", action="store_true", ) parser.add_argument( "--stack", help="Print call stack", action="store_true", ) args = parser.parse_args() global _SHOULD_LOG_SCOPE, _SHOULD_LOG_STACK _SHOULD_LOG_SCOPE, _SHOULD_LOG_STACK = args.scope, args.stack text = open(args.inputfile, "r").read() # print(text) lexer = Lexer(text) try: parser = Parser(lexer) tree = parser.parse() except (LexerError, ParserError) as e: print(e.message) sys.exit(1) semantic_analyzer = SemanticAnalyzer(_SHOULD_LOG_SCOPE) try: semantic_analyzer.visit(tree) except SemanticError as e: print(e.message) sys.exit(1) interpreter = Interpreter() interpreter.interpret(tree)
def __init__(self, filename): self.file = open(filename) self.pending = None self.lexer = Lexer(self.file)
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")
def __init__(self, **kwargs): self.totalLines = 0 self.result = True self.lexer = Lexer() self.parser = yacc.yacc(module=self, **kwargs)
import sys import ply.yacc as yacc from lex import Lexer tokens = Lexer().tokens replacement = ['JZERO', 'JNEG', 'JPOS', 'JUMP'] variables = {} # contains var name and address arrays = {} # contains array name and its address initialized_variables = set() # contains already initialized vars current_instruction = 0 temp_vars = set() register_number = 1 # memory counter ######################################################################################################################## # Declaring 10 temporary registers ######################################################################################################################## # program -> DECLARE declarations BEGIN commands END # 2 | BEGIN commands END ######################################################################################################################## def p_program_with_libs(p): 'program : DECLARE declarations BEGIN commands END' p[0] = str(p[4][0]) + '\nHALT' def p_program_without_libs(p): 'program : BEGIN commands END' p[0] = p[2][0] + '\nHALT'
||| SUMMARY: ||| A simple lexical analyzer that uses an external, ||| simple-format, file for definitions and the respective ||| tokens. Input file can then be specified for checking ||| language against language definition. Output can be ||| presented via print() method or write(filename) method. """ from lex import Lexer yesAnswers = ["y", "yes", "YES", "Yes"] # Run loop by default while True: # Let user choose file for rule definitions ruleDef = input("Enter rules file for definitions: ") lex = Lexer(ruleDef) lex.setRules() # Let user choose input file to be analyzed inputFile = input("Choose code file to read: ") lex.analyze(inputFile) # User response to prompt for output type answer = input("Enter 'print' to output to console, otherwise enter output file name: ") if answer == "print": lex.print() else: lex.writeToFile(answer) # Break loop if user does not wish to read another file answer = input("Analyze another file? ")
class Parser: tokens = Lexer().tokens def __init__(self): pass def p_program(self, p): """program : declist MAIN LRB RRB block""" print("program : declist MAIN LRB RRB block" ) #dghighan mesle fili ke gozashtin def p_decli_version1(self, p): """declist : dec""" print("declist : dec ") # type1 def p_decli_version2(self, p): """declist : declist dec""" print("declist : declist ") # type2 def p_decli_version3(self, p): """declist : empty""" print("declist : empty ") # type3 def p_decversion1(self, p): """dec : vardec """ print("""dec : vardec """) def p_decversion2(self, p): """dec : funcdec """ print("""dec : funcdec """) def p_type1(self, p): """type : INTEGER""" print("""type : INTEGERNUMBER""") def p_type2(self, p): """type : FLOAT""" print("""type : FLOAT""") def p_type3(self, p): """type : BOOLEAN""" print("""type : BOOLEAN""") def p_iddec_version1(self, p): """iddec : ID""" print("""iddec : ID""") def p_iddec1_version2(self, p): """iddec : ID LSB exp RSB""" print("""ID LSB exp RSB""") def p_iddec1_version3(self, p): """iddec : ID ASSIGN exp""" print("""iddec : ID ASSIGN exp""") def p_idlist_version1(self, p): """idlist : iddec""" print("""idlist : iddec""") def p_idlist_version2(self, p): """idlist : idlist COMMA iddec""" print("""idlist : idlist COMMA iddec""") def p_vardec(self, p): """vardec : type idlist SEMICOLON""" print("""vardec : type idlist SEMICOLON""") #semicolen ham dashterror def p_funcdec_vesrion1(self, p): """funcdec : type ID LRB paramdecs RRB block""" print("""funcdec : type ID LRB paramdecs RRB block""") def p_funcdec_version2(self, p): """funcdec : VOID ID LRB paramdecs RRB block""" print("""funcdec : VOID ID LRB paramdecs RRB block""") def p_paramdecs_vesrion1(self, p): """paramdecs : paramdecslist""" print("""paramdecs : paramdecslist""") def p_paramdecs_version2(self, p): """paramdecs : empty""" print("""paramdecs : empty""") def p_paramdecslist_vesrion1(self, p): """paramdecslist : paramdec""" print("""paramdecslist : paramdec""") def p_paramdecslist_vesrion2(self, p): """paramdecslist : paramdecslist COMMA paramdec""" print("""paramdecslist : paramdecslist COMMA paramdec""") def p_paramdec_vesrion1(self, p): """paramdec : type ID""" print("""paramdec : type ID""") def p_paramdec_version2(self, p): """paramdec : type ID LSB RSB""" print("""paramdec : type ID LSB RSB""") def p_varlist_version1(self, p): """varlist : vardec""" print("""varlist : vardec""") def p_varlist_version2(self, p): """varlist : varlist vardec""" print("""varlist : varlist vardec """) def p_varlist_version3(self, p): """varlist : empty""" print("""varlist : empty""") def p_block(self, p): """block : LCB varlist stmtlist RCB""" print("block : LCB varlist stmtlist RCB") def p_stmtlist_version1(self, p): """stmtlist : stmt""" print("""stmtlist : stmt""") def p_stmtlist_version2(self, p): """stmtlist : stmtlist stmt""" print("""stmtlist : stmtlist stmt""") def p_stmtlist_version3(self, p): """stmtlist : empty""" print("""stmtlist : empty""") def p_lvalue_version1(self, p): """lvalue : ID""" print("""lvalue : ID""") def p_lvalue_version2(self, p): """lvalue : ID LSB exp RSB""" print("""lvalue : ID LSB exp RSB""") def p_stmt_version1(self, p): """stmt : matched_stmt""" print("""stmt : matched_stmt""" ) #shyd mohemtrin bakhsh taghsim kedn be match va unmached bshe def p_stmt_version2(self, p): """stmt : unmatched_stmt""" print("""stmt : unmatched_stmt""") def p_stmt_matched_version1(self, p): """matched_stmt : IF LRB exp RRB matched_stmt elseiflist ELSE matched_stmt %prec IF_D""" print( """matched_stmt : IF LRB exp RRB matched_stmt elseiflist ELSE matched_stmt""" ) #if ghbol nmird def p_stmt_matched_version2(self, p): """matched_stmt : everythingthatcanhappen""" print("""matched_stmt : everythingthatcanhappen(other)""") def p_stmt_unmatched_version1(self, p): """unmatched_stmt : IF LRB exp RRB matched_stmt elseiflist %prec IF_D""" print("""unmatched_stmt : IF LRB exp RRB stmt elseiflist""") def p_stmt_unmatched_version2(self, p): """unmatched_stmt : IF LRB exp RRB matched_stmt elseiflist ELSE unmatched_stmt %prec IF_D""" print( """unmatched_stmt : IF LRB exp RRB matched_stmt elseiflist ELSE unmatched_stmt""" ) def p_stmt_others_version1(self, p): """everythingthatcanhappen : RETURN exp SEMICOLON""" print("""everythingthatcanhappen : RETURN exp SEMICOLON""") def p_stmt_others_version2(self, p): """everythingthatcanhappen : exp SEMICOLON""" print("""everythingthatcanhappen : exp SEMICOLON""") def p_stmt_others_version3(self, p): """everythingthatcanhappen : block""" print("""everythingthatcanhappen : block""") def p_stmt_others_version4(self, p): """everythingthatcanhappen : WHILE LRB exp RRB stmt""" print(""" WHILE LRB exp RRB stmt""") def p_stmt_others_version5(self, p): """everythingthatcanhappen : FOR LRB exp SEMICOLON exp SEMICOLON exp RRB stmt""" print( """everythingthatcanhappen : FOR LRB exp SEMICOLON exp SEMICOLON exp RRB stmt""" ) def p_stmt_others_version6(self, p): """everythingthatcanhappen : PRINT LRB ID RRB SEMICOLON""" print("""everythingthatcanhappen : PRINT LRB ID RRB SEMICOLON""") def p_elseiflist_version1(self, p): """elseiflist : ELIF LRB exp RRB stmt""" print("""elseiflist : ELIF LRB exp RRB stmt""") def p_elseiflist_version2(self, p): """elseiflist : elseiflist ELIF LRB exp RRB stmt""" print("""elseiflist : elseiflist ELIF LRB exp RRB stmt""") def p_elseiflist_version3(self, p): """elseiflist : empty""" print("""elseiflist : empty""") def p_exp_version1(self, p): """exp : lvalue ASSIGN exp""" print("""exp : lvalue ASSIGN exp""") def p_exp_version2(self, p): """exp : exp operator exp %prec OP""" print("""exp : exp operator exp""") def p_exp_version3(self, p): """exp : exp relop exp %prec RELOP""" print("""exp : exp relop exp""") def p_exp_version5(self, p): """exp : const""" print("""exp : const""") def p_exp_version6(self, p): """exp : lvalue""" print("""exp : lvalue """) def p_exp_version7(self, p): """exp : ID LRB explist RRB""" print("""exp : ID LRB explist RRB""") def p_exp_version8(self, p): """exp : LRB exp RRB""" print("""exp : LRB exp RRB""") def p_exp_version9(self, p): """exp : ID LRB RRB""" print("""exp : ID LRB RRB""") def p_exp_version10(self, p): """exp : SUB exp %prec UMINUS""" print("""exp : SUB exp""") def p_exp_version11(self, p): """exp : NOT exp""" print("""exp : NOT exp""") def p_operator_version1(self, p): """operator : OR""" print("""operator : OR""") def p_operator_version2(self, p): """operator : AND""" print("""operator : AND""") def p_operator_version3(self, p): """operator : SUM""" print("""operator : SUM""") def p_operator_version4(self, p): """operator : SUB""" print("""operator : SUB""") # def p_operator_version5(self, p): # """operator : MUL""" # print("""operator : MUL""") def p_operator_version6(self, p): """operator : MUL""" print("""operator : MUL""") def p_operator_version7(self, p): """operator : DIV""" print("""operator : DIV""") def p_operator_version8(self, p): """operator : MOD""" print("""operator : MOD""") def p_const_version1(self, p): """const : INTEGERNUMBER""" print("""const : INTEGERNUMBER""") def p_const_version2(self, p): """const : FLOATNUMBER""" print("""const : FLOATNUMBER""") def p_const_version3(self, p): """const : TRUE""" print("""const : TRUE""") def p_const_version4(self, p): """const : FALSE""" print("""const : FALSE""") def p_relop_version1(self, p): """relop : GT""" print("""relop : GT""") def p_relop_version2(self, p): """relop : LT""" print("""relop : LT""") def p_relop_version3(self, p): """relop : NE""" print("""relop : NE""") def p_relop_version4(self, p): """relop : EQ""" print("""relop : EQ""") def p_relop_version5(self, p): """relop : LE""" print("""relop : LE""") def p_relop_version6(self, p): """relop : GE""" print("""relop : GE""") def p_explist_version1(self, p): """explist : exp""" print("""explist : exp""") def p_explist_version2(self, p): """explist : explist COMMA exp""" print("""explist: explist COMMA exp""") def p_empty(self, p): """empty : %prec EMPTY""" pass precedence = ( ('nonassoc', 'EMPTY'), #olaviate bala akhrin olaviuat ('nonassoc', 'IF_D'), ('nonassoc', 'ELIF'), ('nonassoc', 'ELSE'), ('nonassoc', 'RELOP'), ('nonassoc', 'OP'), ('left', 'COMMA'), ('right', 'ASSIGN'), ('left', 'OR'), ('left', 'AND'), ('left', 'EQ', 'NE'), ('left', 'GT', 'LT', 'GE', 'LE'), ('left', 'SUM', 'SUB'), ('left', 'MUL', 'DIV', 'MOD'), ('right', 'NOT'), ('right', 'UMINUS')) def p_error(self, p): print(p.value) raise Exception('ParsingError: invalid grammar at ', p) def build(self, **kwargs): """build the parser""" self.parser = yacc.yacc(module=self, **kwargs) return self.parser
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")
def __init__(self, gramma): self.gl = Glex(open(gramma).read()) self.lexer = Lexer() self.classes = [] self.rules = {}
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")
def scanner(file): lexer = Lexer(file) pending = lexer.lex() while (pending.ltype != "END_OF_INPUT"): print(pending) pending = lexer.lex()
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")
import re from lex import Lexer if __name__ == '__main__': lexer = Lexer().build() file = open('test1.txt') text_input = file.read() file.close() lexer.input(text_input) while True: tok = lexer.token() if not tok: break print(tok)
class Parser(): # Tokens do processo de análise léxica tokens = Lexer.tokens def __init__(self, **kwargs): self.totalLines = 0 self.result = True self.lexer = Lexer() self.parser = yacc.yacc(module=self, **kwargs) def f_column(self, token, pos): input = token.lexer.lexdata line_start = input.rfind('\n', 0, token.lexpos(pos)) + 1 return (token.lexpos(pos) - line_start) + 1 def p_programa(self, p): ''' programa : lista_declaracoes ''' p[0] = Node('programa', value='programa', children=[p[1]]) def p_lista_declaracoes(self, p): ''' lista_declaracoes : lista_declaracoes declaracao | declaracao ''' if (len(p) == 3): p[0] = Node('lista_declaracoes', value='lista_declaracoes', children=[p[1], p[2]]) else: p[0] = Node('lista_declaracoes', value='lista_declaracoes', children=[p[1]]) def p_declaracao(self, p): ''' declaracao : declaracao_variaveis | inicializacao_variaveis | declaracao_funcao ''' p[0] = Node('declaracao', value='declaracao', children=[p[1]]) def p_declaracao_variaveis(self, p): ''' declaracao_variaveis : tipo DOIS_PONTOS lista_variaveis ''' p[0] = Node('declaracao_variaveis', value='declaracao_variaveis', children=[ p[1], Node(str(p[2]), value=str(p[2]), line=(p.lineno(2) - (self.totalLines - 1)), column=self.f_column(p, 2)), p[3] ]) def p_inicializacao_variaveis(self, p): ''' inicializacao_variaveis : atribuicao ''' p[0] = Node('inicializacao_variaveis', value='inicializacao_variaveis', children=[p[1]]) def p_lista_variaveis(self, p): ''' lista_variaveis : lista_variaveis VIRGULA var | var ''' if (len(p) == 4): p[0] = Node('lista_variaveis', value='lista_variaveis', children=[ p[1], Node(str(p[2]), value=str(p[2]), line=(p.lineno(2) - (self.totalLines - 1)), column=self.f_column(p, 2)), p[3] ]) else: p[0] = Node('lista_variaveis', value='lista_variaveis', children=[p[1]]) def p_var(self, p): ''' var : ID | ID indice ''' if (len(p) == 3): p[0] = Node('var', value='var', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)), p[2] ]) else: p[0] = Node('var', value='var', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)) ]) def p_indice(self, p): ''' indice : indice ABRE_COLCHETE expressao FECHA_COLCHETE | ABRE_COLCHETE expressao FECHA_COLCHETE ''' if (len(p) == 5): p[0] = Node('indice', value='indice', children=[ p[1], Node(str(p[2]), value=str(p[2]), line=(p.lineno(2) - (self.totalLines - 1)), column=self.f_column(p, 2)), p[3], Node(str(p[4]), value=str(p[4]), line=(p.lineno(4) - (self.totalLines - 1)), column=self.f_column(p, 4)) ]) else: p[0] = Node('indice', value='indice', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)), p[2], Node(str(p[3]), value=str(p[3]), line=(p.lineno(3) - (self.totalLines - 1)), column=self.f_column(p, 3)) ]) def p_tipo(self, p): ''' tipo : INTEIRO | FLUTUANTE ''' p[0] = Node('tipo', value='tipo', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)) ]) def p_declaracao_funcao(self, p): '''declaracao_funcao : tipo cabecalho | cabecalho''' if (len(p) == 3): p[0] = Node('declaracao_funcao', value='declaracao_funcao', children=[p[1], p[2]]) else: p[0] = Node('declaracao_funcao', value='declaracao_funcao', children=[p[1]]) def p_cabecalho(self, p): '''cabecalho : ID ABRE_PARENTESE lista_parametros FECHA_PARENTESE corpo FIM''' p[0] = Node('cabecalho', value='cabecalho', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)), Node(str(p[2]), value=str(p[2]), line=(p.lineno(2) - (self.totalLines - 1)), column=self.f_column(p, 2)), p[3], Node(str(p[4]), value=str(p[4]), line=(p.lineno(4) - (self.totalLines - 1)), column=self.f_column(p, 4)), p[5] ]) def p_lista_parametros(self, p): ''' lista_parametros : lista_parametros VIRGULA parametro | parametro | vazio ''' if (len(p) == 4): p[0] = Node('lista_parametros', value='lista_parametros', children=[ p[1], Node(str(p[2]), value=str(p[2]), line=(p.lineno(2) - (self.totalLines - 1)), column=self.f_column(p, 2)), p[3] ]) else: if (p[1] is not None): p[0] = Node('lista_parametros', value='lista_parametros', children=[p[1]]) else: p[0] = Node('lista_parametros', value='lista_parametros') def p_parametro(self, p): ''' parametro : tipo DOIS_PONTOS ID | parametro ABRE_COLCHETE FECHA_COLCHETE ''' p[0] = Node('parametro', value='parametro', children=[ p[1], Node(str(p[2]), value=str(p[2]), line=(p.lineno(2) - (self.totalLines - 1)), column=self.f_column(p, 2)), Node(str(p[3]), value=str(p[3]), line=(p.lineno(3) - (self.totalLines - 1)), column=self.f_column(p, 3)) ]) def p_corpo(self, p): ''' corpo : corpo acao | vazio ''' if (len(p) == 3): p[0] = Node('corpo', value='corpo', children=[p[1], p[2]]) else: p[0] = Node('corpo', value='corpo') def p_acao(self, p): ''' acao : expressao | declaracao_variaveis | se | repita | leia | escreva | retorna ''' p[0] = Node('acao', value='acao', children=[p[1]]) def p_se(self, p): ''' se : SE expressao ENTAO corpo FIM | SE expressao ENTAO corpo SENAO corpo FIM ''' if (len(p) == 6): p[0] = Node('condicional', value='condicional', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)), p[2], Node(str(p[3]), value=str(p[3]), line=(p.lineno(3) - (self.totalLines - 1)), column=self.f_column(p, 3)), p[4], Node(str(p[5]), value=str(p[5]), line=(p.lineno(5) - (self.totalLines - 1)), column=self.f_column(p, 5)) ]) else: p[0] = Node('condicional', value='condicional', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)), p[2], Node(str(p[3]), value=str(p[3]), line=(p.lineno(3) - (self.totalLines - 1)), column=self.f_column(p, 3)), p[4], Node(str(p[5]), value=str(p[5]), line=(p.lineno(5) - (self.totalLines - 1)), column=self.f_column(p, 5)), p[6], Node(str(p[7]), value=str(p[7]), line=(p.lineno(7) - (self.totalLines - 1)), column=self.f_column(p, 7)) ]) def p_repita(self, p): ''' repita : REPITA corpo ATE expressao ''' p[0] = Node('repita', value='repita', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)), p[2], Node(str(p[3]), value=str(p[3]), line=(p.lineno(3) - (self.totalLines - 1)), column=self.f_column(p, 3)), p[4] ]) def p_atribuicao(self, p): ''' atribuicao : var ATRIBUICAO expressao ''' p[0] = Node('atribuicao', value='atribuicao', children=[ p[1], Node(str(p[2]), value=str(p[2]), line=(p.lineno(2) - (self.totalLines - 1)), column=self.f_column(p, 2)), p[3] ]) def p_leia(self, p): ''' leia : LEIA ABRE_PARENTESE var FECHA_PARENTESE ''' p[0] = Node('leia', value='leia', children=[ Node(str(p[1]), value=str(p[2]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)), Node(str(p[2]), value=str(p[2]), line=(p.lineno(2) - (self.totalLines - 1)), column=self.f_column(p, 2)), p[3], Node(str(p[4]), value=str(p[4]), line=(p.lineno(4) - (self.totalLines - 1)), column=self.f_column(p, 4)) ]) def p_escreva(self, p): ''' escreva : ESCREVA ABRE_PARENTESE expressao FECHA_PARENTESE ''' p[0] = Node('escreva', value='escreva', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)), Node(str(p[2]), value=str(p[2]), line=(p.lineno(2) - (self.totalLines - 1)), column=self.f_column(p, 2)), p[3], Node(str(p[4]), value=str(p[4]), line=(p.lineno(4) - (self.totalLines - 1)), column=self.f_column(p, 4)) ]) def p_retorna(self, p): ''' retorna : RETORNA ABRE_PARENTESE expressao FECHA_PARENTESE ''' p[0] = Node('retorna', value='retorna', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)), Node(str(p[2]), value=str(p[2]), line=(p.lineno(2) - (self.totalLines - 1)), column=self.f_column(p, 2)), p[3], Node(str(p[4]), value=str(p[4]), line=(p.lineno(4) - (self.totalLines - 1)), column=self.f_column(p, 4)) ]) def p_expressao(self, p): ''' expressao : expressao_logica | atribuicao ''' p[0] = Node('expressao', value='expressao', children=[p[1]]) def p_expressao_logica(self, p): ''' expressao_logica : expressao_simples | expressao_logica operador_logico expressao_simples ''' if (len(p) == 4): p[0] = Node('expressao_logica', value='expressao_logica', children=[p[1], p[2], p[3]]) else: p[0] = Node('expressao_logica', value='expressao_logica', children=[p[1]]) def p_expressao_simples(self, p): ''' expressao_simples : expressao_aditiva | expressao_simples operador_relacional expressao_aditiva ''' if (len(p) == 4): p[0] = Node('expressao_simples', value='expressao_simples', children=[p[1], p[2], p[3]]) else: p[0] = Node('expressao_simples', value='expressao_simples', children=[p[1]]) def p_expressao_aditiva(self, p): ''' expressao_aditiva : expressao_multiplicativa | expressao_aditiva operador_soma expressao_multiplicativa ''' if (len(p) == 4): p[0] = Node('expressao_aditiva', value='expressao_aditiva', children=[p[1], p[2], p[3]]) else: p[0] = Node('expressao_aditiva', value='expressao_aditiva', children=[p[1]]) def p_expressao_multiplicativa(self, p): ''' expressao_multiplicativa : expressao_unaria | expressao_multiplicativa operador_multiplicacao expressao_unaria ''' if (len(p) == 4): p[0] = Node('expressao_multiplicativa', value='expressao_multiplicativa', children=[p[1], p[2], p[3]]) else: p[0] = Node('expressao_multiplicativa', value='expressao_multiplicativa', children=[p[1]]) def p_expressao_unaria(self, p): ''' expressao_unaria : fator | operador_soma fator | operador_negacao fator ''' if (len(p) == 3): p[0] = Node('expressao_unaria', value='expressao_unitaria', children=[p[1], p[2]]) else: p[0] = Node('expressao_unaria', value='expressao_unitaria', children=[p[1]]) def p_operador_relacional(self, p): ''' operador_relacional : MENOR | MAIOR | IGUAL | DIFERENTE | MENOR_IGUAL | MAIOR_IGUAL ''' p[0] = Node('operador_relacional', value='operador_relacional', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)) ]) def p_operador_soma(self, p): ''' operador_soma : MAIS | MENOS ''' p[0] = Node('operador_soma', value='operador_soma', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)) ]) def p_operador_logico(self, p): ''' operador_logico : E_LOGICO | OU_LOGICO ''' p[0] = Node('operador_logico', value='operador_logico', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)) ]) def p_operador_negacao(self, p): ''' operador_negacao : NEGACAO ''' p[0] = Node('operador_negacao', value='operador_negacao', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)) ]) def p_operador_multiplicacao(self, p): ''' operador_multiplicacao : MULTIPLICACAO | DIVISAO ''' p[0] = Node('operador_multiplicacao', value='operador_multiplicacao', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)) ]) def p_fator(self, p): ''' fator : ABRE_PARENTESE expressao FECHA_PARENTESE | var | chamada_funcao | numero ''' if (len(p) == 4): p[0] = Node('fator', value='fator', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)), p[2], Node(str(p[3]), value=str(p[3]), line=(p.lineno(3) - (self.totalLines - 1)), column=self.f_column(p, 3)) ]) else: p[0] = Node('fator', value='fator', children=[p[1]]) def p_numero(self, p): ''' numero : NUM_INTEIRO | NUM_PONTO_FLUTUANTE | NUM_NOTACAO_CIENTIFICA ''' p[0] = Node('numero', value='numero', children=[ Node(str(p[1]), value=p[1], line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)) ]) def p_chamada_funcao(self, p): ''' chamada_funcao : ID ABRE_PARENTESE lista_argumentos FECHA_PARENTESE ''' p[0] = Node('chamada_funcao', value='chamada_funcao', children=[ Node(str(p[1]), value=str(p[1]), line=(p.lineno(1) - (self.totalLines - 1)), column=self.f_column(p, 1)), Node(str(p[2]), value=str(p[2]), line=(p.lineno(2) - (self.totalLines - 1)), column=self.f_column(p, 2)), p[3], Node(str(p[4]), value=str(p[4]), line=(p.lineno(4) - (self.totalLines - 1)), column=self.f_column(p, 4)) ]) def p_lista_argumentos(self, p): ''' lista_argumentos : lista_argumentos VIRGULA expressao | expressao | vazio ''' if (len(p) == 4): p[0] = Node('lista_argumentos', value='lista_argumentos', children=[ p[1], Node(str(p[2]), value=str(p[2]), line=(p.lineno(2) - (self.totalLines - 1)), column=self.f_column(p, 2)), p[3] ]) else: if (p[1] is not None): p[0] = Node('lista_argumentos', value='lista_argumentos', children=[p[1]]) else: p[0] = Node('lista_argumentos', value='lista_argumentos') def p_vazio(self, p): ''' vazio : ''' pass def p_error(self, p): self.result = False if p: print('Sintaxe Inválida do token \'' + str(p.value) + '\' em ' + str(p.lineno) + ':' + str(self.lexer.f_column(p))) else: print('Sintaxe Inválida da saída') def syntactic(self, codeFile, numberOfLines): self.totalLines = numberOfLines self.tree = self.parser.parse(codeFile, tracking=True) return self.tree, self.result
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 SyntaxAnalyzer: def __init__(self, source_code, productions, actions, gotos): self.productions = productions self.actions = actions self.gotos = gotos self.stack = Stack() self.lexer = Lexer(source_code) self.trees = [] self._is_accepted = False def loop(self): while not self._is_accepted: self.iterate() return self.stack def iterate(self): state = self.stack.cur_state() lexeme, token = self.lexer.cur if token in self.actions[state]: action = self.actions[state][token] new_stack = self._act(action) self.stack.append_frame(lexeme, token, action, new_stack, self.trees.copy()) else: self._examine_error() def _act(self, action): if action[0] == 's': new_state = int(action[1:]) return self._shift(new_state) elif action[0] == 'r': look_up = int(action[1:]) return self._reduce(look_up) elif action == 'acc': return self._accept() else: raise Exception() def _shift(self, new_state): _, token = self.lexer.cur self.trees.append(Tree(token)) self.lexer.pop() return self.stack.raw_stack() + [token, new_state] def _reduce(self, look_up): lhs, rhs = self.productions[look_up] new_tree = Tree(lhs) for tree in self.trees[-len(rhs):]: new_tree.add(tree) self.trees = self.trees[:-len(rhs)] + [new_tree] reduced_stack = self.stack.raw_stack()[:-len(rhs) * 2] temp_state = reduced_stack[-1] new_state = self.gotos[temp_state][lhs] return reduced_stack + [lhs, new_state] def _accept(self): lhs, rhs = self.productions[0] parse_tree = Tree() parse_tree.data = lhs for tree in self.trees: parse_tree.add(tree) self._is_accepted = True self.trees = [parse_tree] return self.stack.raw_stack() def _examine_error(self): state = self.stack.cur_state() filtered = set(self.actions[state].keys()) lexeme, token = self.lexer.cur err = self._filtered_to_error(filtered) filtered_str = [token.name for token in filtered] msg = ERROR.format(err, state, token.name, lexeme, state, filtered_str) response = input(msg) if response == 'y': print(str(self.stack)) else: print("Raising Error...") raise err @classmethod def _filtered_to_error(cls, filtered): if filtered == {Token.IDENTIFIER}: return errors.NO_IDENT elif filtered == {Token.IDENTIFIER, Token.INTEGER_LITERAL, Token.TRUE, Token.FALSE}: return errors.NO_IDENT_OR_LIT elif filtered == {Token.BOOLEAN_TYPE, Token.INTEGER_TYPE}: return errors.NO_TYPE elif filtered == {Token.VAR, Token.BEGIN}: return errors.NO_SPECIAL_WORD elif filtered == {Token.EOF}: return errors.EOF_EXPECTED elif filtered == {Token.ASSIGNMENT}: return errors.NO_SYMBOL elif filtered == {Token.LESS, Token.EQUAL, Token.ADDITION, Token.SUBTRACTION, Token.LESS_EQUAL, Token.GREATER_EQUAL, Token.GREATER}: return errors.NO_SYMBOL else: return errors.SYNTAX_ERROR
def makeLexer(self, commentChar=Lexer.defaultCommentChar, commentExtChar=Lexer.defaultCommentExtChar): lexer = Lexer(commentChar, commentExtChar) lexer.addSyntacticChars(self.macros.keys()) lexer.addSpecialChars([self.pairingToken]) # just one for now return lexer
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)
import re from lex import Lexer from parse_qr import Parser if __name__ == '__main__': lexer = Lexer().build() file = open('test.txt') text_input = file.read() file.close() lexer.input(text_input) # while True: # tok = lexer.token() # if not tok: break # print(tok) parser = Parser() parser.build().parse(text_input, lexer, False)
try: # check that SLR table can be read with open("slr_table.csv", "rt") as f: actions, gotos = loadTable(f) # printActions(actions) except IOError: raise ERROR[5] # Couldn’t open SLR table file. # in the beginning we will write the input... # as a sequence of terminal symbols, ending by $ # the input will be the output of the lexical analyzer output = [] try: lexer = Lexer(input_) tokens = { key: result[1].name.lower() # result = (lexeme, token) for key, result in lexer.output.items() } except: raise ERROR[3] # Lexical error tree = parse(tokens, grammar, actions, gotos) if tree: print("Input is syntactically correct!") tree.print() else: print("Code has syntax errors!")
precedence = { '||': 5, '&&': 5, '>': 6, '>=': 6, '<=': 6, '<': 6, '==': 6, '!=': 6, '+': 7, '-': 7, '*': 8, '/': 8, 'UMINUS': 9 } tokens = list(Lexer('1+-10*123').lex()) precs = {'UMINUS': ['E', '-', 'E'], 'POSITIVE': ['E', '+', 'E']} # for t in tokens: # print(t) # print(sm.productions()) # parser = Parser(productions, terminal, nonterminal) parser = Parser(sm.productions, sm.terminal, sm.nonterminal, precedence=precedence, precs=precs) parser.generate() parser.parse(tokens, sm.sdmap) print(calls)
def main(): print("JCOSIM: Java Compiler Simulator") try: if len(argv) < 2: raise GetoptError('ERROR: Input file must be specified') options, remainder = getopt(argv[1:], 'i:o:stuapgc:vh', [ 'input=', 'output=', 'symtable', 'token', 'use-gcc', 'analyzedtree', 'analy', 'gencode', 'clean=', 'verbose', 'help', ]) source = None exe = None symtable = False token = False parsetree = False analyzedtree = False gencode = False clean = False clean_path = '.' cc = False for opt, arg in options: if opt in ('-h', '--help'): raise GetoptError('') elif opt in ('-c', '--clean'): clean = True clean_path = arg elif opt in ('-i', '--input'): source = arg elif opt in ('-u', '--use-gcc'): cc = True elif opt in ('-o', '--output'): exe = arg elif opt in ('-s', '--symtable'): symtable = True elif opt in ('-t', '--token'): token = True elif opt in ('-p', '--parsetree'): parsetree = True elif opt in ('-a', '--analyzedtree'): analyzedtree = True elif opt in ('-g', '--gencode'): gencode = True elif opt in ('-v', '--verbose'): symtable = True token = True parsetree = True analyzedtree = True gencode = True # clean and exit if clean: if source: # Smartly get exe file name if not exe: exe = Path(source).stem else: exe = 'Main' files = [ 'tokens.txt', 'parsetree.png', 'analyzedtree.png', 'symtable.json', f'{exe}.c', f'{exe}.exe', f'{exe}', f'{exe}.o', f'{exe}.obj' ] section(*clean_display(files)) for file in files: _path = Path(clean_path).joinpath(file).resolve() if Path(_path).exists(): Path(_path).unlink() exit() # No source no life if not source: raise GetoptError('ERROR: Input file must be specified') # Smartly get exe file name if not exe: exe = Path(source).stem # Read Java source file with open(source, 'r') as f: buffer = f.read() # Lexing lexer = Lexer(buffer) # Parsing parser = Parser(lexer) program_tree = parser.program() # Generate symbol table lexer.reset() stb = SymbolTable(lexer) # Semantic semantic = Semantic(program_tree, stb) analyzed_tree = semantic.analyze() # Generate C code code_gen = CodeGen(analyzed_tree, stb) code = code_gen.generate_code() # Compile the code and output native binary section(*native_compile_display(code, exe, cc)) # do things based on flags if token: section(*token_display(lexer)) if symtable: section(*symtable_display(stb)) if parsetree: section(*parsetree_display(program_tree, 'parsetree.png')) if analyzedtree: section(*parsetree_display(analyzed_tree, 'analyzedtree.png')) if gencode: section(*gencode_display(code, exe)) except GetoptError as e: section(*help_text()) print(e)
class GParser: def __init__(self, gramma): self.gl = Glex(open(gramma).read()) self.lexer = Lexer() self.classes = [] self.rules = {} def gnt(self): self.nt = self.gl.nextToken() def tis(self, t, v=None): if not self.nt: return False return self.nt[0] == t and (not v or self.nt[1] == v) def tass(self, t, v=None): if self.tis(t, v): return if v: raise ParseError("Expected '%s'" % v, self.nt) else: raise ParseError("Expected %s" % t, self.nt) def parseType(self): self.tass(TLIT) # Name t = GType(self.nt) self.gnt() if self.tis(KEYWORD, "["): # In an array self.gnt() self.tass(KEYWORD, "]") t.isArray = True self.gnt() return t def parseExpr(self): if self.tis(TLIT): c = GConstructorCall(self.nt) self.gnt() self.tass(KEYWORD, "(") self.gnt() if not self.tis(KEYWORD, ")"): while True: c.arguments.append(self.parseExpr()) if not self.tis(KEYWORD, ","): break self.gnt() self.tass(KEYWORD, ")") self.gnt() return c if self.tis(KEYWORD, "this"): x = GThislookup(self.nt) else: self.tass(GLIT) x = GVarlookup(self.nt) self.gnt() while True: if not self.tis(KEYWORD, "."): break self.gnt() self.tass(GLIT) x = GClasslookup(x, self.nt) self.gnt() return x def parseBlock(self): b = GBlock() while True: if self.tis(KEYWORD, "var"): v = GVar() self.gnt() self.tass(GLIT) v.name = self.nt self.gnt() self.tass(KEYWORD, ":") self.gnt() self.tass(TLIT) v.type = self.nt self.gnt() self.tass(KEYWORD, ";") self.gnt() b.stmts.append(v) continue if self.tis(KEYWORD, "return"): self.gnt() b.stmts.append(GReturn(self.parseExpr())) self.tass(KEYWORD, ";") self.gnt() continue if not self.tis(GLIT) and not self.tis(TLIT) and not self.tis(KEYWORD, "this"): break e = self.parseExpr() if self.tis(KEYWORD, "+="): self.gnt() e = GAppend(e, self.parseExpr()) elif self.tis(KEYWORD, "="): self.gnt() e = GAssign(e, self.parseExpr()) self.tass(KEYWORD, ";") self.gnt() b.stmts.append(e) return b def parseClass(self): self.gnt() self.tass(TLIT) # Name c = GClass(self.nt) self.gnt() if self.tis(KEYWORD, "("): self.gnt() while True: self.tass(TLIT) # Extend name c.extends.append(self.nt) self.gnt() if not self.tis(KEYWORD, ","): break self.gnt() self.tass(KEYWORD, ")") self.gnt() self.tass(KEYWORD, "{") self.gnt() while True: if self.tis(KEYWORD, "construct"): con = GConstructor() self.gnt() self.tass(KEYWORD, "(") self.gnt() if not self.tis(KEYWORD, ")"): while True: self.tass(GLIT) # Name n = self.nt self.gnt() self.tass(KEYWORD, ":") self.gnt() t = self.parseType() con.arguments.append((n, t)) if not self.tis(KEYWORD, ","): break self.gnt() self.tass(KEYWORD, ")") self.gnt() self.tass(KEYWORD, "{") self.gnt() con.block = self.parseBlock() self.tass(KEYWORD, "}") self.gnt() c.constructors.append(con) elif self.tis(KEYWORD, "var"): self.gnt() self.tis(GLIT) n = self.nt self.gnt() self.tass(KEYWORD, ":") self.gnt() ty = self.parseType() self.tass(KEYWORD, ";") self.gnt() c.vardecls.append(GClassVarDecl(n, ty)) else: break self.tass(KEYWORD, "}") self.gnt() return c def parseContinuation(self): r = GContinuation() while True: if self.tis(KEYWORD, "{"): self.gnt() r.items.append(self.parseBlock()) self.tass(KEYWORD, "}") self.gnt() continue x = None if self.tis(KEYWORD, "("): self.gnt() x = self.parseConjunction() self.tass(KEYWORD, ")") self.gnt() else: if self.tis(SLIT): x = GTokenRef(self.nt) v = self.nt[1][1:-1] x.tname = self.lexer.addKeyword(v) x.displayName = "'%s'" % v self.gnt() elif self.tis(TLIT): x = GTokenRef(self.nt) self.gnt() if self.tis(KEYWORD, "["): self.gnt() if self.tis(SLIT): x.displayName = self.nt[1][1:-1] else: x.displayName = self.nt[1] self.gnt() self.tass(KEYWORD, "]") self.gnt() elif self.tis(KEYWORD, "recover"): self.gnt() self.tass(TLIT) x = GTokenRef(self.nt, True) self.gnt() elif self.tis(GLIT): x = GGrammaRef(self.nt) self.gnt() else: break if self.tis(KEYWORD, ":"): self.gnt() self.tass(GLIT) x.name = self.nt self.gnt() if self.tis(KEYWORD, "*"): x = GStar(x) self.gnt() if self.tis(KEYWORD, "*"): x.captureAll = True self.gnt() elif self.tis(KEYWORD, "+"): x = GPlus(x) self.gnt() elif self.tis(KEYWORD, "?"): x = GOpt(x) self.gnt() r.items.append(x) return r def parseConjunction(self): r = self.parseContinuation() if self.tis(KEYWORD, "|"): c = GConjunction() c.items.append(r) r = c while self.tis(KEYWORD, "|"): self.gnt() r.items.append(self.parseContinuation()) return r def parse(self): try: self.gnt() while self.nt: if self.tis(TLIT): v = self.nt[1] self.gnt() self.tass(KEYWORD, ":=") r = self.gl.nextRegexp() self.lexer.addClass(v, r) self.gnt() continue if self.tis(KEYWORD, "class"): self.classes.append(self.parseClass()) continue self.tass(GLIT) v = self.nt self.gnt() self.tass(KEYWORD, ":=") self.gnt() self.rules[v[1]] = (v, self.parseConjunction()) self.tass(KEYWORD, ";") self.gnt() except ParseError, e: print "ParseError: %s\nat %s" % (e.msg, self.gl.tloc(e.tok))