Example #1
0
def tree(text):
    lexer = Lexer(text)
    parser = Parser(lexer)
    tree = parser.parse()
    sem_an = SemanticAnalyzer(tree)
    sem_an.analyse()
    return tree
Example #2
0
def test_parser_expr_assign():
    text = 'a: int = (12 + 2) * 2;'
    lexer = Lexer(text)
    parser = Parser(lexer)
    node1 = parser.parse()

    assert isinstance(node1, Block)
    assert len(node1.children) == 2

    node2 = node1.children[0]
    assert isinstance(node2, Assign)
    assert isinstance(node2.name, Variable)
    assert node2.type.type == 'TYPE'  # TYPE Token as type
    assert node2.type.value == 'int'
    assert isinstance(node2.value, BinOp)

    node3 = node2.value
    assert isinstance(node3.left, BinOp)
    assert node3.op.value == '*'
    assert isinstance(node3.right, Number)

    node4 = node3.left
    assert isinstance(node4.left, Number)
    assert node4.op.value == '+'
    assert isinstance(node4.right, Number)
Example #3
0
def test_parser_func_decl3():
    text = """
        function function_name(a: int, b: int) {
            return (b + a);
        }
    """
    lexer = Lexer(text)
    parser = Parser(lexer)
    block = parser.parse()
    func_decl = block.children[0]
    assert isinstance(func_decl, FuncDecl)

    # Params
    params = func_decl.formal_params
    assert isinstance(params, list)
    assert len(params) == 2
    first_param = params[0]
    assert isinstance(first_param, Param)
    assert first_param.var_node.value == 'a'
    assert first_param.type_node.value == 'int'
    second_param = params[1]
    assert isinstance(second_param, Param)
    assert second_param.var_node.value == 'b'
    assert second_param.type_node.value == 'int'

    # Block
    func_block = func_decl.block_node
    assert isinstance(func_block, Block)
Example #4
0
def evaluate(code: str, tape_size: int = 1000) -> str:
    """
            Helper function which combines the process of lexing,
            syntax analysis, and parsing/evaluation to return either
            the finaly output or an error message.

            Parameters:
                code : str
                    the brainfxck code to be evaluated. 

            Returns:
                str
        """

    # Pass the input code to the lexer, then to the syntax analyser
    # where if the is_faulty parameter is true, then the error messages
    # generated by the analyser method are returned, otherwise the
    # token stream is passed to the parser and the output generated
    # is returned

    # Lexical analysis to generate a token stream
    lexer = Lexer(code)
    token_stream = lexer.lex()

    syntax_analyser = SyntaxAnalyser(token_stream)
    error_dic = syntax_analyser.analyse()
    if error_dic["is_faulty"]:
        # Adding a newline character to the beginning of the error message
        op_string = "\n"
        # Traversing throught the faulty tokens in the token list
        for token in error_dic["faulty_token_list"]:
            op_string += (
                f"Error for {token.op_name} at :: line : {token.line_number} position : {token.posn_number}\n"
            )
        return op_string

    # Parsing the token stream to generate output
    parser = Parser(token_stream, tape_size)
    parser.parse()
    output = parser.output_string
    return output
Example #5
0
def interpret(expression):
    try:
        parser = Parser(expression)
        node = parser.parse()
        result = node.traverse()

        namespace.set("_", result)
        return result
    except KeyError as key_error:
        print("Error: name {} is not defined".format(key_error))
    except Exception as exception:
        print("{}: {}".format(type(exception).__name__, str(exception)))
Example #6
0
def test_parser_function_call1():
    text = """
        some_function();
    """
    lexer = Lexer(text)
    parser = Parser(lexer)
    block = parser.parse()
    func_call = block.children[0]
    assert isinstance(func_call, FuncCall)
    assert func_call.params == []
    assert func_call.func_name == 'some_function'
    assert func_call.token.value == 'some_function'
Example #7
0
def test_parser_statement_after_if():
    text = """
        if (a > 2) {
            print('yo');
        }
        b: int = 4; """
    lexer = Lexer(text)
    parser = Parser(lexer)
    main_block = parser.parse()

    if_node = main_block.children[0]
    assert isinstance(if_node, IfStatement)

    assgn_node = main_block.children[1]
    assert isinstance(assgn_node, Assign)
Example #8
0
def test_parser_statement_before_if():
    text = """  
        a: str = "hey";
        if (a == 2) {
            print('yes');
        }
    """
    lexer = Lexer(text)
    parser = Parser(lexer)
    main_block = parser.parse()

    assign_node = main_block.children[0]
    assert isinstance(assign_node, Assign)

    if_node = main_block.children[1]
    assert isinstance(if_node, IfStatement)
Example #9
0
def test_parser_print_str():
    text = 'print("Hello");'
    lexer = Lexer(text)
    parser = Parser(lexer)
    node1 = parser.parse()

    # First node should be Block
    assert isinstance(node1, Block)
    assert len(node1.children) == 2  # Print node and Empty node

    node2 = node1.children[0]
    assert isinstance(node2, Print)
    assert len(node2.args) == 1

    node3 = node2.args[0]
    assert isinstance(node3, String)
    assert node3.value == 'Hello'
Example #10
0
def test_parser_print_bool():
    text = 'print(True);'
    lexer = Lexer(text)
    parser = Parser(lexer)
    node1 = parser.parse()

    # First node should be Block
    assert isinstance(node1, Block)
    assert len(node1.children) == 2  # Print node and Empty node

    node2 = node1.children[0]
    assert isinstance(node2, Print)
    assert len(node2.args) == 1

    node3 = node2.args[0]
    assert isinstance(node3, Boolean)
    assert node3.value == True
Example #11
0
def test_parser_str_assign():
    text = 'a: str = "string";'
    lexer = Lexer(text)
    parser = Parser(lexer)
    node1 = parser.parse()

    assert isinstance(node1, Block)
    assert len(node1.children) == 2

    node2 = node1.children[0]
    assert isinstance(node2, Assign)
    assert isinstance(node2.name, Variable)
    assert node2.type.type == 'TYPE'  # TYPE Token as type
    assert node2.type.value == 'str'
    assert isinstance(node2.value, String)

    node3 = node2.value
    assert node3.value == 'string'
Example #12
0
def test_parser_int_assign():
    text = 'a: int = 46;'
    lexer = Lexer(text)
    parser = Parser(lexer)
    node1 = parser.parse()

    assert isinstance(node1, Block)
    assert len(node1.children) == 2

    node2 = node1.children[0]
    assert isinstance(node2, Assign)
    assert isinstance(node2.name, Variable)
    assert node2.type.type == 'TYPE'  # TYPE Token as type
    assert node2.type.value == 'int'
    assert isinstance(node2.value, Number)

    node3 = node2.value
    assert node3.value == 46
Example #13
0
def test_parser_nested_func_call():
    text = """
    function some_function(a: int) {
        b: int = a + 1;
        return (b);
    }    
    print(some_function(2));
    """
    lexer = Lexer(text)
    parser = Parser(lexer)
    block = parser.parse()
    func_decl = block.children[0]
    assert isinstance(func_decl, FuncDecl)
    assert len(func_decl.formal_params) == 1
    assert func_decl.func_name.value == 'some_function'

    print_statement = block.children[1]
    assert isinstance(print_statement, Print)
Example #14
0
def test_parser_bool_assign():
    text = 'variable: bool = True;'
    lexer = Lexer(text)
    parser = Parser(lexer)
    node1 = parser.parse()

    assert isinstance(node1, Block)
    assert len(node1.children) == 2

    node2 = node1.children[0]
    assert isinstance(node2, Assign)
    assert isinstance(node2.name, Variable)
    assert node2.type.type == 'TYPE'  # TYPE Token as type
    assert node2.type.value == 'bool'
    assert isinstance(node2.value, Boolean)

    node3 = node2.value
    assert node3.value == True
Example #15
0
def run_interpreter(text):
    result = {}
    result['output'] = []
    with Capturing() as output:
        try:
            lexer = Lexer(text)
            parser = Parser(lexer)
            tree = parser.parse()
            sem_an = SemanticAnalyzer(tree)
            sem_an.analyse()
            interpreter = Interpreter(tree)
            result['final_result'] = interpreter.interpret()
        except Exception as exc:
            result['exception'] = str(exc)

    if output:
        result['output'] = output

    return result
Example #16
0
def test_parser_if_comparison2():
    text = """
        if (a <= 2) {
            print('yo');
        } """
    lexer = Lexer(text)
    parser = Parser(lexer)
    block = parser.parse()
    if_node = block.children[0]
    assert isinstance(if_node, IfStatement)

    assert isinstance(if_node.value, Comparison)
    assert isinstance(if_node.block, Block)
    assert if_node.elseblock is None

    comp_node = if_node.value
    assert isinstance(comp_node.left, Variable)
    assert comp_node.op.value == '<='
    assert isinstance(comp_node.right, Number)
Example #17
0
def test_parser_function_call_with_params():
    text = """
        some_function(12 + 4, 'string', 78);
    """
    lexer = Lexer(text)
    parser = Parser(lexer)
    block = parser.parse()
    func_call = block.children[0]
    assert isinstance(func_call, FuncCall)
    assert len(func_call.params) == 3
    assert func_call.func_name == 'some_function'
    assert func_call.token.value == 'some_function'

    first_param = func_call.params[0]
    assert isinstance(first_param, BinOp)

    second_param = func_call.params[1]
    assert isinstance(second_param, String)

    third_param = func_call.params[2]
    assert isinstance(third_param, Number)
Example #18
0
def test_parser_if_true():
    text = """
        if (True) {
            print('yo');
        } """
    lexer = Lexer(text)
    parser = Parser(lexer)
    block = parser.parse()
    if_node = block.children[0]
    assert isinstance(if_node, IfStatement)

    assert isinstance(if_node.value, Comparison)
    comparison = if_node.value
    assert comparison.left.value == True
    assert comparison.op is None
    assert comparison.right is None

    assert isinstance(if_node.block, Block)
    assert if_node.elseblock is None

    block_node = if_node.block
    assert isinstance(block_node.children[0], Print)
Example #19
0
def main():
    arg = sys.argv[1]
    
    processtime_in_ms = time.time() * 1000

    with open(arg) as fs:

        # Generate Tokens
        lexer = Lexer(fs.read())
        tokens = lexer.generate_tokens()

        # Generate AST
        parser = Parser(tokens)
        ast = parser.parse()

        # Global conductor instance
        conductor = Conductor()

        # Interpret AST
        interpreter = Interpreter(ast, conductor)
        interpreter.interpret()

        print(f"\nPROCESS TIME: {time.time() * 1000 - processtime_in_ms}ms")
def tree(text):
    lexer = Lexer(text)
    parser = Parser(lexer)
    tree = parser.parse()
    return tree
Example #21
0
class Interpreter(QObject):

    interpreted = pyqtSignal(str)

    def __init__(self):
        super(Interpreter, self).__init__()
        self.scanner = Scanner()
        self.parser = Parser()
        self.was_retry = False

    def interpret(self, text: str):
        text = text.replace('&lt;', '<').replace('&gt;', '>')
        try:
            tokens, had_error = self.scanner.scan(text)
        except Error as err:
            self.print(err.__str__())
            return
        # for token in tokens: print(token)
        exprs = self.parser.parse(tokens)
        if exprs is not None:
            for expr in exprs:
                if isinstance(expr, Expr):
                    # print(expr.__str__())
                    try:
                        ans = expr.evaluate()
                        # TODO loaded script compatible with 'ans'
                        self.parser.environment.vars['ans'] = ans
                        if type(ans) is bool and not expr.mute:
                            if ans is True:
                                self.print("true")
                            else:
                                self.print("false")
                        else:
                            trimmed = self.trim_trailing_zero(ans)
                            if not expr.mute:
                                self.print(trimmed)
                    except Error as err:
                        self.print(err.__str__())
                elif isinstance(expr, Error):
                    print(expr.__str__())
                    # flexibility about unmatched ')' : allow "a = log(10" by adding a ')' at the end of the text
                    if (expr.__str__() == "ParseError - Expect ')' after arguments."
                        or expr.__str__() == "ParseError - Expect ')' after expression.") \
                            and not self.was_retry:
                        try:
                            self.was_retry = True
                            self.interpret(text + ')')
                        except Error:
                            self.print(expr)
                    else:
                        self.print(expr)
                elif isinstance(expr, Files):
                    loaded = expr.exec()
                    if loaded is not None:
                        self.interpret(loaded)
                        # TODO correct history for loaded scripts
        self.was_retry = False

    def print(self, res):
        self.interpreted.emit(res.__str__())
        # print(res)

    @staticmethod
    def trim_trailing_zero(text):
        text = str(text)
        if text.endswith('.0'):
            text = text[:text.index('.0')]
        return text