inducer / pycparserext

Extensions for Eli Bendersky's pycparser
http://pypi.python.org/pypi/pycparserext
Other
82 stars 28 forks source link

type cast parsing error in (__typeof(h))spa_meta_first(m) line, __typeof(h) type is not allowed by parser rules #79

Closed retif closed 3 months ago

retif commented 3 months ago

Hello, while trying to run project https://gitlab.com/matpi/pipewire-py

I get an error

State  : 484
Stack  : declaration_specifiers id_declarator declaration_list_opt brace_open unary_expression assignment_operator LPAREN expression RPAREN . LexToken(ID,'spa_meta_first',3,138)
ERROR: Error  : declaration_specifiers id_declarator declaration_list_opt brace_open unary_expression assignment_operator LPAREN expression RPAREN . LexToken(ID,'spa_meta_first',3,138)
Traceback (most recent call last):
  File "/home/oleks/projects/pipewire-py/bug/program.py", line 17, in <module>
    parser.parse(PREPROCESSED_SOURCE, debuglevel=True)
  File "/home/oleks/.local/lib/python3.12/site-packages/pycparserext/ext_c_parser.py", line 33, in parse
    return self.cparser.parse(text, lexer=self.clex, debug=debuglevel)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/oleks/.local/lib/python3.12/site-packages/pycparser/ply/yacc.py", line 327, in parse
    return self.parsedebug(input, lexer, debug, tracking, tokenfunc)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/oleks/.local/lib/python3.12/site-packages/pycparser/ply/yacc.py", line 601, in parsedebug
    tok = call_errorfunc(self.errorfunc, errtoken, self)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/oleks/.local/lib/python3.12/site-packages/pycparser/ply/yacc.py", line 193, in call_errorfunc
    r = errorfunc(token)
        ^^^^^^^^^^^^^^^^
  File "/home/oleks/.local/lib/python3.12/site-packages/pycparser/c_parser.py", line 1945, in p_error
    self._parse_error(
  File "/home/oleks/.local/lib/python3.12/site-packages/pycparser/plyparser.py", line 67, in _parse_error
    raise ParseError("%s: %s" % (coord, msg))
pycparser.plyparser.ParseError: :3:24: before: spa_meta_first

Here is the test python code with extracted code sample leading to the error

import pycparserext.ext_c_parser
import pycparserext.ext_c_generator

PREPROCESSED_SOURCE = """
static inline int spa_debugc_buffer(struct spa_debug_context *ctx, int indent, const struct spa_buffer *buffer) {
    (h) = (__typeof(h))spa_meta_first(m);

    for ((h) = (__typeof(h))spa_meta_first(m);  spa_meta_check(h, m);   (h)++) {

    }

    return 0;
}
"""

parser = pycparserext.ext_c_parser.GnuCParser(yacc_debug=True)
parser.parse(PREPROCESSED_SOURCE, debuglevel=True)

The error happens at (h) = (__typeof(h))spa_meta_first(m); because of __typeof(h) type casting which seems not considered as a valid cast type for a parser, but initial code source uses this construct and compiles fine. This is a pcpp.Preprocessor preprocessed code from https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/spa/include/spa/buffer/meta.h?ref_type=heads#L90

Is this a parser bug?

inducer commented 3 months ago

Could be. pycparserext defines typeof expressions as type_specifier for pycparser. You could look in pycparser as to why that might not be allowed in a cast context.