Пример #1
0
    def test_statement(self):
        # Missing '%end'
        with self.parse('''
                        %define x(a)
                            y = a
                        '''):
            self.assertError('Input ended unexpectedly')

        # Success
        with self.parse('''
                        %define f1()
                        %end

                        %define f2(foo)
                           x = foo
                        %end

                        %define f3(foo, bar)
                           x = foo
                           y = bar
                        %end
                        ''') as p:
            self.assertIsInstance(p, ast.Module)
            self.assertEqual(3, len(p.statements))
            p = p.statements

            self.assertIsInstance(p[0], ast.StatementMacroStmt)
            self.assertLocation(p[0], 2, 26)
            self.assertEqual('f1', p[0].name)
            self.assertEqual((), p[0].parameters)
            self.assertEqual((), p[0].statements)

            self.assertIsInstance(p[1], ast.StatementMacroStmt)
            self.assertLocation(p[1], 5, 26)
            self.assertEqual('f2', p[1].name)
            self.assertEqual(('foo',), p[1].parameters)
            self.assertEqual((ast.AssignmentStmt(varname = 'x',
                                                 value = self.foo),),
                             p[1].statements)

            self.assertIsInstance(p[2], ast.StatementMacroStmt)
            self.assertLocation(p[2], 9, 26)
            self.assertEqual('f3', p[2].name)
            self.assertEqual(('foo', 'bar'), p[2].parameters)
            self.assertEqual((ast.AssignmentStmt(varname = 'x',
                                                 value = self.foo),
                              ast.AssignmentStmt(varname = 'y',
                                                 value = self.bar)),
                             p[2].statements)
Пример #2
0
    def test_module(self):
        def test_mod(src, *statements):
            with self.parse(src) as p:
                self.assertIsInstance(p, ast.Module)
                self.assertLocation(p, 0, 0)
                self.assertIsInstance(p.filename, type(''))
                self.assertEqual('', p.filename)
                self.assertIsInstance(p.statements, tuple)
                self.assertEqual(statements, p.statements)

        # Empty
        test_mod('')
        test_mod('// This module is empty\n   \n')

        # Single statement
        test_mod('''
                 var foo = bar
                 ''',
                 ast.VarStmt(name='foo', value=self.bar),
                 )

        # Multiple statements
        test_mod('''
                 // This is a nice module
                 var foo = bar
                 x = 2
                 // One more statement
                 foo bar ()
                 ''',
                 ast.VarStmt(name='foo', value=self.bar),
                 ast.AssignmentStmt(varname='x', value=self.two),
                 ast.DeclarationStmt(type = 'foo',
                                     tag = 'bar',
                                     params = (),
                                     children = ()),
                 )

        # Missing newline between statements
        with self.parse('''
                        x = 1 y = 2
                        '''):
            self.assertError('Missing newline at end of statement',
                             token='y')
Пример #3
0
    def test_basic(self):
        basedir = os.path.join(self.tmpdir, 'base')
        os.mkdir(basedir)

        blah_src = '''\
foo = 1
blah ()
'''
        blah_path = self.write_file('base/blah.mwel', blah_src)

        something_src = '''\
baz {
    foo = 3
}
'''
        something_path = self.write_file('something.mwel', something_src)

        syntax_error_src = '''\
bar = = 1
'''
        syntax_error_path = self.write_file('syntax_error.foo',
                                            syntax_error_src)

        with self.parse(
                '''\
var foo = bar
%%include blah
bar = 2
%%include "../something.mwel"
foo bar () {}
%%include not_an_include
bar = foo
%%include '%s/syntax_error.foo'
bar = 1
%%include 'blah.mwel'  // Repeated include is OK
''' % self.tmpdir, basedir) as p:
            self.assertIsInstance(p, ast.Module)
            self.assertEqual(10, len(p.statements))

            self.assertEqual(
                ast.DeclarationStmt(type='var', tag='foo', value=self.bar),
                p.statements[0])

            blah = p.statements[1]
            self.assertIsInstance(blah, ast.Module)
            self.assertLocation(blah, 2, 2)
            self.assertEqual(blah_path, blah.filename)
            self.assertEqual(2, len(blah.statements))
            self.assertEqual(ast.AssignmentStmt(varname='foo', value=self.one),
                             blah.statements[0])
            self.assertEqual(ast.DeclarationStmt(type='blah'),
                             blah.statements[1])

            self.assertEqual(ast.AssignmentStmt(varname='bar', value=self.two),
                             p.statements[2])

            something = p.statements[3]
            self.assertIsInstance(something, ast.Module)
            self.assertLocation(something, 4, 2)
            self.assertEqual(something_path, something.filename)
            self.assertEqual(1, len(something.statements))
            self.assertEqual(
                ast.DeclarationStmt(type='baz',
                                    children=(ast.AssignmentStmt(
                                        varname='foo', value=self.three), )),
                something.statements[0])

            self.assertEqual(ast.DeclarationStmt(type='foo', tag='bar'),
                             p.statements[4])

            self.assertError(("Failed to open file '%s': "
                              "No such file or directory" %
                              os.path.join(basedir, 'not_an_include.mwel')),
                             lineno=6,
                             colno=2)
            not_an_include = p.statements[5]
            self.assertIsInstance(not_an_include, ast.Module)
            self.assertLocation(not_an_include, 6, 2)
            self.assertEqual(os.path.join(basedir, 'not_an_include.mwel'),
                             not_an_include.filename)
            self.assertEqual(0, len(not_an_include.statements))

            self.assertEqual(ast.AssignmentStmt(varname='bar', value=self.foo),
                             p.statements[6])

            self.assertError(token='=',
                             lineno=1,
                             colno=7,
                             filename=os.path.join(self.tmpdir,
                                                   'syntax_error.foo'))
            syntax_error = p.statements[7]
            self.assertIsInstance(syntax_error, ast.Module)
            self.assertLocation(syntax_error, 8, 2)
            self.assertEqual(syntax_error_path, syntax_error.filename)
            self.assertEqual(0, len(syntax_error.statements))

            self.assertEqual(ast.AssignmentStmt(varname='bar', value=self.one),
                             p.statements[8])

            blah_2 = p.statements[9]
            self.assertIsInstance(blah_2, ast.Module)
            self.assertLocation(blah_2, 10, 2)
            self.assertEqual(blah_path, blah_2.filename)
            self.assertEqual(0, len(blah_2.statements))

            self.assertIsInstance(self.parser.included_files, dict)
            self.assertEqual(3, len(self.parser.included_files))
            included_files = list(self.parser.included_files.items())
            self.assertEqual(blah_path, included_files[0][0])
            self.assertEqual(blah_src, included_files[0][1])
            self.assertEqual(something_path, included_files[1][0])
            self.assertEqual(something_src, included_files[1][1])
            self.assertEqual(syntax_error_path, included_files[2][0])
            self.assertEqual(syntax_error_src, included_files[2][1])
Пример #4
0
    def test_declaration_stmt(self):
        def test_decl(src,
                      typename,
                      tagname=None,
                      value=None,
                      params=(),
                      children=()):
            with self.parse(src) as p:
                self.assertIsInstance(p, ast.Module)
                self.assertEqual(1, len(p.statements))
                p = p.statements[0]

                self.assertIsInstance(p, ast.DeclarationStmt)
                self.assertLocation(p, 1, 1)
                self.assertEqual(typename, p.type)
                self.assertEqual(tagname, p.tag)
                self.assertEqual(value, p.value)
                self.assertIsInstance(p.params, (tuple, dict))
                self.assertEqual(params, p.params)
                self.assertIsInstance(p.children, tuple)
                self.assertEqual(children, p.children)

        #
        # Basics
        #

        test_decl('foo ()', 'foo')
        test_decl('foo ( \n  \n\n  \n )', 'foo')
        test_decl('foo/bar blah ()', 'foo/bar', 'blah')
        test_decl('foo (bar)', 'foo', params=(self.bar, ))
        test_decl(
            'foo ( \n \n 1 \n + \n \n foo \n )',
            'foo',
            params=(self.one_plus_foo, ),
        )
        test_decl('foo/bar (p1 = 1)', 'foo/bar', params={'p1': self.one})
        test_decl(
            'foo/bar (p1 = 1; p2 = 2; p3 = 3)',
            'foo/bar',
            params={
                'p1': self.one,
                'p2': self.two,
                'p3': self.three
            },
        )
        test_decl('''foo 'blah blah blah' (

                         p1 = 1

                         p2 = 2


                     )
                  ''',
                  'foo',
                  'blah blah blah',
                  params={
                      'p1': self.one,
                      'p2': self.two
                  })

        #
        # Expression lists
        #

        foo_bar = ast.ExprList(items=(self.foo, self.bar))
        one_two_three = ast.ExprList(items=(self.one, self.two, self.three))
        foo_to_bar = ast.RangeExpr(start=self.foo, stop=self.bar)

        test_decl('foo "bar" (foo, bar)', 'foo', 'bar', params=(foo_bar, ))
        test_decl('''foo/bar (
                         abc = 1,2,3
                         xyz = foo:bar
                     )
                  ''',
                  'foo/bar',
                  params={
                      'abc': one_two_three,
                      'xyz': foo_to_bar
                  })

        #
        # Children
        #

        # Empty child list
        test_decl('foo () {}', 'foo')
        test_decl('foo {}', 'foo')

        # One child
        test_decl(
            '''foo/bar (p1 = 1) {
                         x = 2
                     }
                  ''',
            'foo/bar',
            params={'p1': self.one},
            children=(ast.AssignmentStmt(varname='x', value=self.two), ),
        )

        # Multiple children
        test_decl(
            '''foo bar (p1 = 1; p2 = 2) { var foo = bar
                         x = 2
                         foo bar () {}
                     }
                  ''',
            'foo',
            'bar',
            params={
                'p1': self.one,
                'p2': self.two
            },
            children=(
                ast.DeclarationStmt(type='var', tag='foo', value=self.bar),
                ast.AssignmentStmt(varname='x', value=self.two),
                ast.DeclarationStmt(type='foo', tag='bar'),
            ),
        )

        #
        # Value
        #

        # No params or children
        test_decl('foo bar = 1', 'foo', 'bar', value=self.one)

        # Params
        test_decl('foo bar = 1 (p1 = 1)',
                  'foo',
                  'bar',
                  value=self.one,
                  params={'p1': self.one})

        # Children
        test_decl(
            '''foo/bar blah = 2 {
                         x = 2
                     }
                  ''',
            'foo/bar',
            'blah',
            value=self.two,
            children=(ast.AssignmentStmt(varname='x', value=self.two), ),
        )

        # Params and children
        test_decl(
            '''foo/bar blah = 2 (p1 = 1) {
                         x = 2
                     }
                  ''',
            'foo/bar',
            'blah',
            value=self.two,
            params={'p1': self.one},
            children=(ast.AssignmentStmt(varname='x', value=self.two), ),
        )

        #
        # Errors
        #

        # Bad sub-type
        with self.parse('foo/1 ()'):
            self.assertExpected('identifier', got='1')

        # Extra /
        with self.parse('''
                        foo/bar/blah ()
                        '''):
            self.assertExpected("'(' or '{'", got='/', colno=32)

        # No parentheses
        with self.parse('''
                        foo blah
                        bar abc ()
                        '''):
            self.assertExpected("'(' or '{'", lineno=2, colno=33)

        # Missing right paren
        with self.parse('''
                        foo blah (
                        bar abc ()
                        '''):
            self.assertExpected(')', got='abc')

        # Bad param name
        with self.parse('''
                        foo (
                            a = 1
                            'b' = 2
                        )
                        '''):
            self.assertExpected('identifier', got="'b'")

        # Missing =
        with self.parse('foo (a 1)'):
            self.assertExpected(')', got='1')

        # Missing value
        with self.parse('''
                        foo (
                            a =
                            b = 2
                        )
                        '''):
            self.assertError('Line ended unexpectedly', token='\n', lineno=3)

        # Missing newline or semicolon
        with self.parse('foo (a = 1 b = 2)'):
            self.assertExpected("line ending or ';'", got='b')

        # Extra semicolon
        with self.parse('foo (a = 1; b = 2;)'):
            self.assertExpected('identifier', got=')')

        # Missing right brace
        with self.parse('''
                        foo () {
                        x = 1
                        y = 2
                        bar ()
                        '''):
            self.assertError('Input ended unexpectedly')

        # Value without tag
        with self.parse('foo = 1 (b = 2)'):
            self.assertError('Missing newline at end of statement', token='(')
Пример #5
0
    def test_nested(self):
        os.makedirs(os.path.join(self.tmpdir, 'dir1/dir2'))
        os.makedirs(os.path.join(self.tmpdir, 'dir3/dir4'))

        include1_src = '''\
foo = 2
%include 'dir2/include2'
foo = 2
'''
        include1_path = self.write_file('dir1/include1.mwel', include1_src)

        include2_src = '''\
foo = 3
%include '../../dir3/dir4/include3'
foo = 3
'''
        include2_path = self.write_file('dir1/dir2/include2.mwel',
                                        include2_src)

        include3_src = '''\
bar = 1
%include include3  // Recursive include is OK
'''
        include3_path = self.write_file('dir3/dir4/include3.mwel',
                                        include3_src)

        with self.parse('''\
foo = 1
%include 'dir1/include1'
foo = 1
''', self.tmpdir) as p:
            self.assertIsInstance(p, ast.Module)
            self.assertEqual(3, len(p.statements))

            self.assertEqual(ast.AssignmentStmt(varname='foo', value=self.one),
                             p.statements[0])
            self.assertEqual(ast.AssignmentStmt(varname='foo', value=self.one),
                             p.statements[2])

            p = p.statements[1]
            self.assertIsInstance(p, ast.Module)
            self.assertEqual(3, len(p.statements))
            self.assertLocation(p, 2, 2)
            self.assertEqual(include1_path, p.filename)

            self.assertEqual(ast.AssignmentStmt(varname='foo', value=self.two),
                             p.statements[0])
            self.assertEqual(ast.AssignmentStmt(varname='foo', value=self.two),
                             p.statements[2])

            p = p.statements[1]
            self.assertIsInstance(p, ast.Module)
            self.assertEqual(3, len(p.statements))
            self.assertLocation(p, 2, 2)
            self.assertEqual(include2_path, p.filename)

            self.assertEqual(
                ast.AssignmentStmt(varname='foo', value=self.three),
                p.statements[0])
            self.assertEqual(
                ast.AssignmentStmt(varname='foo', value=self.three),
                p.statements[2])

            p = p.statements[1]
            self.assertIsInstance(p, ast.Module)
            self.assertEqual(2, len(p.statements))
            self.assertLocation(p, 2, 2)
            self.assertEqual(include3_path, p.filename)

            self.assertEqual(ast.AssignmentStmt(varname='bar', value=self.one),
                             p.statements[0])

            p = p.statements[1]
            self.assertIsInstance(p, ast.Module)
            self.assertEqual(0, len(p.statements))
            self.assertLocation(p, 2, 2)
            self.assertEqual(include3_path, p.filename)

            self.assertIsInstance(self.parser.included_files, dict)
            self.assertEqual(3, len(self.parser.included_files))
            included_files = list(self.parser.included_files.items())
            self.assertEqual(include1_path, included_files[0][0])
            self.assertEqual(include1_src, included_files[0][1])
            self.assertEqual(include2_path, included_files[1][0])
            self.assertEqual(include2_src, included_files[1][1])
            self.assertEqual(include3_path, included_files[2][0])
            self.assertEqual(include3_src, included_files[2][1])