📄 parsermodule.c
字号:
int res = (validate_ntype(tree, exec_stmt)
&& ((nch == 2) || (nch == 4) || (nch == 6))
&& validate_name(CHILD(tree, 0), "exec")
&& validate_expr(CHILD(tree, 1)));
if (!res && !PyErr_Occurred())
err_string("illegal exec statement");
if (res && (nch > 2))
res = (validate_name(CHILD(tree, 2), "in")
&& validate_test(CHILD(tree, 3)));
if (res && (nch == 6))
res = (validate_comma(CHILD(tree, 4))
&& validate_test(CHILD(tree, 5)));
return (res);
}
/* assert_stmt:
*
* 'assert' test [',' test]
*/
static int
validate_assert_stmt(node *tree)
{
int nch = NCH(tree);
int res = (validate_ntype(tree, assert_stmt)
&& ((nch == 2) || (nch == 4))
&& (validate_name(CHILD(tree, 0), "__assert__") ||
validate_name(CHILD(tree, 0), "assert"))
&& validate_test(CHILD(tree, 1)));
if (!res && !PyErr_Occurred())
err_string("illegal assert statement");
if (res && (nch > 2))
res = (validate_comma(CHILD(tree, 2))
&& validate_test(CHILD(tree, 3)));
return (res);
}
static int
validate_while(node *tree)
{
int nch = NCH(tree);
int res = (validate_ntype(tree, while_stmt)
&& ((nch == 4) || (nch == 7))
&& validate_name(CHILD(tree, 0), "while")
&& validate_test(CHILD(tree, 1))
&& validate_colon(CHILD(tree, 2))
&& validate_suite(CHILD(tree, 3)));
if (res && (nch == 7))
res = (validate_name(CHILD(tree, 4), "else")
&& validate_colon(CHILD(tree, 5))
&& validate_suite(CHILD(tree, 6)));
return (res);
}
static int
validate_for(node *tree)
{
int nch = NCH(tree);
int res = (validate_ntype(tree, for_stmt)
&& ((nch == 6) || (nch == 9))
&& validate_name(CHILD(tree, 0), "for")
&& validate_exprlist(CHILD(tree, 1))
&& validate_name(CHILD(tree, 2), "in")
&& validate_testlist(CHILD(tree, 3))
&& validate_colon(CHILD(tree, 4))
&& validate_suite(CHILD(tree, 5)));
if (res && (nch == 9))
res = (validate_name(CHILD(tree, 6), "else")
&& validate_colon(CHILD(tree, 7))
&& validate_suite(CHILD(tree, 8)));
return (res);
}
/* try_stmt:
* 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
* | 'try' ':' suite 'finally' ':' suite
*
*/
static int
validate_try(node *tree)
{
int nch = NCH(tree);
int pos = 3;
int res = (validate_ntype(tree, try_stmt)
&& (nch >= 6) && ((nch % 3) == 0));
if (res)
res = (validate_name(CHILD(tree, 0), "try")
&& validate_colon(CHILD(tree, 1))
&& validate_suite(CHILD(tree, 2))
&& validate_colon(CHILD(tree, nch - 2))
&& validate_suite(CHILD(tree, nch - 1)));
else if (!PyErr_Occurred()) {
const char* name = "except";
if (TYPE(CHILD(tree, nch - 3)) != except_clause)
name = STR(CHILD(tree, nch - 3));
PyErr_Format(parser_error,
"Illegal number of children for try/%s node.", name);
}
/* Skip past except_clause sections: */
while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
res = (validate_except_clause(CHILD(tree, pos))
&& validate_colon(CHILD(tree, pos + 1))
&& validate_suite(CHILD(tree, pos + 2)));
pos += 3;
}
if (res && (pos < nch)) {
res = validate_ntype(CHILD(tree, pos), NAME);
if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
res = (validate_numnodes(tree, 6, "try/finally")
&& validate_colon(CHILD(tree, 4))
&& validate_suite(CHILD(tree, 5)));
else if (res) {
if (nch == (pos + 3)) {
res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
|| (strcmp(STR(CHILD(tree, pos)), "else") == 0));
if (!res)
err_string("illegal trailing triple in try statement");
}
else if (nch == (pos + 6)) {
res = (validate_name(CHILD(tree, pos), "except")
&& validate_colon(CHILD(tree, pos + 1))
&& validate_suite(CHILD(tree, pos + 2))
&& validate_name(CHILD(tree, pos + 3), "else"));
}
else
res = validate_numnodes(tree, pos + 3, "try/except");
}
}
return (res);
}
static int
validate_except_clause(node *tree)
{
int nch = NCH(tree);
int res = (validate_ntype(tree, except_clause)
&& ((nch == 1) || (nch == 2) || (nch == 4))
&& validate_name(CHILD(tree, 0), "except"));
if (res && (nch > 1))
res = validate_test(CHILD(tree, 1));
if (res && (nch == 4))
res = (validate_comma(CHILD(tree, 2))
&& validate_test(CHILD(tree, 3)));
return (res);
}
static int
validate_test(node *tree)
{
int nch = NCH(tree);
int res = validate_ntype(tree, test) && is_odd(nch);
if (res && (TYPE(CHILD(tree, 0)) == lambdef))
res = ((nch == 1)
&& validate_lambdef(CHILD(tree, 0)));
else if (res) {
int pos;
res = validate_and_test(CHILD(tree, 0));
for (pos = 1; res && (pos < nch); pos += 2)
res = (validate_name(CHILD(tree, pos), "or")
&& validate_and_test(CHILD(tree, pos + 1)));
}
return (res);
}
static int
validate_and_test(node *tree)
{
int pos;
int nch = NCH(tree);
int res = (validate_ntype(tree, and_test)
&& is_odd(nch)
&& validate_not_test(CHILD(tree, 0)));
for (pos = 1; res && (pos < nch); pos += 2)
res = (validate_name(CHILD(tree, pos), "and")
&& validate_not_test(CHILD(tree, 0)));
return (res);
}
static int
validate_not_test(node *tree)
{
int nch = NCH(tree);
int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
if (res) {
if (nch == 2)
res = (validate_name(CHILD(tree, 0), "not")
&& validate_not_test(CHILD(tree, 1)));
else if (nch == 1)
res = validate_comparison(CHILD(tree, 0));
}
return (res);
}
static int
validate_comparison(node *tree)
{
int pos;
int nch = NCH(tree);
int res = (validate_ntype(tree, comparison)
&& is_odd(nch)
&& validate_expr(CHILD(tree, 0)));
for (pos = 1; res && (pos < nch); pos += 2)
res = (validate_comp_op(CHILD(tree, pos))
&& validate_expr(CHILD(tree, pos + 1)));
return (res);
}
static int
validate_comp_op(node *tree)
{
int res = 0;
int nch = NCH(tree);
if (!validate_ntype(tree, comp_op))
return (0);
if (nch == 1) {
/*
* Only child will be a terminal with a well-defined symbolic name
* or a NAME with a string of either 'is' or 'in'
*/
tree = CHILD(tree, 0);
switch (TYPE(tree)) {
case LESS:
case GREATER:
case EQEQUAL:
case EQUAL:
case LESSEQUAL:
case GREATEREQUAL:
case NOTEQUAL:
res = 1;
break;
case NAME:
res = ((strcmp(STR(tree), "in") == 0)
|| (strcmp(STR(tree), "is") == 0));
if (!res) {
PyErr_Format(parser_error,
"illegal operator '%s'", STR(tree));
}
break;
default:
err_string("illegal comparison operator type");
break;
}
}
else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
res = (validate_ntype(CHILD(tree, 0), NAME)
&& validate_ntype(CHILD(tree, 1), NAME)
&& (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
&& (strcmp(STR(CHILD(tree, 1)), "not") == 0))
|| ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
&& (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
if (!res && !PyErr_Occurred())
err_string("unknown comparison operator");
}
return (res);
}
static int
validate_expr(node *tree)
{
int j;
int nch = NCH(tree);
int res = (validate_ntype(tree, expr)
&& is_odd(nch)
&& validate_xor_expr(CHILD(tree, 0)));
for (j = 2; res && (j < nch); j += 2)
res = (validate_xor_expr(CHILD(tree, j))
&& validate_vbar(CHILD(tree, j - 1)));
return (res);
}
static int
validate_xor_expr(node *tree)
{
int j;
int nch = NCH(tree);
int res = (validate_ntype(tree, xor_expr)
&& is_odd(nch)
&& validate_and_expr(CHILD(tree, 0)));
for (j = 2; res && (j < nch); j += 2)
res = (validate_circumflex(CHILD(tree, j - 1))
&& validate_and_expr(CHILD(tree, j)));
return (res);
}
static int
validate_and_expr(node *tree)
{
int pos;
int nch = NCH(tree);
int res = (validate_ntype(tree, and_expr)
&& is_odd(nch)
&& validate_shift_expr(CHILD(tree, 0)));
for (pos = 1; res && (pos < nch); pos += 2)
res = (validate_ampersand(CHILD(tree, pos))
&& validate_shift_expr(CHILD(tree, pos + 1)));
return (res);
}
static int
validate_chain_two_ops(node *tree, int (*termvalid)(node *), int op1, int op2)
{
int pos = 1;
int nch = NCH(tree);
int res = (is_odd(nch)
&& (*termvalid)(CHILD(tree, 0)));
for ( ; res && (pos < nch); pos += 2) {
if (TYPE(CHILD(tree, pos)) != op1)
res = validate_ntype(CHILD(tree, pos), op2);
if (res)
res = (*termvalid)(CHILD(tree, pos + 1));
}
return (res);
}
static int
validate_shift_expr(node *tree)
{
return (validate_ntype(tree, shift_expr)
&& validate_chain_two_ops(tree, validate_arith_expr,
LEFTSHIFT, RIGHTSHIFT));
}
static int
validate_arith_expr(node *tree)
{
return (validate_ntype(tree, arith_expr)
&& validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
}
static int
validate_term(node *tree)
{
int pos = 1;
int nch = NCH(tree);
int res = (validate_ntype(tree, term)
&& is_odd(nch)
&& validate_factor(CHILD(tree, 0)));
for ( ; res && (pos < nch); pos += 2)
res = (((TYPE(CHILD(tree, pos)) == STAR)
|| (TYPE(CHILD(tree, pos)) == SLASH)
|| (TYPE(CHILD(tree, pos)) == PERCENT))
&& validate_factor(CHILD(tree, pos + 1)));
return (res);
}
/* factor:
*
* factor: ('+'|'-'|'~') factor | power
*/
static int
validate_factor(node *tree)
{
int nch = NCH(tree);
int res = (validate_ntype(tree, factor)
&& (((nch == 2)
&& ((TYPE(CHILD(tree, 0)) == PLUS)
|| (TYPE(CHILD(tree, 0)) == MINUS)
|| (TYPE(CHILD(tree, 0)) == TILDE))
&& validate_factor(CHILD(tree, 1)))
|| ((nch == 1)
&& validate_power(CHILD(tree, 0)))));
return (res);
}
/* power:
*
* power: atom trailer* ('**' factor)*
*/
static int
validate_power(node *tree)
{
int pos = 1;
int nch = NCH(tree);
int res = (validate_ntype(tree, power) && (nch >= 1)
&& validate_atom(CHILD(tree, 0)));
while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
res = validate_trailer(CHILD(tree, pos++));
if (res && (pos < nch)) {
if (!is_even(nch - pos)) {
err_string("illegal number of nodes for 'power'");
retu
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -