Commit fb4fefc6 authored by scoder's avatar scoder Committed by GitHub

Improve error reporting when users mistakenly write "&&" or "||" instead of...

Improve error reporting when users mistakenly write "&&" or "||" instead of Python's "and" and "or" operators. (GH-3858)
parent ba6cbed8
......@@ -77,7 +77,7 @@ def make_lexicon():
punct = Any(":,;+-*/|&<>=.%`~^?!@")
diphthong = Str("==", "<>", "!=", "<=", ">=", "<<", ">>", "**", "//",
"+=", "-=", "*=", "/=", "%=", "|=", "^=", "&=",
"<<=", ">>=", "**=", "//=", "->", "@=", "&&")
"<<=", ">>=", "**=", "//=", "->", "@=", "&&", "||")
spaces = Rep1(Any(" \t\f"))
escaped_newline = Str("\\\n")
lineterm = Eol + Opt(Str("\n"))
......
......@@ -26,7 +26,7 @@ cdef p_lambdef_nocond(PyrexScanner s)
cdef p_test(PyrexScanner s)
cdef p_test_nocond(PyrexScanner s)
cdef p_or_test(PyrexScanner s)
cdef p_rassoc_binop_expr(PyrexScanner s, ops, p_sub_expr_func p_subexpr)
cdef p_rassoc_binop_expr(PyrexScanner s, unicode op, p_sub_expr_func p_subexpr)
cdef p_and_test(PyrexScanner s)
cdef p_not_test(PyrexScanner s)
cdef p_comparison(PyrexScanner s)
......
......@@ -14,7 +14,7 @@ cython.declare(Nodes=object, ExprNodes=object, EncodedString=object,
Builtin=object, ModuleNode=object, Utils=object, _unicode=object, _bytes=object,
re=object, sys=object, _parse_escape_sequences=object, _parse_escape_sequences_raw=object,
partial=object, reduce=object, _IS_PY3=cython.bint, _IS_2BYTE_UNICODE=cython.bint,
_CDEF_MODIFIERS=tuple)
_CDEF_MODIFIERS=tuple, COMMON_BINOP_MISTAKES=dict)
from io import StringIO
import re
......@@ -159,24 +159,31 @@ def p_test_nocond(s):
#or_test: and_test ('or' and_test)*
COMMON_BINOP_MISTAKES = {'||': 'or', '&&': 'and'}
def p_or_test(s):
return p_rassoc_binop_expr(s, ('or',), p_and_test)
return p_rassoc_binop_expr(s, u'or', p_and_test)
def p_rassoc_binop_expr(s, ops, p_subexpr):
def p_rassoc_binop_expr(s, op, p_subexpr):
n1 = p_subexpr(s)
if s.sy in ops:
if s.sy == op:
pos = s.position()
op = s.sy
s.next()
n2 = p_rassoc_binop_expr(s, ops, p_subexpr)
n2 = p_rassoc_binop_expr(s, op, p_subexpr)
n1 = ExprNodes.binop_node(pos, op, n1, n2)
elif s.sy in COMMON_BINOP_MISTAKES and COMMON_BINOP_MISTAKES[s.sy] == op:
# Only report this for the current operator since we pass through here twice for 'and' and 'or'.
warning(s.position(),
"Found the C operator '%s', did you mean the Python operator '%s'?" % (s.sy, op),
level=1)
return n1
#and_test: not_test ('and' not_test)*
def p_and_test(s):
#return p_binop_expr(s, ('and',), p_not_test)
return p_rassoc_binop_expr(s, ('and',), p_not_test)
return p_rassoc_binop_expr(s, u'and', p_not_test)
#not_test: 'not' not_test | comparison
......
# mode: error
# tag: and, binop, warnings
def test_and(a, b):
return a && b
_WARNINGS = """
5:13: Found the C operator '&&', did you mean the Python operator 'and'?
"""
_ERRORS = """
5:13: Syntax error in simple statement list
"""
# mode: error
# tag: or, binop, warnings
def test_or(a, b):
return a || b
_WARNINGS = """
5:13: Found the C operator '||', did you mean the Python operator 'or'?
"""
_ERRORS = """
5:13: Syntax error in simple statement list
"""
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment