def test1():
	input = "LET foobar = 123"
	lexer = Lexer(input)

	while lexer.peek() != '\0':
		print(lexer.curChar)
		lexer.nextChar()
Exemple #2
0
 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()
Exemple #4
0
    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
Exemple #5
0
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.")
Exemple #7
0
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')
Exemple #8
0
    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()
Exemple #9
0
    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)
Exemple #11
0
 def __init__(self, filename):
     self.file = open(filename)
     self.pending = None
     self.lexer = Lexer(self.file)
Exemple #12
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")
 def __init__(self, **kwargs):
     self.totalLines = 0
     self.result = True
     self.lexer = Lexer()
     self.parser = yacc.yacc(module=self, **kwargs)
Exemple #14
0
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'

Exemple #15
0
||| 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? ")
Exemple #16
0
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
Exemple #17
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")
Exemple #18
0
 def __init__(self, gramma):
     self.gl = Glex(open(gramma).read())
     self.lexer = Lexer()
     self.classes = []
     self.rules = {}
Exemple #19
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")
Exemple #20
0
def scanner(file):
    lexer = Lexer(file)
    pending = lexer.lex()
    while (pending.ltype != "END_OF_INPUT"):
        print(pending)
        pending = lexer.lex()
Exemple #21
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
Exemple #22
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")
Exemple #23
0
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
Exemple #25
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")
Exemple #26
0
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
Exemple #27
0
 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
Exemple #28
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)

Exemple #29
0
def scanner(file):
    lexer = Lexer(file)
    pending = lexer.lex()
    while (pending.ltype != "END_OF_INPUT"):
        print(pending)
        pending = lexer.lex()
Exemple #30
0
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)
Exemple #31
0
    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!")
Exemple #32
0

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)
Exemple #33
0
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)
Exemple #34
0
 def __init__(self, filename):
     self.file = open(filename)
     self.pending = None
     self.lexer = Lexer(self.file)
Exemple #35
0
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))