lcompilers / lpython

Python compiler
https://lpython.org/
Other
1.5k stars 159 forks source link

[Old] More than one Comparision operator is not recognized by the OId parser #814

Open Thirumalai-Shaktivel opened 2 years ago

Thirumalai-Shaktivel commented 2 years ago

Example:

a = all(0 < x < 20 for x in numbers)

causes Old parser Error:

$ lpython --show-ast examples/expr2.py --tree             
Traceback (most recent call last):
  File "/home/thirumalai/Open_Source/lpython/src/bin/../runtime/lpython_parser.py", line 110, in <module>
    a2 = v.visit(a)
  File "/home/thirumalai/conda_root/envs/lf/lib/python3.10/ast.py", line 410, in visit
    return visitor(node)
  File "/home/thirumalai/Open_Source/lpython/src/bin/../runtime/lpython_parser.py", line 77, in generic_visit
    new_list.append(self.visit(item))
  File "/home/thirumalai/conda_root/envs/lf/lib/python3.10/ast.py", line 410, in visit
    return visitor(node)
  File "/home/thirumalai/Open_Source/lpython/src/bin/../runtime/lpython_parser.py", line 88, in generic_visit
    d[field] = self.visit(value)
  File "/home/thirumalai/conda_root/envs/lf/lib/python3.10/ast.py", line 410, in visit
    return visitor(node)
  File "/home/thirumalai/Open_Source/lpython/src/bin/../runtime/lpython_parser.py", line 77, in generic_visit
    new_list.append(self.visit(item))
  File "/home/thirumalai/conda_root/envs/lf/lib/python3.10/ast.py", line 410, in visit
    return visitor(node)
  File "/home/thirumalai/Open_Source/lpython/src/bin/../runtime/lpython_parser.py", line 88, in generic_visit
    d[field] = self.visit(value)
  File "/home/thirumalai/conda_root/envs/lf/lib/python3.10/ast.py", line 410, in visit
    return visitor(node)
  File "/home/thirumalai/Open_Source/lpython/src/bin/../runtime/lpython_parser.py", line 71, in generic_visit
    assert len(value) == 1
AssertionError
The command 'python /home/thirumalai/Open_Source/lpython/src/bin/../runtime/lpython_parser.py examples/expr2.py examples/expr2.pyDCA6071' failed.
Internal Compiler Error: Unhandled exception
Traceback (most recent call last):
  Binary file "/home/thirumalai/Open_Source/lpython/src/bin/lpython", in _start()
  File "./csu/../csu/libc-start.c", line 392, in __libc_start_main_impl()
  File "./csu/../sysdeps/nptl/libc_start_call_main.h", line 58, in __libc_start_call_main()
  File "/home/thirumalai/Open_Source/lpython/src/bin/lpython.cpp", line 827, in ??
    return emit_ast(arg_file, runtime_library_dir, compiler_options);
AssertFailed: diagnostics.has_error()

Originally posted by @akshanshbhatt in https://github.com/lcompilers/lpython/issues/786#issuecomment-1188659782

Thirumalai-Shaktivel commented 2 years ago

https://github.com/lcompilers/lpython/blob/819bb6e95821b53d98dfa34716a7d1629609c845/src/runtime/lpython_parser.py#L69-L71

certik commented 2 years ago

Yes, we'll have to fix this in both the old and new parser.

certik commented 2 years ago

For this, we need to do something like:

--- a/grammar/Python.asdl
+++ b/grammar/Python.asdl
@@ -72,7 +72,7 @@ module LPython
          | YieldFrom(expr value)
          -- need sequences for compare to distinguish between
          -- x < 4 < 3 and (x < 4) < 3
-         | Compare(expr left, cmpop ops, expr* comparators)
+         | Compare(expr left, cmpop2* ops, expr* comparators)
          | Call(expr func, expr* args, keyword* keywords)
          | FormattedValue(expr value, int conversion, expr? format_spec)
          | JoinedStr(expr* values)
@@ -112,6 +112,8 @@ module LPython

     cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn

+    cmpop2 = (cmpop op)
+
     comprehension = (expr target, expr iter, expr* ifs, int is_async)

     excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body)