def test_parse_var_declaration(self): """ 'var' type varName (',' varName)* ';' """ tokens = ( Token('keyword', 'var'), Token('dummy', 'dummy'), # Dummy type Token('identifier', 'foo'), Token('symbol', ','), Token('identifier', 'bar'), Token('symbol', ';'), ) expected = Token('varDec', [ Token('keyword', 'var'), Token('dummy', 'dummy'), # Dummy type Token('identifier', 'foo'), Token('symbol', ','), Token('identifier', 'bar'), Token('symbol', ';'), ]) parser = Parser(tokens) parser.parse_type = self._mock_parse(parser) actual = parser.parse_var_declaration() self.assertEqual(expected, actual)
def test_parse_parameter_list(self): """ ( (type identifier) (',' type identifier)*)? """ tokens = ( Token('dummy', 'dummy'), # Dummy type Token('identifier', 'foo'), Token('symbol', ','), Token('dummy', 'dummy'), # Dummy type Token('identifier', 'bar'), ) expected = Token('parameterList', [ Token('dummy', 'dummy'), # Dummy type Token('identifier', 'foo'), Token('symbol', ','), Token('dummy', 'dummy'), # Dummy type Token('identifier', 'bar'), ]) parser = Parser(tokens) parser.parse_type = self._mock_parse(parser) actual = parser.parse_parameter_list() self.assertEqual(expected, actual)
def test_parse_subroutine_body(self): """ '{' varDec* statements '}' """ tokens = ( Token('symbol', '{'), Token('keyword', 'var'), # Dummy var dec Token('keyword', 'var'), # Dummy var dec Token('dummy', 'dummy'), # Dummy statements Token('symbol', '}'), ) expected = Token('subroutineBody', [ Token('symbol', '{'), Token('dummy', 'dummy'), # Dummy var dec Token('dummy', 'dummy'), # Dummy var dec Token('dummy', 'dummy'), # Dummy statements Token('symbol', '}'), ]) parser = Parser(tokens) parser.parse_var_declaration = self._mock_parse(parser) parser.parse_statements = self._mock_parse(parser) actual = parser.parse_subroutine_body() self.assertEqual(expected, actual)
def test_parse_while_statement(self): """ 'while' '(' expression ')' '{' statements '}' """ tokens = ( Token('keyword', 'while'), Token('symbol', '('), Token('dummy', 'dummy'), # Dummy expression Token('symbol', ')'), Token('symbol', '{'), Token('dummy', 'dummy'), # Dummy expression Token('symbol', '}'), ) expected = Token('whileStatement', [ Token('keyword', 'while'), Token('symbol', '('), Token('dummy', 'dummy'), # Dummy expression Token('symbol', ')'), Token('symbol', '{'), Token('dummy', 'dummy'), # Dummy statements Token('symbol', '}'), ]) parser = Parser(tokens) parser.parse_expression = self._mock_parse(parser) parser.parse_statements = self._mock_parse(parser) actual = parser.parse_while_statement() self.assertEqual(expected, actual)
def test_class_with_body(self): """ 'class' className '{' classVarDec* subroutineDec* '}' """ tokens = ( Token('keyword', 'class'), Token('identifier', 'Main'), Token('symbol', '{'), Token('keyword', 'static'), # Dummy class var declaration Token('keyword', 'function'), # Dummy subroutine declaration Token('symbol', '}'), ) expected = Token('class', [ Token('keyword', 'class'), Token('identifier', 'Main'), Token('symbol', '{'), Token('dummy', 'dummy'), Token('dummy', 'dummy'), Token('symbol', '}'), ]) parser = Parser(tokens) parser.parse_class_var_declaration = self._mock_parse(parser) parser.parse_subroutine_declaration = self._mock_parse(parser) actual = parser.parse_class() self.assertEqual(expected, actual)
def test_parse_let_statement_index(self): """ 'let' varName ('[' expression ']')? '=' expression ';' """ tokens = ( Token('keyword', 'let'), Token('identifier', 'foo'), Token('symbol', '['), Token('dummy', 'dummy'), # Dummy expression Token('symbol', ']'), Token('symbol', '='), Token('dummy', 'dummy'), # Dummy expression Token('symbol', ';'), ) expected = Token('letStatement', [ Token('keyword', 'let'), Token('identifier', 'foo'), Token('symbol', '['), Token('dummy', 'dummy'), # Dummy expression Token('symbol', ']'), Token('symbol', '='), Token('dummy', 'dummy'), # Dummy expression Token('symbol', ';'), ]) parser = Parser(tokens) parser.parse_expression = self._mock_parse(parser) actual = parser.parse_let_statement() self.assertEqual(expected, actual)
def test_class_var_declaration_multiple(self): """ ('static' | 'field' ) type varName (',' varName)* ';' """ tokens = ( Token('keyword', 'static'), Token('keyword', 'int'), # Dummy type Token('identifier', 'foo'), Token('symbol', ','), Token('identifier', 'bar'), Token('symbol', ','), Token('identifier', 'baz'), Token('symbol', ';'), ) expected = Token('classVarDec', [ Token('keyword', 'static'), Token('dummy', 'dummy'), Token('identifier', 'foo'), Token('symbol', ','), Token('identifier', 'bar'), Token('symbol', ','), Token('identifier', 'baz'), Token('symbol', ';'), ]) parser = Parser(tokens) parser.parse_type = self._mock_parse(parser) actual = parser.parse_class_var_declaration() self.assertEqual(expected, actual)
def test_parse_parameter_list_empty(self): """ ( (type identifier) (',' type identifier)*)? """ tokens = (Token('symbol',')'), ) expected = Token('parameterList', []) parser = Parser(tokens) parser.parse_type = self._mock_parse(parser) actual = parser.parse_parameter_list() self.assertEqual(expected, actual)
def test_parse_statements(self): """ (letStatement | ifStatement | whileStatement | doStatement | returnStatement)* """ tokens = ( Token('keyword', 'let'), Token('keyword', 'if'), Token('keyword', 'while'), Token('keyword', 'do'), Token('keyword', 'return'), Token('symbol', '}') # Expect unparsed ) expected = Token('statements', [ Token('dummy', 'dummy'), Token('dummy', 'dummy'), Token('dummy', 'dummy'), Token('dummy', 'dummy'), Token('dummy', 'dummy'), ]) parser = Parser(tokens) parser.parse_let_statement = self._mock_parse(parser) parser.parse_if_statement = self._mock_parse(parser) parser.parse_while_statement = self._mock_parse(parser) parser.parse_do_statement = self._mock_parse(parser) parser.parse_return_statement = self._mock_parse(parser) actual = parser.parse_statements() self.assertEqual(expected, actual)
def test_parse_return_statement_empty(self): """ 'return' expression? ';' """ tokens = ( Token('keyword', 'return'), Token('symbol', ';'), ) expected = Token('returnStatement', [ Token('keyword', 'return'), Token('symbol', ';'), ]) parser = Parser(tokens) actual = parser.parse_return_statement() self.assertEqual(expected, actual)
def test_parse_return_statement(self): """ 'return' expression? ';' """ tokens = ( Token('keyword', 'return'), Token('dummy', 'dummy'), # Dummy expression Token('symbol', ';'), ) expected = Token('returnStatement', [ Token('keyword', 'return'), Token('dummy', 'dummy'), # Dummy expression Token('symbol', ';'), ]) parser = Parser(tokens) parser.parse_expression = self._mock_parse(parser) actual = parser.parse_return_statement() self.assertEqual(expected, actual)
def test_parse_do_statement(self): """ 'do' subroutineCall ';' """ tokens = ( Token('keyword', 'do'), Token('dummy', 'dummy'), # Dummy subroutineCall Token('symbol', ';'), ) expected = Token('doStatement', [ Token('keyword', 'do'), Token('dummy', 'dummy'), # Dummy subroutineCall Token('symbol', ';'), ]) parser = Parser(tokens) parser.parse_subroutine_call = self._mock_parse(parser) actual = parser.parse_do_statement() self.assertEqual(expected, actual)
def test_parse_subroutine_declaration(self): """ ('constructor'|'function'|'method') ('void'|type) identifier '('parameterList ')' subroutineBody """ tokens = ( Token('keyword', 'method'), Token('keyword', 'int'), # Dummy type Token('identifier', 'foo'), Token('symbol', '('), Token('dummy', 'dummy'), # Dummy parameterList Token('symbol', ')'), Token('dummy', 'dummy'), # Dummy subroutineBody ) expected = Token('subroutineDec', [ Token('keyword', 'method'), Token('dummy', 'dummy'), # Dummy type Token('identifier', 'foo'), Token('symbol', '('), Token('dummy', 'dummy'), # Dummy parameterList Token('symbol', ')'), Token('dummy', 'dummy'), # Dummy subroutineBody ]) parser = Parser(tokens) parser.parse_type = self._mock_parse(parser) parser.parse_parameter_list = self._mock_parse(parser) parser.parse_subroutine_body = self._mock_parse(parser) actual = parser.parse_subroutine_declaration() self.assertEqual(expected, actual)
def main(args): p = Parser() for path in args.input: if os.path.isdir(path): for fname in glob.iglob(os.path.join(path, '*.jack')): p.parse(fname) else: p.parse(path)
def test_parse_expression(self): """ term (op term)* """ tokens = ( Token('integerConstant', '1'), Token('symbol', '+'), Token('integerConstant', '1'), Token('symbol', '+'), Token('integerConstant', '1'), ) expected = Token('expression', [ Token('dummy', 'dummy'), Token('symbol', '+'), Token('dummy', 'dummy'), Token('symbol', '+'), Token('dummy', 'dummy'), ]) parser = Parser(tokens) parser.parse_term = self._mock_parse(parser) actual = parser.parse_expression() self.assertEqual(expected, actual)
def test_class_no_body(self): """ 'class' className '{' classVarDec* subroutineDec* '}' """ tokens = ( Token('keyword', 'class'), Token('identifier', 'Main'), Token('symbol', '{'), Token('symbol', '}'), ) expected = Token('class', [ Token('keyword', 'class'), Token('identifier', 'Main'), Token('symbol', '{'), Token('symbol', '}'), ]) actual = Parser(tokens).parse_class() self.assertEqual(expected, actual)
def compile(file_text): tokens = tokenize(file_text) parse_tree = Parser(tokens).parse_class() vm_text = CodeGenerator().compile_class(parse_tree) return vm_text
def analyse(file_text): tokens = tokenize(file_text) parse_tree = Parser(tokens).parse_class() return parse_tree.to_xml()