Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
0ac9b079
Kaydet (Commit)
0ac9b079
authored
Eyl 12, 2000
tarafından
Fred Drake
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Simplify some of the code. Use PyErr_Format() instead of sprintf(), etc.
Reduces lines of code and compiled object size.
üst
e92cdba1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
122 additions
and
186 deletions
+122
-186
parsermodule.c
Modules/parsermodule.c
+122
-186
No files found.
Modules/parsermodule.c
Dosyayı görüntüle @
0ac9b079
...
...
@@ -579,83 +579,41 @@ parser_tuple2ast(PyAST_Object *self, PyObject *args, PyObject *kw)
{
NOTE
(
ARGUNUSED
(
self
))
PyObject
*
ast
=
0
;
PyObject
*
tuple
=
0
;
PyObject
*
temp
=
0
;
int
ok
;
int
start_sym
=
0
;
PyObject
*
tuple
;
node
*
tree
;
static
char
*
keywords
[]
=
{
"sequence"
,
NULL
};
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kw
,
"O:
tupl
e2ast"
,
keywords
,
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kw
,
"O:
sequenc
e2ast"
,
keywords
,
&
tuple
))
return
(
0
);
if
(
!
PySequence_Check
(
tuple
))
{
PyErr_SetString
(
PyExc_ValueError
,
"
tupl
e2ast() requires a single sequence argument"
);
"
sequenc
e2ast() requires a single sequence argument"
);
return
(
0
);
}
/*
* This mess of tests is written this way so we can use the abstract
* object interface (AOI). Unfortunately, the AOI increments reference
* counts, which requires that we store a pointer to retrieved object
* so we can DECREF it after the check. But we really should accept
* lists as well as tuples at the very least.
* Convert the tree to the internal form before checking it.
*/
ok
=
PyObject_Size
(
tuple
)
>=
2
;
if
(
ok
)
{
temp
=
PySequence_GetItem
(
tuple
,
0
);
ok
=
(
temp
!=
NULL
)
&&
PyInt_Check
(
temp
);
if
(
ok
)
/* this is used after the initial checks: */
start_sym
=
PyInt_AS_LONG
(
temp
);
Py_XDECREF
(
temp
);
}
if
(
ok
)
{
temp
=
PySequence_GetItem
(
tuple
,
1
);
ok
=
(
temp
!=
NULL
)
&&
PySequence_Check
(
temp
);
Py_XDECREF
(
temp
);
}
if
(
ok
)
{
temp
=
PySequence_GetItem
(
tuple
,
1
);
ok
=
(
temp
!=
NULL
)
&&
PyObject_Size
(
temp
)
>=
2
;
if
(
ok
)
{
PyObject
*
temp2
=
PySequence_GetItem
(
temp
,
0
);
if
(
temp2
!=
NULL
)
{
ok
=
PyInt_Check
(
temp2
);
Py_DECREF
(
temp2
);
}
tree
=
build_node_tree
(
tuple
);
if
(
tree
!=
0
)
{
int
start_sym
=
TYPE
(
tree
);
if
(
start_sym
==
eval_input
)
{
/* Might be an eval form. */
if
(
validate_expr_tree
(
tree
))
ast
=
parser_newastobject
(
tree
,
PyAST_EXPR
);
}
else
if
(
start_sym
==
file_input
)
{
/* This looks like an exec form so far. */
if
(
validate_file_input
(
tree
))
ast
=
parser_newastobject
(
tree
,
PyAST_SUITE
);
}
else
{
/* This is a fragment, at best. */
PyNode_Free
(
tree
);
err_string
(
"Parse tree does not use a valid start symbol."
);
}
Py_XDECREF
(
temp
);
}
/* If we've failed at some point, get out of here. */
if
(
!
ok
)
{
err_string
(
"malformed sequence for tuple2ast()"
);
return
(
0
);
}
/*
* This might be a valid parse tree, but let's do a quick check
* before we jump the gun.
*/
if
(
start_sym
==
eval_input
)
{
/* Might be an eval form. */
node
*
expression
=
build_node_tree
(
tuple
);
if
((
expression
!=
0
)
&&
validate_expr_tree
(
expression
))
ast
=
parser_newastobject
(
expression
,
PyAST_EXPR
);
}
else
if
(
start_sym
==
file_input
)
{
/* This looks like an exec form so far. */
node
*
suite_tree
=
build_node_tree
(
tuple
);
if
((
suite_tree
!=
0
)
&&
validate_file_input
(
suite_tree
))
ast
=
parser_newastobject
(
suite_tree
,
PyAST_SUITE
);
}
else
/* This is a fragment, and is not yet supported. Maybe they
* will be if I find a use for them.
*/
err_string
(
"Fragmentary parse trees not supported."
);
/* Make sure we throw an exception on all errors. We should never
* get this, but we'd do well to be sure something is done.
*/
...
...
@@ -666,51 +624,6 @@ parser_tuple2ast(PyAST_Object *self, PyObject *args, PyObject *kw)
}
/* int check_terminal_tuple()
*
* Check a tuple to determine that it is indeed a valid terminal
* node. The node is known to be required as a terminal, so we throw
* an exception if there is a failure.
*
* The format of an acceptable terminal tuple is "(is[i])": the fact
* that elem is a tuple and the integer is a valid terminal symbol
* has been established before this function is called. We must
* check the length of the tuple and the type of the second element
* and optional third element. We do *NOT* check the actual text of
* the string element, which we could do in many cases. This is done
* by the validate_*() functions which operate on the internal
* representation.
*/
static
int
check_terminal_tuple
(
PyObject
*
elem
)
{
int
len
=
PyObject_Size
(
elem
);
int
res
=
1
;
char
*
str
=
"Illegal terminal symbol; bad node length."
;
if
((
len
==
2
)
||
(
len
==
3
))
{
PyObject
*
temp
=
PySequence_GetItem
(
elem
,
1
);
res
=
PyString_Check
(
temp
);
str
=
"Illegal terminal symbol; expected a string."
;
if
(
res
&&
(
len
==
3
))
{
PyObject
*
third
=
PySequence_GetItem
(
elem
,
2
);
res
=
PyInt_Check
(
third
);
str
=
"Invalid third element of terminal node."
;
Py_XDECREF
(
third
);
}
Py_XDECREF
(
temp
);
}
else
{
res
=
0
;
}
if
(
!
res
)
{
elem
=
Py_BuildValue
(
"(os)"
,
elem
,
str
);
PyErr_SetObject
(
parser_error
,
elem
);
}
return
(
res
);
}
/* node* build_node_children()
*
* Iterate across the children of the current non-terminal node and build
...
...
@@ -726,7 +639,7 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
int
i
;
for
(
i
=
1
;
i
<
len
;
++
i
)
{
/* elem must always be a
tupl
e, however simple */
/* elem must always be a
sequenc
e, however simple */
PyObject
*
elem
=
PySequence_GetItem
(
tuple
,
i
);
int
ok
=
elem
!=
NULL
;
long
type
=
0
;
...
...
@@ -747,31 +660,52 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
}
if
(
!
ok
)
{
PyErr_SetObject
(
parser_error
,
Py_BuildValue
(
"
(os)
"
,
elem
,
Py_BuildValue
(
"
os
"
,
elem
,
"Illegal node construct."
));
Py_XDECREF
(
elem
);
return
(
0
);
}
if
(
ISTERMINAL
(
type
))
{
i
f
(
check_terminal_tuple
(
elem
))
{
PyObject
*
temp
=
PySequence_GetItem
(
elem
,
1
)
;
i
nt
len
=
PyObject_Size
(
elem
);
PyObject
*
temp
;
/* check_terminal_tuple() already verified it's a string */
strn
=
(
char
*
)
PyMem_MALLOC
(
PyString_GET_SIZE
(
temp
)
+
1
);
if
(
strn
!=
NULL
)
(
void
)
strcpy
(
strn
,
PyString_AS_STRING
(
temp
));
if
((
len
!=
2
)
&&
(
len
!=
3
))
{
err_string
(
"Terminal nodes must have 2 or 3 entries."
);
return
0
;
}
temp
=
PySequence_GetItem
(
elem
,
1
);
if
(
temp
==
NULL
)
return
0
;
if
(
!
PyString_Check
(
temp
))
{
PyErr_Format
(
parser_error
,
"Second item in terminal node must be a string,"
" found %s."
,
((
PyTypeObject
*
)
PyObject_Type
(
temp
))
->
tp_name
);
Py_DECREF
(
temp
);
if
(
PyObject_Size
(
elem
)
==
3
)
{
PyObject
*
temp
=
PySequence_GetItem
(
elem
,
2
);
*
line_num
=
PyInt_AsLong
(
temp
);
Py_DECREF
(
temp
);
}
return
0
;
}
else
{
Py_XDECREF
(
elem
);
return
(
0
);
if
(
len
==
3
)
{
PyObject
*
o
=
PySequence_GetItem
(
elem
,
2
);
if
(
o
!=
NULL
)
{
if
(
PyInt_Check
(
o
))
*
line_num
=
PyInt_AS_LONG
(
o
);
else
{
PyErr_Format
(
parser_error
,
"Third item in terminal node must be an"
" integer, found %s."
,
((
PyTypeObject
*
)
PyObject_Type
(
temp
))
->
tp_name
);
Py_DECREF
(
o
);
Py_DECREF
(
temp
);
return
0
;
}
Py_DECREF
(
o
);
}
}
len
=
PyString_GET_SIZE
(
temp
)
+
1
;
strn
=
(
char
*
)
PyMem_MALLOC
(
len
);
if
(
strn
!=
NULL
)
(
void
)
memcpy
(
strn
,
PyString_AS_STRING
(
temp
),
len
);
Py_DECREF
(
temp
);
}
else
if
(
!
ISNONTERMINAL
(
type
))
{
/*
...
...
@@ -779,8 +713,7 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
* Throw an exception.
*/
PyErr_SetObject
(
parser_error
,
Py_BuildValue
(
"(os)"
,
elem
,
"Unknown node type."
));
Py_BuildValue
(
"os"
,
elem
,
"Unknown node type."
));
Py_XDECREF
(
elem
);
return
(
0
);
}
...
...
@@ -808,7 +741,7 @@ build_node_tree(PyObject *tuple)
{
node
*
res
=
0
;
PyObject
*
temp
=
PySequence_GetItem
(
tuple
,
0
);
long
num
=
-
1
;
long
num
=
-
1
;
if
(
temp
!=
NULL
)
num
=
PyInt_AsLong
(
temp
);
...
...
@@ -818,8 +751,8 @@ build_node_tree(PyObject *tuple)
* The tuple is simple, but it doesn't start with a start symbol.
* Throw an exception now and be done with it.
*/
tuple
=
Py_BuildValue
(
"
(os)
"
,
tuple
,
"Illegal ast tuple; cannot start with terminal symbol."
);
tuple
=
Py_BuildValue
(
"
os
"
,
tuple
,
"Illegal ast tuple; cannot start with terminal symbol."
);
PyErr_SetObject
(
parser_error
,
tuple
);
}
else
if
(
ISNONTERMINAL
(
num
))
{
...
...
@@ -836,19 +769,17 @@ build_node_tree(PyObject *tuple)
}
else
/* The tuple is illegal -- if the number is neither TERMINAL nor
* NONTERMINAL, we can't use it.
* NONTERMINAL, we can't use it. Not sure the implementation
* allows this condition, but the API doesn't preclude it.
*/
PyErr_SetObject
(
parser_error
,
Py_BuildValue
(
"
(os)
"
,
tuple
,
Py_BuildValue
(
"
os
"
,
tuple
,
"Illegal component tuple."
));
return
(
res
);
}
#define VALIDATER(n) static int validate_##n(node *tree)
/*
* Validation routines used within the validation section:
*/
...
...
@@ -871,6 +802,8 @@ staticforward int validate_terminal(node *terminal, int type, char *string);
#define validate_dot(ch) validate_terminal(ch, DOT, ".")
#define validate_name(ch, str) validate_terminal(ch, NAME, str)
#define VALIDATER(n) static int validate_##n(node *tree)
VALIDATER
(
node
);
VALIDATER
(
small_stmt
);
VALIDATER
(
class
);
VALIDATER
(
node
);
VALIDATER
(
parameters
);
VALIDATER
(
suite
);
...
...
@@ -899,6 +832,7 @@ VALIDATER(exprlist); VALIDATER(dictmaker);
VALIDATER
(
arglist
);
VALIDATER
(
argument
);
VALIDATER
(
listmaker
);
#undef VALIDATER
#define is_even(n) (((n) & 1) == 0)
#define is_odd(n) (((n) & 1) == 1)
...
...
@@ -907,14 +841,12 @@ VALIDATER(listmaker);
static
int
validate_ntype
(
node
*
n
,
int
t
)
{
int
res
=
(
TYPE
(
n
)
==
t
);
if
(
!
res
)
{
char
buffer
[
128
];
(
void
)
sprintf
(
buffer
,
"Expected node type %d, got %d."
,
t
,
TYPE
(
n
));
err_string
(
buffer
);
if
(
TYPE
(
n
)
!=
t
)
{
PyErr_Format
(
parser_error
,
"Expected node type %d, got %d."
,
t
,
TYPE
(
n
));
return
0
;
}
return
(
res
)
;
return
1
;
}
...
...
@@ -929,11 +861,11 @@ static int
validate_numnodes
(
node
*
n
,
int
num
,
const
char
*
const
name
)
{
if
(
NCH
(
n
)
!=
num
)
{
char
buff
[
60
];
(
void
)
sprintf
(
buff
,
"Illegal number of children for %s node."
,
name
);
err_string
(
buff
)
;
PyErr_Format
(
parser_error
,
"Illegal number of children for %s node."
,
name
);
return
0
;
}
return
(
NCH
(
n
)
==
num
)
;
return
1
;
}
...
...
@@ -944,9 +876,8 @@ validate_terminal(node *terminal, int type, char *string)
&&
((
string
==
0
)
||
(
strcmp
(
string
,
STR
(
terminal
))
==
0
)));
if
(
!
res
&&
!
PyErr_Occurred
())
{
char
buffer
[
60
];
(
void
)
sprintf
(
buffer
,
"Illegal terminal: expected
\"
%s
\"
"
,
string
);
err_string
(
buffer
);
PyErr_Format
(
parser_error
,
"Illegal terminal: expected
\"
%s
\"
"
,
string
);
}
return
(
res
);
}
...
...
@@ -1395,24 +1326,31 @@ static int
validate_small_stmt
(
node
*
tree
)
{
int
nch
=
NCH
(
tree
);
int
res
=
(
validate_numnodes
(
tree
,
1
,
"small_stmt"
)
&&
((
TYPE
(
CHILD
(
tree
,
0
))
==
expr_stmt
)
||
(
TYPE
(
CHILD
(
tree
,
0
))
==
print_stmt
)
||
(
TYPE
(
CHILD
(
tree
,
0
))
==
del_stmt
)
||
(
TYPE
(
CHILD
(
tree
,
0
))
==
pass_stmt
)
||
(
TYPE
(
CHILD
(
tree
,
0
))
==
flow_stmt
)
||
(
TYPE
(
CHILD
(
tree
,
0
))
==
import_stmt
)
||
(
TYPE
(
CHILD
(
tree
,
0
))
==
global_stmt
)
||
(
TYPE
(
CHILD
(
tree
,
0
))
==
assert_stmt
)
||
(
TYPE
(
CHILD
(
tree
,
0
))
==
exec_stmt
)));
int
res
=
validate_numnodes
(
tree
,
1
,
"small_stmt"
);
if
(
res
)
res
=
validate_node
(
CHILD
(
tree
,
0
));
if
(
res
)
{
int
ntype
=
TYPE
(
CHILD
(
tree
,
0
));
if
(
(
ntype
==
expr_stmt
)
||
(
ntype
==
print_stmt
)
||
(
ntype
==
del_stmt
)
||
(
ntype
==
pass_stmt
)
||
(
ntype
==
flow_stmt
)
||
(
ntype
==
import_stmt
)
||
(
ntype
==
global_stmt
)
||
(
ntype
==
assert_stmt
)
||
(
ntype
==
exec_stmt
))
res
=
validate_node
(
CHILD
(
tree
,
0
));
else
{
res
=
0
;
err_string
(
"illegal small_stmt child type"
);
}
}
else
if
(
nch
==
1
)
{
char
buffer
[
60
]
;
(
void
)
sprintf
(
buffer
,
"Unrecognized child node of small_stmt: %d."
,
TYPE
(
CHILD
(
tree
,
0
)));
err_string
(
buffer
);
res
=
0
;
PyErr_Format
(
parser_error
,
"Unrecognized child node of small_stmt: %d."
,
TYPE
(
CHILD
(
tree
,
0
))
);
}
return
(
res
);
}
...
...
@@ -1426,24 +1364,24 @@ validate_compound_stmt(node *tree)
{
int
res
=
(
validate_ntype
(
tree
,
compound_stmt
)
&&
validate_numnodes
(
tree
,
1
,
"compound_stmt"
));
int
ntype
;
if
(
!
res
)
return
(
0
);
tree
=
CHILD
(
tree
,
0
);
res
=
((
TYPE
(
tree
)
==
if_stmt
)
||
(
TYPE
(
tree
)
==
while
_stmt
)
||
(
TYPE
(
tree
)
==
for
_stmt
)
||
(
TYPE
(
tree
)
==
try
_stmt
)
||
(
TYPE
(
tree
)
==
funcdef
)
||
(
TYPE
(
tree
)
==
classdef
));
if
(
res
)
ntype
=
TYPE
(
tree
);
if
(
(
ntype
==
if
_stmt
)
||
(
ntype
==
while
_stmt
)
||
(
ntype
==
for
_stmt
)
||
(
ntype
==
try_stmt
)
||
(
ntype
==
funcdef
)
||
(
ntype
==
classdef
)
)
res
=
validate_node
(
tree
);
else
{
char
buffer
[
60
];
(
void
)
sprintf
(
buffer
,
"Illegal compound statement type: %d."
,
TYPE
(
tree
));
err_string
(
buffer
);
res
=
0
;
PyErr_Format
(
parser_error
,
"Illegal compound statement type: %d."
,
TYPE
(
tree
));
}
return
(
res
);
}
...
...
@@ -1814,14 +1752,13 @@ validate_try(node *tree)
&&
validate_suite
(
CHILD
(
tree
,
2
))
&&
validate_colon
(
CHILD
(
tree
,
nch
-
2
))
&&
validate_suite
(
CHILD
(
tree
,
nch
-
1
)));
else
{
else
if
(
!
PyErr_Occurred
())
{
const
char
*
name
=
"except"
;
char
buffer
[
60
];
if
(
TYPE
(
CHILD
(
tree
,
nch
-
3
))
!=
except_clause
)
name
=
STR
(
CHILD
(
tree
,
nch
-
3
));
(
void
)
sprintf
(
buffer
,
"Illegal number of children for try/%s node."
,
name
);
err_string
(
buffer
);
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
))
{
...
...
@@ -1974,9 +1911,8 @@ validate_comp_op(node *tree)
res
=
((
strcmp
(
STR
(
tree
),
"in"
)
==
0
)
||
(
strcmp
(
STR
(
tree
),
"is"
)
==
0
));
if
(
!
res
)
{
char
buff
[
128
];
(
void
)
sprintf
(
buff
,
"Illegal operator: '%s'."
,
STR
(
tree
));
err_string
(
buff
);
PyErr_Format
(
parser_error
,
"Illegal operator: '%s'."
,
STR
(
tree
));
}
break
;
default:
...
...
@@ -2582,7 +2518,7 @@ validate_node(node *tree)
break
;
case
small_stmt
:
/*
* expr_stmt | print_stmt
| del_stmt | pass_stmt | flow_stmt
* expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
* | import_stmt | global_stmt | exec_stmt | assert_stmt
*/
res
=
validate_small_stmt
(
tree
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment