eliben / pycparser

:snake: Complete C99 parser in pure Python
Other
3.21k stars 612 forks source link

Parehthesized compount statements #538

Open Mesyanzhin opened 4 months ago

Mesyanzhin commented 4 months ago

This expression are processed correctly:

            float __left_0 = (  {
              float __x1_1 = __K1;
              float __x2_1 = __K2;
              ( __x1_1 < __x2_1 ) ? __x1_1 : __x2_1;
            } );

But this valid expression

            float __df_3 = __iz_3 / (  {
              float __x1_4 = __T1;
              float __x2_4 = __T2;
              ( __x1_4 > __x2_4 ) ? __x1_4 : __x2_4;
            } );

causes a traceback with parsing error:

pycparser.plyparser.ParseError: :14:36: before: {

eliben commented 4 months ago

Can you provide a minimal, complete reproducer?

Mesyanzhin commented 4 months ago

Can you provide a minimal, complete reproducer?

pycparser version:

__version__ = '2.22'

Input:

from pycparser import c_parser, c_generator

src1 = '''
float f1( float __K1, float __K2 ) {
    float __left_0 = (  {
        float __x1_1 = __K1;
        float __x2_1 = __K2;
        ( __x1_1 < __x2_1 ) ? __x1_1 : __x2_1;
    } );
    return __left_0;
}
'''

src2 = '''
float f2( float __iz_3, float __T1, float __T2 ) {
    float __df_3 = __iz_3 / (  {
        float __x1_4 = __T1;
        float __x2_4 = __T2;
        ( __x1_4 > __x2_4 ) ? __x1_4 : __x2_4;
    } );
    return __df_3;
}
'''

def c2c(src):
    parser = c_parser.CParser()
    ast = parser.parse(src)
    generator = c_generator.CGenerator()
    return generator.visit(ast)

print(c2c(src1))
print(c2c(src2))

Output:

/home/artem/PycharmProjects/TestPy3/envs/bin/python /home/artem/PycharmProjects/TestPy3/c2c.py 
float f1(float __K1, float __K2)
{
  float __left_0 =   {
    float __x1_1 = __K1;
    float __x2_1 = __K2;
    (__x1_1 < __x2_1) ? (__x1_1) : (__x2_1);
  }
;
  return __left_0;
}

Traceback (most recent call last):
  File "/home/artem/PycharmProjects/TestPy3/c2c.py", line 32, in <module>
    print(c2c(src2))
  File "/home/artem/PycharmProjects/TestPy3/c2c.py", line 27, in c2c
    ast = parser.parse(src)
  File "/home/artem/PycharmProjects/TestPy3/pycparser/c_parser.py", line 147, in parse
    return self.cparser.parse(
  File "/home/artem/PycharmProjects/TestPy3/pycparser/ply/yacc.py", line 331, in parse
    return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
  File "/home/artem/PycharmProjects/TestPy3/pycparser/ply/yacc.py", line 1199, in parseopt_notrack
    tok = call_errorfunc(self.errorfunc, errtoken, self)
  File "/home/artem/PycharmProjects/TestPy3/pycparser/ply/yacc.py", line 193, in call_errorfunc
    r = errorfunc(token)
  File "/home/artem/PycharmProjects/TestPy3/pycparser/c_parser.py", line 1945, in p_error
    self._parse_error(
  File "/home/artem/PycharmProjects/TestPy3/pycparser/plyparser.py", line 67, in _parse_error
    raise ParseError("%s: %s" % (coord, msg))
pycparser.plyparser.ParseError: :3:32: before: {

Process finished with exit code 1
eliben commented 4 months ago

Thanks. This is probably not too hard to fix for someone motivated enough to dig into the code. PRs welcome :)