Commit 28f739aa authored by Fred Drake's avatar Fred Drake

Update the parser module to support augmented assignment.

Add some test cases.
parent 6ef68b5b
test_parser test_parser
Expressions: Expressions:
foo(1) expr: foo(1)
[1, 2, 3] expr: [1, 2, 3]
[x**3 for x in range(20)] expr: [x**3 for x in range(20)]
[x**3 for x in range(20) if x % 3] expr: [x**3 for x in range(20) if x % 3]
foo(*args) expr: foo(*args)
foo(*args, **kw) expr: foo(*args, **kw)
foo(**kw) expr: foo(**kw)
foo(key=value) expr: foo(key=value)
foo(key=value, *args) expr: foo(key=value, *args)
foo(key=value, *args, **kw) expr: foo(key=value, *args, **kw)
foo(key=value, **kw) expr: foo(key=value, **kw)
foo(a, b, c, *args) expr: foo(a, b, c, *args)
foo(a, b, c, *args, **kw) expr: foo(a, b, c, *args, **kw)
foo(a, b, c, **kw) expr: foo(a, b, c, **kw)
foo + bar expr: foo + bar
Statements: Statements:
print suite: print
print 1 suite: print 1
print 1, suite: print 1,
print >>fp suite: print >>fp
print >>fp, 1 suite: print >>fp, 1
print >>fp, 1, suite: print >>fp, 1,
suite: a
suite: a = b
suite: a = b = c = d = e
suite: a += b
suite: a -= b
suite: a *= b
suite: a /= b
suite: a %= b
suite: a &= b
suite: a |= b
suite: a ^= b
suite: a <<= b
suite: a >>= b
suite: a **= b
Invalid parse trees: Invalid parse trees:
...@@ -34,3 +48,6 @@ caught expected exception for invalid tree ...@@ -34,3 +48,6 @@ caught expected exception for invalid tree
a,,c a,,c
caught expected exception for invalid tree caught expected exception for invalid tree
a $= b
caught expected exception for invalid tree
import os.path
import parser import parser
import pprint import pprint
import sys import sys
...@@ -12,38 +13,68 @@ from test_support import verbose ...@@ -12,38 +13,68 @@ from test_support import verbose
# #
def roundtrip(f, s): def roundtrip(f, s):
print s
st1 = f(s) st1 = f(s)
t = st1.totuple() t = st1.totuple()
st2 = parser.sequence2ast(t) st2 = parser.sequence2ast(t)
def roundtrip_fromfile(filename):
roundtrip(suite, open(filename).read())
def test_expr(s):
print "expr:", s
roundtrip(expr, s)
def test_suite(s):
print "suite:", s
roundtrip(suite, s)
print "Expressions:" print "Expressions:"
roundtrip(expr, "foo(1)") test_expr("foo(1)")
roundtrip(expr, "[1, 2, 3]") test_expr("[1, 2, 3]")
roundtrip(expr, "[x**3 for x in range(20)]") test_expr("[x**3 for x in range(20)]")
roundtrip(expr, "[x**3 for x in range(20) if x % 3]") test_expr("[x**3 for x in range(20) if x % 3]")
roundtrip(expr, "foo(*args)") test_expr("foo(*args)")
roundtrip(expr, "foo(*args, **kw)") test_expr("foo(*args, **kw)")
roundtrip(expr, "foo(**kw)") test_expr("foo(**kw)")
roundtrip(expr, "foo(key=value)") test_expr("foo(key=value)")
roundtrip(expr, "foo(key=value, *args)") test_expr("foo(key=value, *args)")
roundtrip(expr, "foo(key=value, *args, **kw)") test_expr("foo(key=value, *args, **kw)")
roundtrip(expr, "foo(key=value, **kw)") test_expr("foo(key=value, **kw)")
roundtrip(expr, "foo(a, b, c, *args)") test_expr("foo(a, b, c, *args)")
roundtrip(expr, "foo(a, b, c, *args, **kw)") test_expr("foo(a, b, c, *args, **kw)")
roundtrip(expr, "foo(a, b, c, **kw)") test_expr("foo(a, b, c, **kw)")
roundtrip(expr, "foo + bar") test_expr("foo + bar")
print print
print "Statements:" print "Statements:"
roundtrip(suite, "print") test_suite("print")
roundtrip(suite, "print 1") test_suite("print 1")
roundtrip(suite, "print 1,") test_suite("print 1,")
roundtrip(suite, "print >>fp") test_suite("print >>fp")
roundtrip(suite, "print >>fp, 1") test_suite("print >>fp, 1")
roundtrip(suite, "print >>fp, 1,") test_suite("print >>fp, 1,")
# expr_stmt
test_suite("a")
test_suite("a = b")
test_suite("a = b = c = d = e")
test_suite("a += b")
test_suite("a -= b")
test_suite("a *= b")
test_suite("a /= b")
test_suite("a %= b")
test_suite("a &= b")
test_suite("a |= b")
test_suite("a ^= b")
test_suite("a <<= b")
test_suite("a >>= b")
test_suite("a **= b")
#d = os.path.dirname(os.__file__)
#roundtrip_fromfile(os.path.join(d, "os.py"))
#roundtrip_fromfile(os.path.join(d, "test", "test_parser.py"))
# #
# Second, we take *invalid* trees and make sure we get ParserError # Second, we take *invalid* trees and make sure we get ParserError
...@@ -114,3 +145,34 @@ tree = \ ...@@ -114,3 +145,34 @@ tree = \
(0, '')) (0, ''))
check_bad_tree(tree, "a,,c") check_bad_tree(tree, "a,,c")
# a $= b
tree = \
(257,
(264,
(265,
(266,
(267,
(312,
(291,
(292,
(293,
(294,
(296,
(297,
(298,
(299, (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
(268, (37, '$=')),
(312,
(291,
(292,
(293,
(294,
(296,
(297,
(298,
(299, (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
(4, ''))),
(0, ''))
check_bad_tree(tree, "a $= b")
...@@ -1467,10 +1467,34 @@ validate_expr_stmt(node *tree) ...@@ -1467,10 +1467,34 @@ validate_expr_stmt(node *tree)
&& is_odd(nch) && is_odd(nch)
&& validate_testlist(CHILD(tree, 0))); && validate_testlist(CHILD(tree, 0)));
for (j = 1; res && (j < nch); j += 2) if (res && nch == 3
res = (validate_equal(CHILD(tree, j)) && TYPE(CHILD(tree, 1)) == augassign) {
&& validate_testlist(CHILD(tree, j + 1))); res = (validate_numnodes(CHILD(tree, 1), 1, "augassign")
&& validate_testlist(CHILD(tree, 2)));
if (res) {
char *s = STR(CHILD(CHILD(tree, 1), 0));
res = (strcmp(s, "+=") == 0
|| strcmp(s, "-=") == 0
|| strcmp(s, "*=") == 0
|| strcmp(s, "/=") == 0
|| strcmp(s, "%=") == 0
|| strcmp(s, "&=") == 0
|| strcmp(s, "|=") == 0
|| strcmp(s, "^=") == 0
|| strcmp(s, "<<=") == 0
|| strcmp(s, ">>=") == 0
|| strcmp(s, "**=") == 0);
if (!res)
err_string("illegal augmmented assignment operator");
}
}
else {
for (j = 1; res && (j < nch); j += 2)
res = (validate_equal(CHILD(tree, j))
&& validate_testlist(CHILD(tree, j + 1)));
}
return (res); return (res);
} }
...@@ -2822,9 +2846,11 @@ static PyMethodDef parser_functions[] = { ...@@ -2822,9 +2846,11 @@ static PyMethodDef parser_functions[] = {
}; };
DL_IMPORT(void) initparser(void);
DL_EXPORT(void) DL_EXPORT(void)
initparser(void) initparser(void)
{ {
PyObject* module; PyObject* module;
PyObject* dict; PyObject* dict;
...@@ -2834,8 +2860,6 @@ initparser(void) ...@@ -2834,8 +2860,6 @@ initparser(void)
if (parser_error == 0) if (parser_error == 0)
parser_error = PyErr_NewException("parser.ParserError", NULL, NULL); parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
else
puts("parser module initialized more than once!");
if ((parser_error == 0) if ((parser_error == 0)
|| (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) { || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
......
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