예제 #1
0
 def compile_statements(self):
     local_root = SyntaxTreeNode('statements')
     local_root.add_many(lambda: or_compile((
         self.compile_do,
         self.compile_let,
         self.compile_while,
         self.compile_return,
         self.compile_if,
     )))
     return local_root
예제 #2
0
 def __expect_symbol(self, symbols):
     next_token = self.tokenizer.peek_next()
     if next_token and next_token.get_type() == TokenType.SYMBOL:
         tk_value = next_token.get_symbol()
         if tk_value in symbols:
             self.tokenizer.advance()
             return SyntaxTreeNode('symbol', tk_value)
예제 #3
0
 def __expect_keyword(self, keywords):
     next_token = self.tokenizer.peek_next()
     if next_token and next_token.get_type() == TokenType.KEYWORD:
         tk_value = next_token.get_keyword()
         if tk_value in keywords:
             self.tokenizer.advance()
             return SyntaxTreeNode('keyword', tk_value)
예제 #4
0
 def compile_subroutine_body(self):
     # subroutineBody
     # '{' varDec* statements '}'
     local_root = SyntaxTreeNode('subroutineBody')
     # '{'
     node = self.__expect_symbol('{')
     if not node:
         return None
     local_root.add_child(node)
     # varDesc*
     local_root.add_many(self.compile_var_dec)
     # statements
     local_root.add_child(self.compile_statements(), 'expect statements')
     # '}'
     local_root.add_child(self.__expect_symbol('}'), 'expect }')
     return local_root
예제 #5
0
 def compile_return(self):
     # 'return' expression? ';'
     node = self.__expect_keyword('return')
     if not node:
         return None
     local_root = SyntaxTreeNode('returnStatement')
     local_root.add_child(node)
     local_root.add_child(self.compile_expression())
     local_root.add_child(self.__expect_symbol(';') ,'expect ; in return')
     return local_root
예제 #6
0
 def compile_do(self):
     # 'do' subroutineCall ';'
     node = self.__expect_keyword('do')
     if not node:
         return None
     local_root = SyntaxTreeNode('doStatement')
     local_root.add_child(node)
     sub_call = self.compile_subroutine_call()
     if not sub_call:
         sys.exit('missing subroutine call in do statement')
     local_root.add_child(sub_call)
     # ;
     local_root.add_child(self.__expect_symbol(';'), 'expect ; in do')
     return local_root
예제 #7
0
 def compile_expression(self):
     # term (op term)*
     node = self.compile_term()
     if not node:
         return None
     local_root = SyntaxTreeNode('expression')
     local_root.add_child(node)
     while True:
         node = self.__expect_op()
         if node:
             local_root.add_child(node)
             local_root.add_child(self.compile_term(), 'expect term after op')
         else:
             break
     return local_root
예제 #8
0
 def compile_expression_list(self):
     # (expression (',' expression)* )?
     local_root = SyntaxTreeNode('expressionList')
     node = self.compile_expression()
     if node:
         local_root.add_child(node)
         # (',' expression)*
         while True:
             node = self.__expect_symbol(',')
             if node:
                 local_root.add_child(node)
                 local_root.add_child(self.compile_expression(), 'expect expression in exp list')
             else:
                 break
     return local_root
예제 #9
0
 def __expect_identifier(self):
     next_token = self.tokenizer.peek_next()
     if next_token and next_token.get_type() == TokenType.IDENTIFIER:
         self.tokenizer.advance()
         return SyntaxTreeNode('identifier', next_token.get_identifier())
예제 #10
0
 def compile_if(self):
     # 'if' '(' expression ')' '{' statements '}'
     # ('else' '{' statements '}')?
     node = self.__expect_keyword('if')
     if not node:
         return None
     local_root = SyntaxTreeNode('ifStatement')
     local_root.add_child(node)
     local_root.add_child(self.__expect_symbol('('), 'expect ( in if')
     local_root.add_child(self.compile_expression(), 'expect expression in if')
     local_root.add_child(self.__expect_symbol(')'), 'expect ) in if')
     local_root.add_child(self.__expect_symbol('{'), 'expect { in if')
     local_root.add_child(self.compile_statements(), 'expect statements in if')
     local_root.add_child(self.__expect_symbol('}'), 'expect } in if')
     next_token = self.tokenizer.peek_next()
     if next_token and next_token.get_keyword() == 'else':
         local_root.add_child(self.__expect_keyword('else'))
         local_root.add_child(self.__expect_symbol('{'), 'expect { in else')
         local_root.add_child(self.compile_statements(), 'expect statements in else')
         local_root.add_child(self.__expect_symbol('}'), 'expect } in else')
     return local_root
예제 #11
0
 def compile_while(self):
     # 'while' '(' expression ')' '{' statements '}'
     node = self.__expect_keyword('while')
     if not node:
         return None
     local_root = SyntaxTreeNode('whileStatement')
     local_root.add_child(node)
     local_root.add_child(self.__expect_symbol('('), 'expect ( in while')
     local_root.add_child(self.compile_expression(), 'expect expression in while')
     local_root.add_child(self.__expect_symbol(')'), 'expect ) in while')
     local_root.add_child(self.__expect_symbol('{'), 'expect { in while')
     local_root.add_child(self.compile_statements(), 'expect statements in while')
     local_root.add_child(self.__expect_symbol('}'), 'expect } in while')
     return local_root
예제 #12
0
 def compile_parameter_list(self):
     # ((type varName) (',' type varName)*)?
     local_root = SyntaxTreeNode('parameterList')
     # (type varName)
     node = self.__expect_type()
     if not node:
         return local_root
     local_root.add_child(node)
     local_root.add_child(self.__expect_identifier(), 'expect varName')
     # (',' type varName) *
     while True:
         node = self.__expect_symbol(',')
         if node:
             local_root.add_child(node)
             local_root.add_child(self.__expect_type(), 'expect type')
             local_root.add_child(self.__expect_identifier(), 'expect identifier')
         else:
             break
     return local_root
예제 #13
0
 def compile_class(self):
     # class: 'class' className '{' classVarDec* subroutineDec* '}'
     local_root = SyntaxTreeNode('class')
     # 'class'
     local_root.add_child(self.__expect_keyword('class'), 'expect keyword class')
     # className
     class_name_node = self.__expect_identifier()
     local_root.add_child(class_name_node, 'expect identifier className')
     self.class_name = class_name_node.value
     # '{'
     local_root.add_child(self.__expect_symbol('{'), 'expect {')
     # classVarDec*
     local_root.add_many(self.compile_class_var_dec)
     # subroutineDec*
     local_root.add_many(self.compile_subroutine)
     # '}'
     local_root.add_child(self.__expect_symbol('}'), 'expect } in class')
     return local_root
예제 #14
0
 def __expect_integer_constant(self):
     next_token = self.tokenizer.peek_next()
     if next_token and next_token.get_type() == TokenType.INT_CONSTANT:
         self.tokenizer.advance()
         return SyntaxTreeNode('integerConstant', next_token.get_integer_constant())
예제 #15
0
 def compile_subroutine_call(self) -> SyntaxTreeNode:
     # subroutineCall: subroutineName '(' expressionList ')'
     # | (className | varName) '.' subroutineName '(' expressionList ')'
     local_root = None
     next_token = self.tokenizer.peek_next()
     if next_token.get_type() == TokenType.IDENTIFIER:
         next2_token = self.tokenizer.peek_next(2)
         n2_value = next2_token.get_symbol()
         if n2_value in ('(', '.'):
             # ok, this is a subroutine call
             local_root = SyntaxTreeNode('subroutineCall')
             node = self.__expect_identifier()
             local_root.add_child(node)
             next_token = self.tokenizer.peek_next()
             if next_token.get_symbol() == '.':
                 local_root.add_child(self.__expect_symbol('.'))
                 local_root.add_child(self.__expect_identifier())
             local_root.add_child(self.__expect_symbol('('))
             local_root.add_child(self.compile_expression_list())
             local_root.add_child(self.__expect_symbol(')'))
     return local_root
예제 #16
0
 def compile_var_dec(self):
     # 'var' type varName (',' varName)* ';'
     node = self.__expect_keyword('var')
     if not node:
         return None
     # 'var' type varName
     local_node = SyntaxTreeNode('varDec')
     local_node.add_child(node)
     local_node.add_child(self.__expect_type(), 'expect type in varDec')
     local_node.add_child(self.__expect_identifier(), 'expect identifier in varDec')
     # (',' varName)*
     while True:
         node = self.__expect_symbol(',')
         if node:
             local_node.add_child(node)
             local_node.add_child(self.__expect_identifier(), 'expect identifier in varDec')
         else:
             break
     # ;
     local_node.add_child(self.__expect_symbol(';'))
     return local_node
예제 #17
0
    def compile_term(self):
        # integerConstant | stringConstant | keywordConstant |
        # varName | varName '[' expression ']' |
        # subroutineCall | '(' expression ')' |
        # unaryOp term
        local_root = SyntaxTreeNode('term')

        # integerConstant | stringConstant | keywordConstant
        node = or_compile((
            self.__expect_integer_constant,
            self.__expect_string_constant,
            self.__expect_keyword_constant,
        ))
        if node:
            local_root.add_child(node)
            return local_root

        # subroutineCall
        sub_call = self.compile_subroutine_call()
        if sub_call:
            local_root.add_child(sub_call)
            return local_root

        next_token = self.tokenizer.peek_next()
        # varName | varName '[' expression ']'
        if next_token and next_token.get_type() == TokenType.IDENTIFIER:
            local_root.add_child(self.__expect_identifier())
            next2 = self.tokenizer.peek_next()
            if next2 and next2.get_symbol() == '[':
                local_root.add_child(self.compile_array_access())
            return local_root

        # '(' expression ')'
        if next_token and next_token.get_symbol() == '(':
            local_root.add_child(self.__expect_symbol('('))
            local_root.add_child(self.compile_expression(), 'expect expression after ( in term')
            local_root.add_child(self.__expect_symbol(')'), 'expect ) in term')
            return local_root

        # unaryOp term
        node = self.__expect_unary_op()
        if node:
            local_root.add_child(node)
            local_root.add_child(self.compile_term(), 'expect term after unary op in term')
            return local_root

        return None
예제 #18
0
 def __expect_string_constant(self):
     next_token = self.tokenizer.peek_next()
     if next_token and next_token.get_type() == TokenType.STRING_CONSTANT:
         self.tokenizer.advance()
         return SyntaxTreeNode('stringConstant', next_token.get_string_constant())
예제 #19
0
 def compile_let(self):
     # 'let' varName ('[' expression ']')? '=' expression ';'
     node = self.__expect_keyword('let')
     if not node:
         return None
     local_root = SyntaxTreeNode('letStatement')
     local_root.add_child(node)
     local_root.add_child(self.__expect_identifier(), 'expect varName in let')
     next_token = self.tokenizer.peek_next()
     if next_token and next_token.get_symbol() == '[':
         local_root.add_child(self.compile_array_access())
     local_root.add_child(self.__expect_symbol('='), 'expect = in let')
     local_root.add_child(self.compile_expression(), 'expect expression in let statement')
     # ;
     local_root.add_child(self.__expect_symbol(';'), 'expect ; in let')
     return local_root
예제 #20
0
 def compile_array_access(self):
     local_root = SyntaxTreeNode('arrayAccess')
     local_root.add_child(self.__expect_symbol('['), 'expect [')
     local_root.add_child(self.compile_expression(), 'expect expression in array access')
     local_root.add_child(self.__expect_symbol(']'), 'expect ]')
     return local_root
예제 #21
0
 def compile_class_var_dec(self):
     # classVarDec: ('static' | 'field') type varName (',' varName)* ';'
     # ('static' | 'field')
     node = self.__expect_keyword(('static', 'field'))
     if not node:
         return None
     local_root = SyntaxTreeNode('classVarDec')
     local_root.add_child(node)
     # re.type: 'int' | 'char' | 'boolean' | className
     # re.className: identifier
     local_root.add_child(self.__expect_type(), 'expect type')
     # varName: identifier
     local_root.add_child(self.__expect_identifier(), 'expect varName')
     # (',' varName)*
     while True:
         node = self.__expect_symbol(',')
         if node:
             local_root.add_child(node)
             local_root.add_child(self.__expect_identifier(), 'expect varName after ,')
         else:
             break
     # ';'
     local_root.add_child(self.__expect_symbol(';'), 'expect ; in varDec')
     return local_root
예제 #22
0
 def compile_subroutine(self):
     # ('constructor' | 'function' | 'method')
     node = self.__expect_keyword(('constructor', 'function', 'method'))
     if not node:
         return None
     local_root = SyntaxTreeNode('subroutineDec')
     local_root.add_child(node)
     # ('void' | type)
     local_root.add_child(self.__expect_void_or_type(), 'expect void or type')
     # subroutineName
     local_root.add_child(self.__expect_identifier(), 'expect subroutineName')
     # '('
     local_root.add_child(self.__expect_symbol('('), 'expect )')
     # parameterList
     local_root.add_child(self.compile_parameter_list(), 'expect parameterList')
     # ')'
     local_root.add_child(self.__expect_symbol(')'), 'expect )')
     # subroutineBody
     local_root.add_child(self.compile_subroutine_body(), 'expect subroutineBody')
     return local_root