Skip to content

Commit

Permalink
Support for labels with no statement (#562)
Browse files Browse the repository at this point in the history
* Add possibility to omit semicolon in labeled statement

* Add extra rule to properly parse semicolons so that the ASTs remain equal. Add test corroborating equality of ASTs

* Remove unnecesary rule for labeled statements

* Update label test to check the structure of the AST

---------

Co-authored-by: Ignacio Tiraboschi <ignacio.tiraboschi@eclypsium.com>
  • Loading branch information
ignatirabo and Ignacio Tiraboschi authored Jan 13, 2025
1 parent 42b5423 commit 7ae671d
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
4 changes: 4 additions & 0 deletions pycparser/c_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1580,6 +1580,10 @@ def p_labeled_statement_3(self, p):
""" labeled_statement : DEFAULT COLON pragmacomp_or_statement """
p[0] = c_ast.Default([p[3]], self._token_coord(p, 1))

def p_labeled_statement_4(self, p):
""" labeled_statement : ID COLON """
p[0] = c_ast.Label(p[1], c_ast.EmptyStatement(self._token_coord(p, 1)), self._token_coord(p, 1))

def p_selection_statement_1(self, p):
""" selection_statement : IF LPAREN expression RPAREN pragmacomp_or_statement """
p[0] = c_ast.If(p[3], p[5], None, self._token_coord(p, 1))
Expand Down
14 changes: 14 additions & 0 deletions tests/test_c_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2489,6 +2489,20 @@ def test_samescope_reuse_name(self):
'''
self.assertRaises(ParseError, self.parse, s2)

def test_label_empty_statement(self):
# Labels with empty statements and no semicolon should be parsed correctly
s1 = r'''
int main() {
int i = 0;
label0: i++;
label1:
}
'''
s1_ast : FileAST = self.parse(s1)
self.assertIsInstance(s1_ast.ext[0].body.block_items[1], Label)
self.assertIsInstance(s1_ast.ext[0].body.block_items[1].stmt, UnaryOp)
self.assertIsInstance(s1_ast.ext[0].body.block_items[2], Label)
self.assertIsInstance(s1_ast.ext[0].body.block_items[2].stmt, EmptyStatement)

if __name__ == '__main__':
#~ suite = unittest.TestLoader().loadTestsFromNames(
Expand Down

0 comments on commit 7ae671d

Please # to comment.