summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJordan Yates <jordan.yates.au@gmail.com>2021-07-08 00:11:25 +1000
committerGitHub <noreply@github.com>2021-07-07 07:11:25 -0700
commit56b14671b558c06899ab475402e265fe4475bc18 (patch)
tree5427b4b4c69989f83fde6addce830c5d3a4a2eeb /tests
parentc819d537f32989364791b58493f1fec5ca3de062 (diff)
downloadpycparser-56b14671b558c06899ab475402e265fe4475bc18.tar.gz
c_parser: support parenthesized compounds (#423)
* c_parser: support parenthesized compounds Support parenthesized compound statements as described here: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au> * test_c_parser: support additional initializers Add support to `expand_init` for additional `c_ast` types. If a type is not explicitly handled, return the type name instead of `None`. Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au> * test_c_parser: test parenthesized compounds Add parsing tests for various situations of parenthesized compound statements. The complete tree generated by the test string is: ``` FileAST: FuncDef: Decl: foo, [], [], [] FuncDecl: TypeDecl: foo, [] IdentifierType: ['void'] Compound: Decl: a, [], [], [] TypeDecl: a, [] IdentifierType: ['int'] Compound: Compound: Constant: int, 1 Compound: Constant: int, 1 Constant: int, 2 Decl: b, [], [], [] TypeDecl: b, [] IdentifierType: ['int'] Compound: Constant: int, 1 Decl: c, [], [], [] TypeDecl: c, [] IdentifierType: ['int'] Decl: d, [], [], [] TypeDecl: d, [] IdentifierType: ['int'] Compound: Decl: x, [], [], [] TypeDecl: x, [] IdentifierType: ['int'] Constant: int, 1 BinaryOp: + ID: x Constant: int, 2 Assignment: = ID: a Compound: Decl: x, [], [], [] TypeDecl: x, [] IdentifierType: ['int'] Constant: int, 1 BinaryOp: * Constant: int, 2 ID: x ``` Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
Diffstat (limited to 'tests')
-rwxr-xr-xtests/test_c_parser.py53
1 files changed, 53 insertions, 0 deletions
diff --git a/tests/test_c_parser.py b/tests/test_c_parser.py
index f9f5281..a46fb1a 100755
--- a/tests/test_c_parser.py
+++ b/tests/test_c_parser.py
@@ -85,8 +85,20 @@ def expand_init(init):
return ['Constant', init.type, init.value]
elif typ == ID:
return ['ID', init.name]
+ elif typ == Decl:
+ return ['Decl', init.name]
elif typ == UnaryOp:
return ['UnaryOp', init.op, expand_decl(init.expr)]
+ elif typ == BinaryOp:
+ return ['BinaryOp', expand_init(init.left), init.op, expand_init(init.right)]
+ elif typ == Compound:
+ blocks = []
+ if init.block_items:
+ blocks = [expand_init(i) for i in init.block_items]
+ return ['Compound', blocks]
+ else:
+ # Fallback to type name
+ return [typ.__name__]
class TestCParser_base(unittest.TestCase):
@@ -612,6 +624,47 @@ class TestCParser_fundamentals(TestCParser_base):
([['ID', 'a']], [['Constant', 'int', '1'], ['Constant', 'int', '2']]),
([['ID', 'b'], ['Constant', 'int', '0']], ['ID', 't'])])
+ def test_parenthesized_compounds(self):
+ e = self.parse(r'''
+ void foo() {
+ int a;
+ ({});
+ ({ 1; });
+ ({ 1; 2; });
+ int b = ({ 1; });
+ int c, d = ({ int x = 1; x + 2; });
+ a = ({ int x = 1; 2 * x; });
+ }''')
+ body = e.ext[0].body.block_items
+
+ self.assertIsInstance(body[1], Compound)
+ self.assertEqual(body[1].block_items, None)
+
+ self.assertIsInstance(body[2], Compound)
+ self.assertEqual(len(body[2].block_items), 1)
+ self.assertIsInstance(body[2].block_items[0], Constant)
+
+ self.assertIsInstance(body[3], Compound)
+ self.assertEqual(len(body[3].block_items), 2)
+ self.assertIsInstance(body[3].block_items[0], Constant)
+ self.assertIsInstance(body[3].block_items[1], Constant)
+
+ self.assertIsInstance(body[4], Decl)
+ self.assertEqual(expand_init(body[4].init),
+ ['Compound', [['Constant', 'int', '1']]])
+
+ self.assertIsInstance(body[5], Decl)
+ self.assertEqual(body[5].init, None)
+
+ self.assertIsInstance(body[6], Decl)
+ self.assertEqual(expand_init(body[6].init),
+ ['Compound', [['Decl', 'x'], ['BinaryOp', ['ID', 'x'], '+', ['Constant', 'int', '2']]]])
+
+ self.assertIsInstance(body[7], Assignment)
+ self.assertIsInstance(body[7].rvalue, Compound)
+ self.assertEqual(expand_init(body[7].rvalue),
+ ['Compound', [['Decl', 'x'], ['BinaryOp', ['Constant', 'int', '2'], '*', ['ID', 'x']]]])
+
def test_enums(self):
e1 = "enum mycolor op;"
e1_type = self.parse(e1).ext[0].type.type