Exemplo n.º 1
0
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")
Exemplo n.º 2
0
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")
Exemplo n.º 3
0
        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)

Exemplo n.º 4
0
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")
Exemplo n.º 5
0
import sys
sys.path.append("..")
from lex import Lexer

def filename(path):
    index = str(path).rfind('/') + 1
    name = path[index:]
    return name

def read_file(path):
    with open(path, 'r') as f:
        return f.read()

if __name__ == '__main__':
    path = './t1.c'
    lexer = Lexer(filename(path), read_file(path))
    lexer.lex()
    lexer.see_tokens()

Exemplo n.º 6
0
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")
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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")
Exemplo n.º 9
0
def scanner(file):
    lexer = Lexer(file)
    pending = lexer.lex()
    while (pending.ltype != "END_OF_INPUT"):
        print(pending)
        pending = lexer.lex()
Exemplo n.º 10
0
def scanner(file):
    lexer = Lexer(file)
    pending = lexer.lex()
    while (pending.ltype != "END_OF_INPUT"):
        print(pending)
        pending = lexer.lex()