Example #1
0
 def test_multiplication_in_parentheses_and_binary_minus(self):
     # This is tricky because it's not a cast and an unary minus.  To fully
     # distinguish those cases we would need to know what identifiers are
     # types and what identifiers are variables, e.g.
     #         (x) - y
     # depends on the meaning of x. If x is a type then it can be a cast and
     # an unary minus, if x is a variable then it is a binary minus.
     source = '(a * b) - c'
     actual = self.parser.parse(source)
     expected = c_ast.CFunctionCall(
         function_name='-',
         arguments=[
             c_ast.CNestedExpression(opener='(',
                                     content=c_ast.CFunctionCall(
                                         function_name='*',
                                         arguments=[
                                             c_ast.CVariable('a'),
                                             c_ast.CVariable('b'),
                                         ],
                                     ),
                                     closer=')'),
             c_ast.CVariable('c'),
         ],
     )
     self.assertASTEqual(actual, expected)
Example #2
0
 def test_parse_logical_or_and_negation(self):
     source = 'someFunction(a) || !defined(b) || c < 2'
     expected = c_ast.CFunctionCall(
         function_name='||',
         arguments=[
             c_ast.CFunctionCall(
                 function_name='||',
                 arguments=[
                     c_ast.CFunctionCall(
                         function_name='someFunction',
                         arguments=[c_ast.CVariable('a')],
                     ),
                     c_ast.CFunctionCall(
                         function_name='!',
                         arguments=[
                             c_ast.CFunctionCall(
                                 function_name='defined',
                                 arguments=[c_ast.CVariable('b')],
                             )
                         ],
                     ),
                 ],
             ),
             c_ast.CFunctionCall(
                 function_name='<',
                 arguments=[
                     c_ast.CVariable('c'),
                     c_ast.CNumber(2),
                 ],
             ),
         ],
     )
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Example #3
0
 def test_parse_unary_operator_on_expression_in_parentheses(self):
     source = '!(x > 0 || y == 0)'
     expected = c_ast.CFunctionCall(
         function_name='!',
         arguments=[
             c_ast.CNestedExpression(
                 opener='(',
                 content=c_ast.CFunctionCall(
                     function_name='||',
                     arguments=[
                         c_ast.CFunctionCall(
                             function_name='>',
                             arguments=[
                                 c_ast.CVariable('x'),
                                 c_ast.CNumber(0),
                             ],
                         ),
                         c_ast.CFunctionCall(
                             function_name='==',
                             arguments=[
                                 c_ast.CVariable('y'),
                                 c_ast.CNumber(0),
                             ],
                         ),
                     ],
                 ),
                 closer=')',
             ),
         ],
     )
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Example #4
0
 def test_parse_array_expression(self):
     source = 't[x]'
     actual = self.parser.parse(source)
     expected = c_ast.CFunctionCall(
         function_name='[]',
         arguments=[
             c_ast.CVariable('t'),
             c_ast.CVariable('x'),
         ],
     )
     self.assertASTEqual(actual, expected)
Example #5
0
 def test_parse_ternary_conditional(self):
     source = 'a ? b : c'
     actual = self.parser.parse(source)
     expected = c_ast.CFunctionCall(
         function_name='?:',
         arguments=[
             c_ast.CVariable('a'),
             c_ast.CVariable('b'),
             c_ast.CVariable('c'),
         ],
     )
     self.assertASTEqual(actual, expected)
Example #6
0
 def test_parse_function_call_with_multiword_argument(self):
     source = 'f(union u)'
     expected = c_ast.CFunctionCall(
         function_name='f',
         arguments=[
             pre_ast.CompositeBlock([
                 c_ast.CVariable('union'),
                 c_ast.CVariable('u'),
             ]),
         ],
     )
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Example #7
0
 def test_parse_addition_and_multiplication_precedence(self):
     source = 'a + b * c'
     expected = c_ast.CFunctionCall(function_name='+',
                                    arguments=[
                                        c_ast.CVariable('a'),
                                        c_ast.CFunctionCall(
                                            function_name='*',
                                            arguments=[
                                                c_ast.CVariable('b'),
                                                c_ast.CVariable('c'),
                                            ])
                                    ])
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Example #8
0
 def test_parse_parentheses_and_binary_plus(self):
     source = '(a) + b'
     actual = self.parser.parse(source)
     expected = c_ast.CFunctionCall(
         function_name='+',
         arguments=[
             c_ast.CNestedExpression(
                 opener='(',
                 content=c_ast.CVariable('a'),
                 closer=')',
             ),
             c_ast.CVariable('b'),
         ],
     )
     self.assertASTEqual(actual, expected)
Example #9
0
    def test_parse_variable_in_parentheses2(self):
        # Unfortunately our parser is not that great since it misidentifies the
        # below with & is substituted for +. It accidentally considers it the
        # dereference operator.  I dont think there is a way to properly parse
        # without context (i.e. cant make a context free grammer) because you
        # need to resolve the RHS to the & operator to know if it makes sense.
        source = '(((x) + 1) | 2)'
        actual = self.parser.parse(source)
        expected = c_ast.CNestedExpression(
            opener='(',
            closer=')',
            content=c_ast.CFunctionCall(
                function_name="|",
                arguments=[
                    c_ast.CNestedExpression(
                        opener='(',
                        closer=')',
                        content=c_ast.CFunctionCall(
                            function_name="+",
                            arguments=[
                                c_ast.CNestedExpression(
                                    opener='(',
                                    content=c_ast.CVariable('x'),
                                    closer=')',
                                ),
                                c_ast.CNumber(1),
                            ])),
                    c_ast.CNumber(2)
                ]))

        self.assertASTEqual(actual, expected)
Example #10
0
 def test_visit_nested_expression(self):
     expression = c_ast.CNestedExpression(
         opener='(',
         content=c_ast.CVariable('a'),
         closer=')',
     )
     actual = self.expression_evaluator.evaluate(expression)
     self.assertEqual(actual, 1)
Example #11
0
 def test_parse_defined_function_like(self):
     source = 'defined(CONFIG_SOMETHING)'
     expected = c_ast.CFunctionCall(
         function_name='defined',
         arguments=[c_ast.CVariable('CONFIG_SOMETHING')],
     )
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Example #12
0
 def test_parse_same_precedence_operators_plus_and_plus(self):
     source = 'a + b + c'
     expected = c_ast.CFunctionCall(
         function_name='+',
         arguments=[
             c_ast.CFunctionCall(
                 function_name='+',
                 arguments=[
                     c_ast.CVariable('a'),
                     c_ast.CVariable('b'),
                 ],
             ),
             c_ast.CVariable('c'),
         ],
     )
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Example #13
0
 def test_parse_binary_operator_with_function_calls(self):
     source = 'defined(CONFIG_SOMETHING) && defined(CONFIG_SOMETHING_ELSE)'
     expected = c_ast.CFunctionCall(
         function_name='&&',
         arguments=[
             c_ast.CFunctionCall(
                 function_name='defined',
                 arguments=[c_ast.CVariable('CONFIG_SOMETHING')],
             ),
             c_ast.CFunctionCall(
                 function_name='defined',
                 arguments=[c_ast.CVariable('CONFIG_SOMETHING_ELSE')],
             ),
         ],
     )
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Example #14
0
 def test_parse_function_call_with_one_argument(self):
     source = 'f(a)'
     expected = c_ast.CFunctionCall(
         function_name='f',
         arguments=[c_ast.CVariable('a')],
     )
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Example #15
0
 def test_parse_unary_operator_with_variable(self):
     for unary_operator in self.unary_operators:
         source = unary_operator + 'CONFIG_SOMETHING'
         actual = self.parser.parse(source)
         expected = c_ast.CFunctionCall(
             function_name=unary_operator,
             arguments=[c_ast.CVariable('CONFIG_SOMETHING')],
         )
         self.assertASTEqual(actual, expected)
Example #16
0
 def test_parse_variable_in_parentheses(self):
     source = '(x)'
     expected = c_ast.CNestedExpression(
         opener='(',
         content=c_ast.CVariable('x'),
         closer=')',
     )
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Example #17
0
 def test_parse_parentheses_with_addition_and_multiplication(self):
     source = '(a + b) * c'
     expected = c_ast.CFunctionCall(function_name='*',
                                    arguments=[
                                        c_ast.CNestedExpression(
                                            opener='(',
                                            content=c_ast.CFunctionCall(
                                                function_name='+',
                                                arguments=[
                                                    c_ast.CVariable('a'),
                                                    c_ast.CVariable('b'),
                                                ],
                                            ),
                                            closer=')',
                                        ),
                                        c_ast.CVariable('c'),
                                    ])
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Example #18
0
 def test_parse_attribute(self):
     source = '__attribute__((x))'
     expected = c_ast.CFunctionCall(
         function_name='__attribute__',
         arguments=[
             c_ast.CVariable('x'),
         ],
     )
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Example #19
0
 def test_parse_complex_parentheses_expression(self):
     source = '(((x) + (y)) & ~(y))'
     actual = self.parser.parse(source)
     expected = c_ast.CNestedExpression(
         opener='(',
         content=c_ast.CFunctionCall(
             function_name='&',
             arguments=[
                 c_ast.CNestedExpression(
                     opener='(',
                     content=c_ast.CFunctionCall(
                         function_name='+',
                         arguments=[
                             c_ast.CNestedExpression(
                                 opener='(',
                                 content=c_ast.CVariable('x'),
                                 closer=')',
                             ),
                             c_ast.CNestedExpression(
                                 opener='(',
                                 content=c_ast.CVariable('y'),
                                 closer=')',
                             ),
                         ],
                     ),
                     closer=')',
                 ),
                 c_ast.CFunctionCall(
                     function_name='~',
                     arguments=[
                         c_ast.CNestedExpression(
                             opener='(',
                             content=c_ast.CVariable('y'),
                             closer=')',
                         ),
                     ],
                 ),
             ],
         ),
         closer=')',
     )
     self.assertASTEqual(actual, expected)
Example #20
0
 def test_parse_binary_operator_with_variable_and_number(self):
     for binary_operator in self.binary_operators:
         source = '51' + binary_operator + 'CONFIG_SOMETHING'
         actual = self.parser.parse(source)
         expected = c_ast.CFunctionCall(
             function_name=binary_operator,
             arguments=[
                 c_ast.CNumber(51),
                 c_ast.CVariable('CONFIG_SOMETHING'),
             ])
         self.assertASTEqual(actual, expected)
Example #21
0
 def test_parse_function_call_with_two_arguments(self):
     source = 'f(a, 42)'
     expected = c_ast.CFunctionCall(
         function_name='f',
         arguments=[
             c_ast.CVariable('a'),
             c_ast.CNumber(42),
         ],
     )
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Example #22
0
 def test_parse_binary_operators_with_parentheses_on_right(self):
     source = 'x < 4 || (y == 4 && z < 1)'
     expected = c_ast.CFunctionCall(
         function_name='||',
         arguments=[
             c_ast.CFunctionCall(
                 function_name='<',
                 arguments=[
                     c_ast.CVariable('x'),
                     c_ast.CNumber(4),
                 ],
             ),
             c_ast.CNestedExpression(
                 opener='(',
                 content=c_ast.CFunctionCall(
                     function_name='&&',
                     arguments=[
                         c_ast.CFunctionCall(
                             function_name='==',
                             arguments=[
                                 c_ast.CVariable('y'),
                                 c_ast.CNumber(4),
                             ],
                         ),
                         c_ast.CFunctionCall(
                             function_name='<',
                             arguments=[
                                 c_ast.CVariable('z'),
                                 c_ast.CNumber(1),
                             ],
                         ),
                     ],
                 ),
                 closer=')',
             ),
         ],
     )
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Example #23
0
 def test_parse_comparison_and_shift_with_parentheses_on_right(self):
     source = 'x < (1 << 14)'
     expected = c_ast.CFunctionCall(
         function_name='<',
         arguments=[
             c_ast.CVariable('x'),
             c_ast.CNestedExpression(
                 opener='(',
                 content=c_ast.CFunctionCall(function_name='<<',
                                             arguments=[
                                                 c_ast.CNumber(1),
                                                 c_ast.CNumber(14),
                                             ]),
                 closer=')',
             ),
         ],
     )
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Example #24
0
 def test_parse_variable(self):
     source = 'CONFIG_SOMETHING'
     expected = c_ast.CVariable('CONFIG_SOMETHING')
     actual = self.parser.parse(source)
     self.assertASTEqual(actual, expected)
Example #25
0
 def test_visit_variable(self):
     variable = c_ast.CVariable('c')
     actual = self.expression_evaluator.evaluate(variable)
     self.assertEqual(actual, 2)